______________________________________ | | | | | ,'`. | Managing Sprite Cel VRAM | ,' `. | | ,' ,'`. `. | on the Game Boy Advance | ,' ,' `. `. | | ,' ,' ,'`. `. `. | | ,' ,' ,' `. `. `. | | `. `.,' ,'`. `.,' ,' | by | `. `,,' `. `.,' | | ,'`. `. ,'`. `. | Damian Yerrick | ,' ,'`. `.,' ,'`. `. | | `. `. `. ,' ,' ,' | | `. `. `.,' ,' ,' | | `. `. ,' ,' | | `. `.,' ,' | | `. ,' | | `.,' | | | |______________________________________| TM Copyright (c) 2002 Damian Yerrick . Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License" (http://www.gnu.org/licenses/fdl.html). THE DOCUMENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS DOCUMENT. The Pin Eight logo is a trademark of Damian Yerrick. Nintendo and Game Boy are trademarks of Nintendo. Sprite is a trademark of the Coca-Cola Company, but only if it looks like a soda can (see http://pics.pineight.com/nes/spritecans-2011.zip). In addresses 0x06010000 to 0x06017ffe of the GBA's address space lies 32 KB of sprite tile VRAM. At first, this may not seem like a lot of space for sprites. But it turns out to be straightforward to stream in sprite cel images, and under normal game conditions, it turns out that (to paraphrase a saying commonly attributed to Bill Gates) 32 KB should be enough for almost anyone. Note that the following analysis makes assumptions that apply to a typical 2D console game such as a side-view platform game (Mario, Sonic, etc.), an overhead-view adventure (Zelda, Diablo, etc.), a scrolling shoot-em-up (1942, Zero Wing, etc.), or a fighting game (SF2, Mortal Kombat, etc.). Specifically, it does NOT readily apply to some game genres such as simulations with scores of units (C&C, Starcraft). Assume that your main character sprites (players, enemies) are 32x32 pixels in 16 colors (4 bits per pixel), or equivalently 16x32 pixels (the size of Super Mario) in 256 colors (8 bits per pixel). This makes each cel image 512 bytes (32*32 pixels * 1/2 byte per pixel, or 16*32 pixels * 1 byte per pixel). Assume further that only 32 of them will be on screen at once. This means that if each sprite has a unique image, you can fit them all into 16 KiB, or half the available VRAM. Assume that "particles" (bullets, score displays, etc.) are 16x16 or smaller and also in 16 colors; thus, their cels will each be 128 bytes (16*16 pixels * 1/2 byte per pixel). You can fit 128 particles' images into the remaining 16 KiB (128*128) of VRAM; if some of your particles are 8x8 or 8x16 pixels, you can fit even more. Assume that a ROM-to-VRAM DMA copy takes 6 cycles per 32-bit word (gbadev 10245). A 512-byte copy of one sprite animation frame thus takes 128 u32/sprite * 6 cycles/u32 = 768 cycles to copy from ROM. Turning on the ROM prefetch for the duration of transfers may make them even faster at the expense of slightly decreased battery life. Thus, if half your character sprites change their image in a frame, streaming in 16 images takes only 12,288 cycles, or about 10 vblank scanlines. Even if the program uses CPU copies instead of DMA, it should still be fast enough: optimized code using the `ldmia' and `stmia' instructions should be only 10% slower than DMA. Note, however, that this analysis assumes uncompressed tile data in ROM, a luxury that a multiboot game cannot afford. It's well-known that DMA can cause problems with multiplayer serial communication. But if you do the DMA 512 bytes (one sprite) at a time, you shouldn't have too much problem with DMA blocking serial interrupts, as the GBA runs at 16 MHz, and each 512-byte DMA takes less than 46 microseconds (768 cycles/sprite / 16.78 MHz). You may even be able to get away with not doing serial I/O every frame; if PC Internet games can do prediction on a 170 millisecond (i.e. 10 frame) ping, you can surely use prediction to cover up for missing one frame. === HISTORY === "Managing Sprite Cel VRAM on the Game Boy Advance" By Damian Yerrick on 20020322 Available at http://pineight.com/gba/ After Robert Murray 's advice, I mentioned using ldmia/stmia for CPU copies and clarified how GBA games would use prediction. After Fatty 's advice, I clarified what game styles this advice applies to (excluding RTS games) and explained the Coca-Cola joke. "Managing Sprite Cel VRAM on the Game Boy Advance" By Damian Yerrick on 20020319 Available at http://pineight.com/gba/ Initial release. === BIBLIOGRAPHY === Happ, Tom. "CowBite Virtual Hardware Specifications." http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm "gbadev archives." http://groups.yahoo.com/group/gbadev/