OAM (sprites)
The GBA supports 128 simultaneous sprites. These can be up to 64x64 pixels in size. The OAM, which starts at 0x07000000
, has one entry for each of the 128 sprites. Intermixed with this data are the rotation/scaling attributes, of which there are 32 sets of 4 16 bit values.
Each OAM entry is 8 bytes long and has the following format:
Bytes 1 and 2 (Attribute 0)
F E D C B A 9 8 7 6 5 4 3 2 1 0 S S A M T T D R J J J J J J J J
Bits | Description |
---|---|
0-7 (J) | Y co-ordinate of the sprite (pixels). Note that for regular sprites, this is the y coordinate of the upper left corner. For rotate/scale sprites, this is the y coordinate of the sprite's center. center . Note on Coordinates: The values actually wrap around: to achieve a -1 y coordinate, use y = 255. |
8 (R) | Rotation/Scaling on/off |
9 (D) | 0 = sprite is single sized; 1 = sprite is virtually double sized; allowing sheared sprite pixels to overflow sprite the size (specified by bits 14 - 15 of OAM attribute 1). A 16x16 sized sprite is treated internaly as a 32x32 sprite. This specification comes in evidence when rotating a sprite at 45°, since the H/V size of the sprite becomes SQRT(16² + 16²) = SQRT(512) =~ 22.62 pixels. This will cause the sprite to appear clipped if this bit is set to 0. (Thanks to Kay for the description) |
A-B (T) | 00 = normal01 = semi-transparent10 = obj window11 = illegal codeNote that semi-transparent sprites appear as transparent even if REG_BLDCNT has the sprites bit turned off. Also note that sprites cannot be blended against one another. For more details, see REG_BLDCNT. |
C (M) | enables mosaic for this sprite. |
D (A) | 256 color if on, 16 color if off |
E-F (S) | Sprite shape. This determines the size of the sprite when combined with bits E-F of attr1. See below for more info. |
Bytes 3 and 4 (Attribute 1)
F E D C B A 9 8 7 6 5 4 3 2 1 0 S S V H X X X I I I I I I I I I (standard sprites) S S F F F F F I I I I I I I I I (rotation/scaling on)
Bits | Description |
---|---|
0-8 (I) | X coordinate of the sprite (pixels). For regular sprites, this is the x coordinate of the upper left corner. For rotate/scale sprites, this is the x coordinate of the sprite's center. Note on coordinates: The values actually wrap around. To achieve a -1 x, use x = 511. |
C (H) | The flip horizinal bit |
D (V) | The flip vertical bit |
9-D (F) | For rotation scaling sprites, the index into the rotation data to be used for that sprite. This index can be from 0 - 31. The rotation/scaling data is located in OAM attribute 3 (bytes 7 and 8). However, instead of the rotation and scaling data going with the corresponding sprite, it is separated accross four sequential sprites. This index can be thought of as referencing into an array of four-sprite blocks, 32 bytes each. |
E-F (S) | Size of the sprite. The top two bits of the size value are found in attribute 0 and the bottom two bits are in attribute 1. This forms a 4-bit value which sets the size of the sprite in the following way: 0000: 8 x 8 1000: 8 x 16 |
Bytes 5 and 6 (Attribute 2)
F E D C B A 9 8 7 6 5 4 3 2 1 0 L L L L P P T T T T T T T T T T
Bits | Description |
---|---|
0-9 (T) | Tile number. This value indexes selects the bitmap of the tile to be displayed by indexing into the tile data area. Each index refernces 32 bytes, so the memory address of a tile is roughly |
A-B (P) | Priority. This controls the priority of the sprite. Note that sprites take precedence over backgrounds of the same priority. See the description of priority under REG_BG0 - REG_BG3 for a more detailed explanation. |
C-F (L) | Palette number. If you use 16 color palettes, this tells you which palette number to use. |
Bytes 7 and 8 (Attribute 3)
F E D C B A 9 8 7 6 5 4 3 2 1 0 S I I I I I I I F F F F F F F F
Bits | Description |
---|---|
0-7 (F) | Fraction. |
8-E (I) | Integer |
F (S) | Sign bit |
These bytes control sprite rotation and scaling. Instead of the rotation and scaling data going with the corresponding sprite, it is separated accross four sequential sprites. This is indexed by bits 9 - 13 in attribute 1. Note that these are all relative to the center of the sprite (background rotation/scaling is relative to the upper left). Starting with sprite 0 and repeating every 4 sprites, they appear in the following order:
-
Sprite 0, Attribute 3 - PA (DX)
Scales the sprite in the x direction by an amount equal to 1/(register value). Thus, a value of 1.0 results in the original image size, while a value of 2 is half as large, and a value of .5 is twice as large.
-
Sprite 1, Attribute 3 - PB (DMX)
Shears the x coordinates of the sprite over y. A value of 0 will result in no shearing, a value of 1.00 will make the image appear to be sheared left going down the screen, and a value of -1 will make the image appear sheared right going down the screen.
-
Sprite 2, Attribute 3 - PC (DY)
Shears the y coordinates of the sprite over x. A value of 0 will result in no shearing, a value of 1.00 will make the image appear to be sheared upwards to the right, and a value of -1 will make the image appear sheared downwards and to the right.
-
Sprite 3, Attribute 3 - PD (DMY)
Scales the image in the y direction by an amount equal to 1/(register value). Thus, a value of 1.0 results in the original image size, while a value of 2 is half as large, and a value of .5 is twice as large.
To Make a Sprite Rotate and Scale
The basic form of the equations for rotating and scaling is as follows:
pa = x_scale * cos(angle) pb = y_scale * sin(angle) pc = x_scale * -sin(angle) pd = y_scale * cos(angle)
Sprite Tile Data
The tile data area contains the actual bitmap for each tile. The sprites do not share tile data with the BG layers as on the Gameboy Color. The sprite tile data starts at 0x06010000
. All tiles are 8x8 pixels large. Sprites use the second palette which begins at 0x05000200
. For 256 color sprites, there are 64 bytes per tile, one byte per pixel. This is an 8-bit value which is an index into the 256 color palette. For 16-color sprites, attribute 2 of the OAM data contains a 4 bit index into 16 16-color palettes, and sprites have 32 bytes per tile, with 4 bits per pixel. Note that the tile index references 32 bytes at a time, so in the case of 256 color sprite tiles, you will want to set your tile number to reference ever other index (i.e. 0, 2, 4, 6, etc.).
Another thing to note is that in the bitmapped modes (3-5) the memory required to hold background data is larger than 0x10000 bytes, forcing the GBA to cut away from available sprite tile data. Thus in these modes you may only reference sprites tiles of indices 512 and up.
When the sprite is larger than 8x8 pixels, multiple tiles are glued together to make the sprite's width horizontally, and then vertically. How this is done depends on whether character data is stored in 2D or 1D mode (determined by bit 6 of DISPCNT).
1D Mapping
In 1D mode, tiles are stored sequentially. If you were to set up a 32x32 16-color sprite, and set the tile number to 5, the sprite would be displayed as follows:
--------------------- | 5 | 6 | 7 | 8 | | | | | | --------------------- | 9 | 10 | 11 | 12 | | | | | | --------------------- | 13 | 14 | 15 | 16 | | | | | | --------------------- | 17 | 18 | 19 | 20 | | | | | | ---------------------
2D Mapping
Tiles on each row of the sprite are stored 32 slots in. Using the same 32x32 sprite above, with a tile number of 5, the sprite would be displayed as:
--------------------- | 5 | 6 | 7 | 8 | | | | | | --------------------- | 37 | 38 | 39 | 40 | | | | | | --------------------- | 69 | 70 | 71 | 72 | | | | | | --------------------- | 101| 102| 103| 104| | | | | | ---------------------