mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-07 20:28:31 +00:00
SubChunk: implement branchless read/write for nibble arrays (#2489)
this was inspired by https://hub.spigotmc.org/stash/projects/SPIGOT/repos/spigot/browse/CraftBukkit-Patches/0121-Branchless-NibbleArray.patch
This commit is contained in:
parent
6dd2597934
commit
cac21c2caf
@ -66,31 +66,22 @@ class SubChunk implements SubChunkInterface{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getBlockData(int $x, int $y, int $z) : int{
|
public function getBlockData(int $x, int $y, int $z) : int{
|
||||||
$m = ord($this->data{($x << 7) + ($z << 3) + ($y >> 1)});
|
return (ord($this->data{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf;
|
||||||
if(($y & 1) === 0){
|
|
||||||
return $m & 0x0f;
|
|
||||||
}else{
|
|
||||||
return $m >> 4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setBlockData(int $x, int $y, int $z, int $data) : bool{
|
public function setBlockData(int $x, int $y, int $z, int $data) : bool{
|
||||||
$i = ($x << 7) | ($z << 3) | ($y >> 1);
|
$i = ($x << 7) | ($z << 3) | ($y >> 1);
|
||||||
if(($y & 1) === 0){
|
|
||||||
$this->data{$i} = chr((ord($this->data{$i}) & 0xf0) | ($data & 0x0f));
|
$shift = ($y & 1) << 2;
|
||||||
}else{
|
$byte = ord($this->data{$i});
|
||||||
$this->data{$i} = chr((($data & 0x0f) << 4) | (ord($this->data{$i}) & 0x0f));
|
$this->data{$i} = chr(($byte & ~(0xf << $shift)) | (($data & 0xf) << $shift));
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFullBlock(int $x, int $y, int $z) : int{
|
public function getFullBlock(int $x, int $y, int $z) : int{
|
||||||
$i = ($x << 8) | ($z << 4) | $y;
|
$i = ($x << 8) | ($z << 4) | $y;
|
||||||
if(($y & 1) === 0){
|
return (ord($this->ids{$i}) << 4) | ((ord($this->data{$i >> 1}) >> (($y & 1) << 2)) & 0xf);
|
||||||
return (ord($this->ids{$i}) << 4) | (ord($this->data{$i >> 1}) & 0x0f);
|
|
||||||
}else{
|
|
||||||
return (ord($this->ids{$i}) << 4) | (ord($this->data{$i >> 1}) >> 4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool{
|
public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool{
|
||||||
@ -106,12 +97,11 @@ class SubChunk implements SubChunkInterface{
|
|||||||
|
|
||||||
if($data !== null){
|
if($data !== null){
|
||||||
$i >>= 1;
|
$i >>= 1;
|
||||||
|
|
||||||
|
$shift = ($y & 1) << 2;
|
||||||
$byte = ord($this->data{$i});
|
$byte = ord($this->data{$i});
|
||||||
if(($y & 1) === 0){
|
$this->data{$i} = chr(($byte & ~(0xf << $shift)) | (($data & 0xf) << $shift));
|
||||||
$this->data{$i} = chr(($byte & 0xf0) | ($data & 0x0f));
|
|
||||||
}else{
|
|
||||||
$this->data{$i} = chr((($data & 0x0f) << 4) | ($byte & 0x0f));
|
|
||||||
}
|
|
||||||
if($this->data{$i} !== $byte){
|
if($this->data{$i} !== $byte){
|
||||||
$changed = true;
|
$changed = true;
|
||||||
}
|
}
|
||||||
@ -121,42 +111,30 @@ class SubChunk implements SubChunkInterface{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getBlockLight(int $x, int $y, int $z) : int{
|
public function getBlockLight(int $x, int $y, int $z) : int{
|
||||||
$byte = ord($this->blockLight{($x << 7) + ($z << 3) + ($y >> 1)});
|
return (ord($this->blockLight{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf;
|
||||||
if(($y & 1) === 0){
|
|
||||||
return $byte & 0x0f;
|
|
||||||
}else{
|
|
||||||
return $byte >> 4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setBlockLight(int $x, int $y, int $z, int $level) : bool{
|
public function setBlockLight(int $x, int $y, int $z, int $level) : bool{
|
||||||
$i = ($x << 7) + ($z << 3) + ($y >> 1);
|
$i = ($x << 7) | ($z << 3) | ($y >> 1);
|
||||||
|
|
||||||
|
$shift = ($y & 1) << 2;
|
||||||
$byte = ord($this->blockLight{$i});
|
$byte = ord($this->blockLight{$i});
|
||||||
if(($y & 1) === 0){
|
$this->blockLight{$i} = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift));
|
||||||
$this->blockLight{$i} = chr(($byte & 0xf0) | ($level & 0x0f));
|
|
||||||
}else{
|
|
||||||
$this->blockLight{$i} = chr((($level & 0x0f) << 4) | ($byte & 0x0f));
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBlockSkyLight(int $x, int $y, int $z) : int{
|
public function getBlockSkyLight(int $x, int $y, int $z) : int{
|
||||||
$byte = ord($this->skyLight{($x << 7) + ($z << 3) + ($y >> 1)});
|
return (ord($this->skyLight{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf;
|
||||||
if(($y & 1) === 0){
|
|
||||||
return $byte & 0x0f;
|
|
||||||
}else{
|
|
||||||
return $byte >> 4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
|
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
|
||||||
$i = ($x << 7) + ($z << 3) + ($y >> 1);
|
$i = ($x << 7) | ($z << 3) | ($y >> 1);
|
||||||
|
|
||||||
|
$shift = ($y & 1) << 2;
|
||||||
$byte = ord($this->skyLight{$i});
|
$byte = ord($this->skyLight{$i});
|
||||||
if(($y & 1) === 0){
|
$this->skyLight{$i} = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift));
|
||||||
$this->skyLight{$i} = chr(($byte & 0xf0) | ($level & 0x0f));
|
|
||||||
}else{
|
|
||||||
$this->skyLight{$i} = chr((($level & 0x0f) << 4) | ($byte & 0x0f));
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user