Thread overview
Bits in Int / short / etc
May 29, 2005
Nate
May 29, 2005
Nate
May 30, 2005
Regan Heath
May 30, 2005
Tom S
May 30, 2005
Regan Heath
May 29, 2005
Tom S
May 29, 2005
Nate
May 29, 2005
Tom S
May 29, 2005
Hello Folks,

I'm having a real tough time trying to figure out how to accomplish this. What I am doing is reading a game map file; the format is a series of chars in the header and then compressed "WORDS" (ushorts) in the body.

I've figured out how to read the entire header and I have figured out how to decompress the compressed map portioin of "WORDS". The problem is that some of these ushorts need further breaking down by finding 'highest bits' and such and I have no idea how to proceed...

Here is an example of the data. 280 is an empty tile 33024-33026 are 4 seperate animated tiles. That data needs broken down further.

33024 33025 280 280 [ A TON MORE 280's (256 wide total)] 280
33026 33027 280 280 [ A TON MORE 280's (256 wide total)] 280

33024 is supposed to be animation 0 with offset 0
33025 is supposed to be animation 1 with offset 0
33026 is supposed to be animation 2 with offset 0
33027 is supposed to be animation 3 with offset 0

How do I get the highest bit for 33024, etc and then the lower 15 bits if it is zero? If its not zero i need bits 8-14... I'm very lost at this point. How the heck can I do this?

Here is the only info I have on the file:

> When you decompress the data, you'll have a 256x256 array of WORDs...
> Each one of these can represent a single tile that maps over to the pieces
> in tiles.bmp or it can point to an animation.  Look at the highest bit of
> each word, if it is 0, the lower 15 bits are an index to a tile in
> tiles.bmp (40 tiles per row since each tile is 16x16).  Otherwise: If bit
> 15 is 1, the lower 15 bits refer to an animation... but an animation can
> have an "offset".. so if you had an animation that was 10 frames long, you
> could put two of them next to each other, one with an offset of 0 (normal)
> and one with an offset of 5, so the animations would appear out of phase.
> The lower 8 bits of the WORD represent the animation number (since there
> can be 256 animations) and bits 8-14 is the animation offset.

Thanks very much for your help guys,

Nate
May 29, 2005
I've figured how to do this by hand, I'm still not sure how to do this with D.

Examples
33024 is 1000 0001 00000000 (animation 0, frame 1)

** 1000 = 1 (3 zeros ignored)
** 0001 = offset by 1 (first anim frame)
** 00000000 = tile zero

33280 is 1000 0010 00000000 (animation 0 frame 2)
33536 is 1000 0011 00000000 (animation 0 frame 3)

32793 is 1000 0000 00011001 (animation 25 frame 1)
33305 is 1000 0010 00011001 (animation 25 frame 2)
33561 is 1000 0011 00011001 (animation 25 frame 3)
(11001 is 25 in binary)

So how can I convert an integer to binary and then slice up the binary into sections like this and convert them back to int?

Again thanks for your time.

Nate wrote:
> Hello Folks,
> 
> I'm having a real tough time trying to figure out how to accomplish this. What I am doing is reading a game map file; the format is a series of chars in the header and then compressed "WORDS" (ushorts) in the body.
> 
> I've figured out how to read the entire header and I have figured out how to decompress the compressed map portioin of "WORDS". The problem is that some of these ushorts need further breaking down by finding 'highest bits' and such and I have no idea how to proceed...
> 
> Here is an example of the data. 280 is an empty tile 33024-33026 are 4 seperate animated tiles. That data needs broken down further.
> 
> 33024 33025 280 280 [ A TON MORE 280's (256 wide total)] 280
> 33026 33027 280 280 [ A TON MORE 280's (256 wide total)] 280
> 
> 33024 is supposed to be animation 0 with offset 0
> 33025 is supposed to be animation 1 with offset 0
> 33026 is supposed to be animation 2 with offset 0
> 33027 is supposed to be animation 3 with offset 0
> 
> How do I get the highest bit for 33024, etc and then the lower 15 bits if it is zero? If its not zero i need bits 8-14... I'm very lost at this point. How the heck can I do this?
> 
> Here is the only info I have on the file:
> 
>  > When you decompress the data, you'll have a 256x256 array of WORDs...
>  > Each one of these can represent a single tile that maps over to the pieces
>  > in tiles.bmp or it can point to an animation.  Look at the highest bit of
>  > each word, if it is 0, the lower 15 bits are an index to a tile in
>  > tiles.bmp (40 tiles per row since each tile is 16x16).  Otherwise: If bit
>  > 15 is 1, the lower 15 bits refer to an animation... but an animation can
>  > have an "offset".. so if you had an animation that was 10 frames long, you
>  > could put two of them next to each other, one with an offset of 0 (normal)
>  > and one with an offset of 5, so the animations would appear out of phase.
>  > The lower 8 bits of the WORD represent the animation number (since there
>  > can be 256 animations) and bits 8-14 is the animation offset.
> 
> Thanks very much for your help guys,
> 
> Nate
May 29, 2005
ushort value;

if (value & 0x8000) {
	ushort tileIndex = value & 0x7fff;
	// read tiles.bmp
} else {
	ushort animationNbr = value & 0xff;
	ushort animationOffst = (value & 0x7fff) >> 8;
	// load the animation
}


Nate wrote:
> 33024 is supposed to be animation 0 with offset 0
> 33025 is supposed to be animation 1 with offset 0
> 33026 is supposed to be animation 2 with offset 0
> 33027 is supposed to be animation 3 with offset 0

According to my calculations:
33024 - animation 0; offset 1
33025 - animation 1; offset 1
33026 - animation 2; offset 1
33027 - animation 3; offset 1


-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
May 29, 2005
Amazing! I am _very_ grateful. Coming from a VB -> C# background I am weak in this area. This works perfect but I don't understand how, if you  know any good references for this I'd love to read them.

Thanks again.

Tom S wrote:
> ushort value;
> 
> if (value & 0x8000) {
>     ushort tileIndex = value & 0x7fff;
>     // read tiles.bmp
> } else {
>     ushort animationNbr = value & 0xff;
>     ushort animationOffst = (value & 0x7fff) >> 8;
>     // load the animation
> }
> 
> 
> Nate wrote:
> 
>> 33024 is supposed to be animation 0 with offset 0
>> 33025 is supposed to be animation 1 with offset 0
>> 33026 is supposed to be animation 2 with offset 0
>> 33027 is supposed to be animation 3 with offset 0
> 
> 
> According to my calculations:
> 33024 - animation 0; offset 1
> 33025 - animation 1; offset 1
> 33026 - animation 2; offset 1
> 33027 - animation 3; offset 1
> 
> 
May 29, 2005
Nate wrote:
> Amazing! I am _very_ grateful. Coming from a VB -> C# background I am weak in this area. This works perfect but I don't understand how, if you  know any good references for this I'd love to read them.

Maybe this one: http://www.gamedev.net/reference/articles/article1563.asp


-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
May 30, 2005
Here is an alternative, kinda fun, and maybe educational solution to the problem:

import std.stdio;

void main() {
	int frame,anim;
	
	parseAnimFrame(33280,anim,frame);
	writefln("33280:= anim=%02d, frame=%02d",anim,frame);
	
	parseAnimFrame(33536,anim,frame);
	writefln("33536:= anim=%02d, frame=%02d",anim,frame);
	
	parseAnimFrame(32793,anim,frame);
	writefln("32793:= anim=%02d, frame=%02d",anim,frame);
	
	parseAnimFrame(33305,anim,frame);
	writefln("33305:= anim=%02d, frame=%02d",anim,frame);
	
	parseAnimFrame(33561,anim,frame);
	writefln("33561:= anim=%02d, frame=%02d",anim,frame);
}

void parseAnimFrame(int raw, out int anim, out int frame)
{
	bit[] bVal = (cast(bit*)&raw)[0..32];
	anim = bitArrayToInt(bVal[0..8]);
	frame = bitArrayToInt(bVal[8..12]);
}

int bitArrayToInt(bit[] array)
{
	int val;
	foreach(bit b; array.reverse) {
		val *= 2;
		val += b;
	}
	return val;
}

Of course, it's less efficient than Tom's. However, it does show casting to a bit[] (which can be useful) and how to then reconstitute that bit[] into an int.

Regan

On Sun, 29 May 2005 18:19:00 -0400, Nate <plummn@comdel.net> wrote:
> I've figured how to do this by hand, I'm still not sure how to do this with D.
>
> Examples
> 33024 is 1000 0001 00000000 (animation 0, frame 1)
>
> ** 1000 = 1 (3 zeros ignored)
> ** 0001 = offset by 1 (first anim frame)
> ** 00000000 = tile zero
>
> 33280 is 1000 0010 00000000 (animation 0 frame 2)
> 33536 is 1000 0011 00000000 (animation 0 frame 3)
>
> 32793 is 1000 0000 00011001 (animation 25 frame 1)
> 33305 is 1000 0010 00011001 (animation 25 frame 2)
> 33561 is 1000 0011 00011001 (animation 25 frame 3)
> (11001 is 25 in binary)
>
> So how can I convert an integer to binary and then slice up the binary into sections like this and convert them back to int?
>
> Again thanks for your time.
>
> Nate wrote:
>> Hello Folks,
>>  I'm having a real tough time trying to figure out how to accomplish this. What I am doing is reading a game map file; the format is a series of chars in the header and then compressed "WORDS" (ushorts) in the body.
>>  I've figured out how to read the entire header and I have figured out how to decompress the compressed map portioin of "WORDS". The problem is that some of these ushorts need further breaking down by finding 'highest bits' and such and I have no idea how to proceed...
>>  Here is an example of the data. 280 is an empty tile 33024-33026 are 4 seperate animated tiles. That data needs broken down further.
>>  33024 33025 280 280 [ A TON MORE 280's (256 wide total)] 280
>> 33026 33027 280 280 [ A TON MORE 280's (256 wide total)] 280
>>  33024 is supposed to be animation 0 with offset 0
>> 33025 is supposed to be animation 1 with offset 0
>> 33026 is supposed to be animation 2 with offset 0
>> 33027 is supposed to be animation 3 with offset 0
>>  How do I get the highest bit for 33024, etc and then the lower 15 bits if it is zero? If its not zero i need bits 8-14... I'm very lost at this point. How the heck can I do this?
>>  Here is the only info I have on the file:
>>   > When you decompress the data, you'll have a 256x256 array of WORDs...
>>  > Each one of these can represent a single tile that maps over to the pieces
>>  > in tiles.bmp or it can point to an animation.  Look at the highest bit of
>>  > each word, if it is 0, the lower 15 bits are an index to a tile in
>>  > tiles.bmp (40 tiles per row since each tile is 16x16).  Otherwise: If bit
>>  > 15 is 1, the lower 15 bits refer to an animation... but an animation can
>>  > have an "offset".. so if you had an animation that was 10 frames long, you
>>  > could put two of them next to each other, one with an offset of 0 (normal)
>>  > and one with an offset of 5, so the animations would appear out of phase.
>>  > The lower 8 bits of the WORD represent the animation number (since there
>>  > can be 256 animations) and bits 8-14 is the animation offset.
>>  Thanks very much for your help guys,
>>  Nate

May 30, 2005
Regan Heath wrote:
> Here is an alternative, kinda fun, and maybe educational solution to the  problem:
> 
> // snip ...
> 
> int bitArrayToInt(bit[] array)
> {
>     int val;
>     foreach(bit b; array.reverse) {
>         val *= 2;
>         val += b;
>     }
>     return val;
> }
> 
> Of course, it's less efficient than Tom's. However, it does show casting  to a bit[] (which can be useful) and how to then reconstitute that bit[]  into an int.

What about this code ? :D I'm sure it can be done more efficient too...

# int bitArrayToInt(bit[] array)
# {
# 	static bit[int.sizeof * 8] tmp;
# 	tmp[0 .. array.length] = array[];
# 	tmp[array.length .. length] = 0;
# 	return *cast(int*)&tmp[0];
# }


-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
May 30, 2005
On Mon, 30 May 2005 14:50:13 +0200, Tom S <h3r3tic@remove.mat.uni.torun.pl> wrote:
> Regan Heath wrote:
>> Here is an alternative, kinda fun, and maybe educational solution to the  problem:
>>  // snip ...
>>  int bitArrayToInt(bit[] array)
>> {
>>     int val;
>>     foreach(bit b; array.reverse) {
>>         val *= 2;
>>         val += b;
>>     }
>>     return val;
>> }
>>  Of course, it's less efficient than Tom's. However, it does show casting  to a bit[] (which can be useful) and how to then reconstitute that bit[]  into an int.
>
> What about this code ? :D I'm sure it can be done more efficient too...
>
> # int bitArrayToInt(bit[] array)
> # {
> # 	static bit[int.sizeof * 8] tmp;
> # 	tmp[0 .. array.length] = array[];
> # 	tmp[array.length .. length] = 0;
> # 	return *cast(int*)&tmp[0];
> # }

I'd prefer...

int bitArrayToInt(bit[] array)
{
	bit[] tmp;
	if (array.length >= 32) tmp = array;
	else {
		tmp.length = 32;
		tmp[0 .. array.length] = array[];
		tmp[array.length .. tmp.length] = 0;
	}
	return *(cast(int*)tmp.ptr);
}

Of course, if you used int.sizeof you could make a generic one using templates.

Regan