All of the functions relating to
sprites, including those of the Object Attribute Memory (OAM) can be
found in C:\devkitPro\libnds\include\nds\arm9\sprite.h
Sprites are primarily all about the Object Attribute Memory (OAM)
functions: of which there are many necessary to complete, before you
can achieve the desired results. We start with oamInit():
void oamInit(OamState*
oam, SpriteMapping mapping, bool
extPalette);
- OamState can only be either &oamMain or &oamSub depending on which screen you are rendering the sprite to. This is a small (1kb) data bank with direct 32bit access to the ARM 9 processor. In every instance of it's usage it is entered into the parameters of a function as a pointer, since it is updated by each function.
- SpriteMapping is an enumerator with one of 9 possible options. I always enter SpriteMapping_1D_128 since I don't really understand any of the explanations: “1D tile mapping 128 byte boundary between offset”...Yeah.
- Extended palettes are only for 8bpp sprites.
- (Very) typical example:
oamInit(&oamMain,
SpriteMapping_1D_128, false);
Much less standardized, and with a very
important return output, is the function oamAllocateGfx():
u16*
oamAllocateGfx(OamState *oam, SpriteSize
size, SpriteColorFormat colorFormat);
- OamState, is the same as in the previous function.
- SpriteSize is an enumerator which goes up to 64x64 pixel sprites (though, as with the maps, later, it is possible to combine several sprites together to make something larger, if necessary)
- SpriteColorFormat is typically 256 colors, but can use, both, 16 color format and 16bit bitmaps.
- The function returns a half-word pointer. This is crucial. It describes the address in VRAM of the allocated and bound sprite and should therefore be assigned to a pointer variable for easy recall in later functions:
sprite->sprite_gfx_mem =
oamAllocateGfx(&oamMain,
SpriteSize_64x64, SpriteColorFormat_256Color);
If you are using the (GRIT) GBA Raster
Image Transmogrifier (which you should be), importing your image as a
.h file at the top of your code will result in your importing, both,
tile and palette data, of the form: filenameTiles and
filenamePal.
Your palette, you merely need to bind
directly to the SPRITE_PALETTE using dmaCopy, e.g.:
dmaCopy(manPal, SPRITE_PALETTE, 512)
- dmaCopy is explained in further detail, below, but is basically in the form of dmaCopy(from, to, size-in-bytes)
- the size, in this instance, is 512 since each color is a half-word or 2 bytes (16bit colours of the form aBBBBBGGGGGRRRRR – alpha, blue, green, red – each 0 to 32) and there are a maximum of 256 colours in any one palette.
- It should be noted that it is perfectly possible to, otherwise, save the address of the start of the imported palette to a pointer variable, copy the address of this pointer to the SPRITE_PALETTE using dmaCopy(), and therefore, switch between several palettes by setting that variable to point at different sets when needed.
Your tiles, alternatively, you need
to have a pointer variable reference their address, e.g.:
u8*
frame_gfx = (u8*) manTiles;
such that you can bring in the tiles as
an array and merely add the required amount of bytes to the end of
the address in order to advance it to the next frame of animation:
u8*
offset = sprite->frame_gfx + frame * 64*64;
then, it is entered into dmaCopy():
dmaCopy(offset,
sprite->sprite_gfx_mem, 64*64);
- Remember that sprite_gfx_mem variable? Yeah, this is the pointer variable which references the address of the allocated and bound sprite, and that is why it was so important to receive it from oamAllocateGfx().
There are a couple more OAM functions
which contain information about the sprite – usually relating to
special functionality, such as scaling and rotating – but which
otherwise have to be completed each time, even if you do not use such
aspects. These are:
void
oamSet(OamState* oam, int
id, int x, int
y, int priority, int
palette_alpha, SpriteSize size, SpriteColorFormat format, const
void* gfxOffset, int
affineIndex, bool sizeDouble, bool
hide, bool hflip, bool
vflip, bool mosaic);
Yep, that's a big one. This is pretty
much all of your attributes.
- Id is the number of this set, increasing from 0 to 127, for each new sprite.
- x and y are positions on the screen, for animation purposes.
- Priority is between 0 and 3. Never used it: always 0.
- palette alpha is used in extended Palette mode and with bitmaps. Set to 0.
- SpriteSize and ColorFormat are the same as used previously in oamAllocateGfx.
- *gfxOffset is our favourite pointer again – the pointer variable which references the address of the allocated and bound sprite.
- AffineIndex is used for transformations between 0 and 32. Set to -1.
- finally we end with five bool transformations, which are fairly obvious from the names, and are typically all set to false, (except for hflip – which is very useful for turning your character around) thus:
oamSet(&oamMain, 0,
sprite.x, sprite.y, 0, 0,
SpriteSize_64x64, SpriteColorFormat_256Color,
sprite->sprite_gfx_mem, -1, false,
false,
manFlip, false,
false);
Finally, we have oamUpdate():
void
oamUpdate(OamState* oam);
A nice easy one to end with.
- This needs to be called after each Vblank.
No comments:
Post a Comment