Difference between revisions of "GBDK set sprite prop"
(Initial page for setting binary sprite properties) |
m (fix an unclosed tag) |
||
Line 4: | Line 4: | ||
== TL;DR: == | == TL;DR: == | ||
− | The property argument is a byte and can be combined using bitwise operators to pass several properties at once: <code>property1 | property2 | ... | propertyn</code> to send multiple properties, <code>existingProperties | property<code> to leave everything the same but turn property on, <code>existingProperties & ~property<code> to leave everything the same but turn property off. | + | The property argument is a byte and can be combined using bitwise operators to pass several properties at once: <code>property1 | property2 | ... | propertyn</code> to send multiple properties, <code>existingProperties | property<code> to leave everything the same but turn property on, <code>existingProperties & ~property</code> to leave everything the same but turn property off. |
== Definitions == | == Definitions == |
Revision as of 03:56, 19 June 2016
Contents
Introduction
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.
The set_sprite_prop
function, found in gb.h, sets properties of a sprite.
TL;DR:
The property argument is a byte and can be combined using bitwise operators to pass several properties at once: property1 | property2 | ... | propertyn
to send multiple properties, existingProperties | property<code> to leave everything the same but turn property on, <code>existingProperties & ~property
to leave everything the same but turn property off.
Definitions
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:
Bit | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
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 |
set_sprite_prop
Using the defined shorthand, you can call
set_sprite_prop(spriteNumber, S_FLIPY);
which sets the properties to 01000000
(40 in hexadecimal, 64 in decimal), and
set_sprite_prop(spriteNumber, S_FLIPX);
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.
Bitwise operators
So how do you do both? With bitwise operators! We're specifically interested in &
(and), |
(or), and ~
complement. &
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?
OR
Well, we know that S_FLIPY
is 01000000
and S_FLIPX
is 00100000
. To turn both on in one move, you'd use OR: |
, and get 01100000
:
set_sprite_prop(spriteNumber, S_FLIPY | S_FLIPX);
get_sprite_prop
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 |
operator:
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 &
and ~
operators come into play.
With &
, 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.
An example:
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
& ~00100000
Breaking this down completely, let's apply the NOT first and flip the latter set:
11011111
Now let's combine them using AND:
00100011
11011111
making:
00000011
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);
Takeaway
Hopefully you can now apply any changes to a sprite's properties without a lot of hassle or trial and error.