-
Notifications
You must be signed in to change notification settings - Fork 56
bits and you (how to manage space efficiently)
You may already know flags from their hit single include/constants/flags.h
, with tracks such as: FLAG_SYS_POKEDEX_GET
and FLAG_SYS_GAME_CLEAR
, but do you know what a flag actually is?
It's something you toggle right?
It's either on or off.
Sounds like a bit, huh?
Yeah, a flag is just a single lonely bit. That lonely bit can be either 0, or 1, and that's actually really helpful because it means we can check an individual case. Want to check whether the player has or doesn't have their first badge? Just check FLAG_BADGE01_GET
. Want to check if they have their second badge? Just check FLAG_BADGE02_GET
. If it's on (1), then we have the badge!
Bits never appear alone. Bits always form together in groups of 8 called a byte. As mentioned earlier, a byte is defined by using u8
.
So if we have a byte how do we access only a single bit? Well one way we could do it would be by breaking up the field like so:
struct Saveblock
{
u8 badge1get:1;
u8 badge2get:1;
u8 badge3get:1;
// etc. etc.
}
We can do this in any struct
, notably, the SaveBlock.
Notice the :1
at the end of each field? That tells the compiler to use only one bit from the u8
. Leaving the remaining 7 bits untouched. With those remaining 7 bits, we can continue to use as much as we want, including using all of the remaining 7 bits at once, like so: u8 somethingThatNeeds7Bits:7;
.
The only thing to consider is that if we use more bits than are remaining in the previous byte, we'll actually have to start a new byte. So this:
struct
{
u8 foo:3;
u8 bar:6;
}
Actually becomes:
struct
{
u8 foo:3;
u8 remainder:5;
u8 bar:6;
u8 remainder2:2;
}
This is also the reason you can see padding
in the SaveBlock. Whenever only a portion of a byte is used, the remaining bits are left there untouched. If we don't document these, it can sometimes be hard to spot where we have free space.
Using the remaining bits from an existing field like this doesn't even increase the size of the struct. The space was already there, it was just unused. It's good practice when you put data into a struct, to use the minimum amount of bits possible, and document like so:
struct
{
u8 myVerySpecialByte:4; // only needed to represent numbers from 0-15
// u8 padding:4; // the remaining 4 bits are unused. feel free to use before adding new bytes! :)
}
git clone https://github.com/pret/pokeemerald.git cd pokeemerald git remote rename origin upstream git remote add origin https://github.com/DEN-DALI-KAVKA/Copy-of-the-World.git git push -u origin