2007-04-25

Palettes, Sprite Numbers and Global Variables

Trying to chop up the existing sprites and use them as explosion graphics turned out to be impractical due to the way the sprite system works in PALib. Decided to use individual files instead, but then I ran into a problem - the DS can have 15 sprite palettes, and I’ve already got more than 15 different sprite bitmaps. Checking the PALib forum reveals that PAGfx can use the same palette for multiple sprites so long as the total number of colours doesn’t exceed 256. It’s easy to do; just change the PAGfx.ini file so that all sprites use the same palette name:

Sprite1.bmp 256colours sprite0
Sprite2.bmp 256colours sprite0
Sprite3.bmp 256colours sprite0

Each bitmap uses a palette called “sprite0”. PAGfx automatically adds any new colours from each image into the palette. Clever stuff; I thought I was going to have to do it manually.

Apart from reducing the number of sprite palettes to 1, this had two beneficial effects. I no longer have to pass palette numbers around in sprite constructors, which saves a small amount of hassle. It’s also somehow fixed the mutants’ palette cycling routine. Not sure how, but I’m not complaining.

Another change I’ve made is the way that the game handles sprite numbers. The DS can have up to 128 2D sprites running simultaneously. In the PALib, each sprite is given a unique number between 0 and 127 and is tracked using that number. I originally implemented a simple system in which the “Game” class tracks the current sprite number. Every new sprite is passed a pointer to the current instance of the Game class, and they request a sprite number from that instance in its constructor. Each time a request is made the game increases its internal count of sprites used.

This works OK until sprites start getting deleted and new sprites added, at which point it all falls apart. It would be possible to create and delete a single sprite 128 times, and then, when trying to add another sprite, the DS would crash because we’re trying to allocate sprite 129. We wouldn’t even have a single sprite active at that point.

Instead, I’ve gone for something more akin to the way Flash handles movie clips. The Game class now stores an array of 128 boolean values. When a new sprite requests a sprite number, the game scans along the array for the first false value, sets that value to true, and returns its index. When a sprite is destroyed it tells the game to set that array item back to false. This way, sprite numbers are freed up as sprites are removed from the game, and the game class always returns the lowest free sprite number.

Today’s final discovery involves global variables. Up until now I’ve been passing bitmap pointers created by PAGfx between classes because they’re inaccessible in files other than “main.cpp”. This got impractical when I began working with explosions - passing 12 bitmap pointers between three or four different classes was just not practical. Searched the PALib forum and discovered that all I had to do was include the “all_gfx.h” file in my other files, the same as any other header file. Doh!