GBDK set sprite prop
This tutorial seeks to describe, with examples, how to make precise changes to a sprite's state, without requiring any previous knowledge of binary or bitwise operators.
set_sprite_prop function, found in gb.h, sets properties of a sprite.
The property argument is a byte and can be combined using bitwise operators (ways to combine binary sets) to pass several properties at once:
property1 | property2 | ... | propertyn to send multiple properties,
existingProperties | property to leave everything the same but turn property on,
existingProperties & ~property to leave everything the same but turn property off.
gb.h includes some property definitions:
- #define S_PALETTE 0x10U
- #define S_FLIPX 0x20U
- #define S_FLIPY 0x40U
- #define S_PRIORITY 0x80U
The problem with setting these is that any will obliterate any other properties.
Sprite property flags
The flags are stored in binary like this:
|Feature||Relative to background||Flip Y||Flip X||DMG palette||GBC Tile bank||Color||Color||Color|
|0||In front||Don't flip||Don't flip||Monochrome palette 0||Bank 0||0+||0+||0|
|1||Behind||Flip vertically||Flip horizontally||Monochrome palette 1||Bank 1||1+||1+||1|
Using the defined shorthand, you can call
which sets the properties to
01000000 (40 in hexadecimal, 64 in decimal), and
which sets the properties to
00100000 (20 in hexadecimal, 32 in decimal)
but if you do both, the entire set is overwritten with the latest set, so the bit that is flipped gets flipped back.
So how do you do both? With bitwise operators! We're specifically interested in
| (or), and
& adds two bit sets together but only carries over 1s that existed in both previous sets (1100 & 1011 is 1000).
| carries over any 1s that existed in either (1000 | 1011 is 1011).
~ gives the complement of a single set, effectively flipping each bit to its opposite, regardless of its position (~1011 is 0100).
So how do we put this into practice?
Well, we know that
00100000. To turn both on in one move, you'd use OR:
|, and get
set_sprite_prop(spriteNumber, S_FLIPY | S_FLIPX);
That's great! But it ignores the existing states of the other bits, for example a color palette, or priority relative to the background. Perhaps you want to flip the sprite on its axes independently of each other. For that, you can feed
get_sprite_prop directly into
set_sprite_prop (or set it to a variable and feed that in) and use the
set_sprite_prop(spriteNumber, get_sprite_prop(spriteNumber) | newProp);
A real example:
set_sprite_prop(0, get_sprite_prop(0) | S_FLIPX);
AND and NOT
Now how do you switch a bit off? Here's where the
~ operators come into play.
&, we know that only 1s found in both sets get carried over. Any set
& a set full of 1s will result in that set. Any 0 in either set will result in a 0 in the resulting set. So we need to
& combine the existing property set with a set full of 1s and a 0 in the position of the bit we want to switch off. We can get the latter with the complement operator
~ and any single or collective setting we want turned off.
The existing state of properties on a sprite is
00100011 (see #get_sprite_prop)(flipped horizontally, set to color palette 3), and we want to revert the mirrored effect. So:
00100011 & ~
Breaking this down completely, let's apply the NOT first and flip the latter set:
Now let's combine them using AND:
We've successfully retained all previous bit states except for the one we switched off.
Here's a real-world example:
set_sprite_prop(0, get_sprite_prop(0) & ~S_FLIPX);
Hopefully you can now apply any changes to a sprite's properties without a lot of hassle or trial and error.