gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Animations, DMA or ALL in VRAM?

#147085 - elyk1212 - Fri Dec 14, 2007 8:19 am

Hey all,

I wanted to add many frames of animation to my 2D characters on my GBA game (think DK Country, or earthworm Jim) but I was wondering what recommendations you may have for implementation.

I can either keep all frames for characters on the screen in VRAM (and simply update the index in OAM), or I can do DMA transfers (or slower memsets) between frames. This is highly dependent on the size of the sprites, I realize, but I wanted high detail sprites and at least 6 characters (should be) possible on the screen at one time.


Do you think the DMA (or memset) option would be too slow? I don't have enough differeing characters/frames of animation yet to test this claim, just wondering if experienced folk (industry or otherwise) may have some insight.

#147088 - DiscoStew - Fri Dec 14, 2007 8:29 am

If the animations are simple and are used a lot, loading into VRAM would work well. But for such detailed and fluid animations like DK Country, you'll most likely have to load from ROM.
_________________
DS - It's all about DiscoStew

#147090 - elyk1212 - Fri Dec 14, 2007 8:35 am

So DK probably does it that way then? I am not surprised since there are so many frames and states (attacking, ducking, walking standing, scratching) all with tons of frames.

What I am surprised at is that this still does not significantly bog down the system. I guess underestimate the GBA. Perhaps, there is a well capped limit on 'baddies' allowed on the screen at once?

I suppose the brute force way would be to load at each frame, would this be a good approach?

It seems there could be a middle ground (e.g. load common tiles for a state into VRAM, say walking, standing, etc). Thoughts?

#147112 - ScottLininger - Fri Dec 14, 2007 5:25 pm

I've always had success loading tiles from ROM at render time. Even if this drops your frame rate to 30 or 20 FPS, the end results might be okay for you.

-Scott
_________________
Some of my GBA projects

#147116 - Kyoufu Kawa - Fri Dec 14, 2007 6:36 pm

Pok?mon copied the required frames as needed, and so does OpenPok

#147117 - elyk1212 - Fri Dec 14, 2007 6:57 pm

ScottLininger wrote:
I've always had success loading tiles from ROM at render time. Even if this drops your frame rate to 30 or 20 FPS, the end results might be okay for you.

-Scott


When you did that, did you use DMA or just memset,etc? Is there a rule of thumb, e.g. for 'X' many bytes (or Xbytes and N transfers), use DMA, else just use memset?

#147122 - Miked0801 - Fri Dec 14, 2007 7:51 pm

Pretty much every game I worked on used a VRAM double buffer to load stuff from ROM. That way, we could compress the graphics and load into VRAM outside of the VBlank (at the cost of just over 1/2 of Sprite VRAM to the buffering). Then just flip the buffer when the time came. Spyro TEN was the first game in a long time where we actually did some loads without double buffering due to the silly sizes of some of the boss monsters. As such, there was no compression and we DMA'd during vblank from ROM. It was plenty fast.

And never, ever use memset/memcpy for vblank loads. They are just too Slow for anything beyond simple demos. For loads smaller than around 40 bytes or so, we just did ldm/stm loads directly via structure assigns. Larger loads meant Dmas. The trade-off comes from the need to setup the DMA registers as opposed to directly starting to copy. Whilst memcpy and even cpufastcopy just have too much overhead in starting up and then loop too much once the copying has begun.

#147127 - tepples - Fri Dec 14, 2007 8:17 pm

Or you can decompress to EWRAM and load them from there.

On the GBA, DMA freezes the CPU. If you are using the horizontal blank interrupt for raster effects more complicated than a single HDMA channel can provide, or if you're doing multiplayer, a CPU-based copy using an ldm/stm loop has the advantage that it will respond quickly to horizontal blanking or serial interrupts.

You might find my early white paper on this subject interesting.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#147144 - ScottLininger - Sat Dec 15, 2007 1:01 am

elyk1212 wrote:
When you did that, did you use DMA or just memset,etc? Is there a rule of thumb, e.g. for 'X' many bytes (or Xbytes and N transfers), use DMA, else just use memset?


You know, I think that for my early games I just manually copied stuff with a for loop until I got it working nicely, and then I swapped it out with DMA calls once I knew everything was working.

In general, I'm a big fan of "get it working now... optimize later."

-Scott
_________________
Some of my GBA projects

#147303 - brave_orakio - Tue Dec 18, 2007 10:17 am

Miked0801, how do you double buffer VRAM? Any tutorials or tips on this?
_________________
help me

#147330 - Miked0801 - Tue Dec 18, 2007 10:55 pm

No tutorial per se. Here's how it works though:

You decompress your first image somewhere in VRAM (probably with a VRAM management module you wrote to hande such things.) When it comes time to load your next image/frame, you decompress your image somewhere else in VRAM. During VBlank, you point the OAM to the new image and mark the old VRAM as free and usable. Rinse and repeat.

Not much more to it that that. It wastes quite a bit of VRAM space, but frees up (speeds up) the main loop and also frees EWRAM from being a decompression buffer.

#147351 - brave_orakio - Wed Dec 19, 2007 2:03 am

I see, it uses twice the required amount of VRAM compared to copying/overwriting on the fly. I thought maybe you use EWRAM but that would be a lot slower wouldn't it?

Many thanks for that!
_________________
help me

#147647 - elyk1212 - Tue Dec 25, 2007 6:34 am

Yeah, thanks guys! Great ideas.

Happy Holidays!