DGL
https://delphigl.com/forum/

Extracting 4-Bits from a Array of Byte
https://delphigl.com/forum/viewtopic.php?f=19&t=9560
Seite 1 von 1

Autor:  Stucuk [ Mi Okt 27, 2010 06:50 ]
Betreff des Beitrags:  Extracting 4-Bits from a Array of Byte

Im working on an application to render Minecraft Levels. The lighting information is stored in a Byte Array with each 4-bits belonging to a different Block in the world. Im wondering if the following should extract the 4-bits correctly:

Code:
function GetLight(Data : Pointer; ID : Integer) : Byte;
begin
  if Odd(ID) then
  Result := Byte(Pointer(Cardinal(Data) + (ID-1) div 2*SizeOf(Byte))^)
  else
  Result := Byte(Pointer(Cardinal(Data) + (ID) div 2*SizeOf(Byte))^);

  if Odd(ID) then
  begin
    Result := Result shl 4;
    Result := Result shr 4;
  end
  else
  Result := Result shr 4;
end;


Problem is that it doesn't seem to get the correct information as parts of the level which should be bright are completely black.

Autor:  damadmax [ Mi Okt 27, 2010 08:55 ]
Betreff des Beitrags:  Re: Extracting 4-Bits from a Array of Byte

hi,

i would try this approach:
Code:
function GetLight(Data : Pointer; ID : Integer) : Byte;
var
  index:integer;
  data:byte;
  bits:byte;
begin
  index := ID div 2;
  data := Byte(Pointer(Cardinal(Data) + index )^)
  if Odd(ID) then
    bits := data and 15; // mask lower 4 bits
  else
    bits := (data shr 4) and 15; // move upper 4 bits down
  Result := bits;
end;


maybe the second "and 15" isn't needed. but i'm not sure if the "shr" cuts off or rotates the bits. i'm betting 80% on cuting off. :)
and i'm not sure of the pointer-moving part. maybe i've broken it. another reason why i hate pointers...

Autor:  TAK2004 [ Mi Okt 27, 2010 17:10 ]
Betreff des Beitrags:  Re: Extracting 4-Bits from a Array of Byte

Shr and shl are base on the processor shifting operation and both drop the overflow and fill with 0.
So you can remove the "and 15".

Autor:  Stucuk [ Mi Okt 27, 2010 19:24 ]
Betreff des Beitrags:  Re: Extracting 4-Bits from a Array of Byte

Thanks but it looks like either both of our code is wrong or both is right (Gives the same results).

P.S You can't have Data as a Parameter and as a Local Variable :P .

Autor:  Bergmann89 [ Mi Okt 27, 2010 22:08 ]
Betreff des Beitrags:  Re: Extracting 4-Bits from a Array of Byte

Hey,

maybe this way?!
Code:
function GetLight(Data: Pointer; ID: Integer): Byte;
var
  Index: Integer;
begin
  Index := ID div 2;
  inc(PByte(Data), Index);
  if Odd(ID) then
    result := PByte(Data)^ and $0F
  else
    result := PByte(Data)^ shr 4;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  ByteArr: array of Byte;
  i: Integer;
  str: String;
begin
  SetLength(ByteArr, 4);
  for i := 0 to High(ByteArr) do
    ByteArr[i] := i+1;
  str := '';
  for i := 0 to 2*Length(ByteArr)-1 do
    str := str + IntToStr(GetLight(@ByteArr[0], i));
  Caption := str;
end;


this code sets the Caption to '01020304'. so if you doesn't get the right results with this code, you must check your input data.

greetings, Bergmann.

Autor:  Stucuk [ Mi Okt 27, 2010 23:10 ]
Betreff des Beitrags:  Re: Extracting 4-Bits from a Array of Byte

All 3 seem to give the same results. I don't think there should be any way the input is wrong.

Code:
Light    := TNBT_Container(Data.Data).FindProperty('BlockLight');
 SkyLight := TNBT_Container(Data.Data).FindProperty('SkyLight');
 Blocks   := TNBT_Container(Data.Data).FindProperty('Blocks');

 SetLength(FBlocks,16,128,16);

 for X := 0 to 15 do
 for Z := 0 to 15 do
 for Y := 0 to 127 do
 begin
  BlockType := Byte(Pointer(Cardinal(Blocks.Data) + (Y + ( Z * 128 + ( X * 128 * 16 ) )))^);

  FBlocks[X,Y,Z].Block           := BlockArray[BlockType];
  FBlocks[X,Y,Z].Data.CanFall    := False;
  FBlocks[X,Y,Z].Data.FallOffset := 0;
  FBlocks[X,Y,Z].Data.Light      := Max(GetLight(Light.Data,(Y + ( Z * 128 + ( X * 128 * 16 ) ))),GetLight(SkyLight.Data,(Y + ( Z * 128 + ( X * 128 * 16 ) ))));
  if FBlocks[X,Y,Z].Data.Light > 15 then
  FBlocks[X,Y,Z].Data.Light := 15;
 end;

As far as i understand Blocks, SkyLight and BlockLight are all stored in X,Z,Y format.

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/