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.

Coding > Drawing in Mode4

#6899 - Peter - Wed Jun 04, 2003 10:49 am

Hi,

I'm thinking of what could be the fastest way of drawing graphics in mode4.

I guess the greatest disadvantage is its "strange" storage format, that's
why i decided to make a "virtual buffer" where i draw all my stuff in.

It's a 2D array (in EWRAM) so i can access each pixel like buffer[y][x] = color ...

This is pretty fast compared to drawing directly into VRAM.
Once drawing is done, i copy the entire buffer into VRAM. (once per frame)

I use DMA3 to copy the virtual buffer to VRAM, i also tried BIOS SWI "CpuFastMemSet" which seems to be slighty slower on real hardware than DMA. DMA3 requires around 1/4 frame.

To clear the virtual buffer i use the set function of CpuFastMemSet BIOS SWI. This needs around 1/5 frame.

Makes together around 1/2 frame so i should have 50% power free to perform the drawing itself.

As far as my tests went, this is faster than simply writing to VRAM in mode 4, but i guess this cannot be the "good" way of drawing efficient?!


Does anybody of you know of an efficient/fast way to draw stuff in mode 4?


Thanks for reading,
Peter

#6937 - Jason Wilkins - Wed Jun 04, 2003 7:43 pm

First, use dirty rectangles if you can. With dirty rectangles, you keep track of the areas which change between frames and only update those. You can find ways to use and optimize dirty rectangles by doing a google search for them.

Dirty rectangles basically means changing only the parts of the screen that change. You clear/erase only the parts (sprites) which have moved and draw only where they are in the current frame.

Second, do not clear the whole screen if you don't have to. If you are going to redraw the whole screen then just draw over it. If you only draw parts, then use dirty rectangles to clear only those parts that need to be cleared before you update.

An idea just occured to me. If you made a blit routine in assembly using ldmia/stmia (i.e., it would be fast) which only copied, say 16x16 squares, then you could create a 15x10 grid of dirty flags for the whole screen. You would mark the grid when you draw, and then blit only the 16x16 sections of the screen which changed each frame.

You could even quickly examine the dirty grid and see if more than a certain amount of it was dirty, and if it was just use a routine which blits the whole thing (you would have to experiment to find the tipping point where this was faster).

It might even be worth creating other specialized blitting routines for sizes like 32x16 or 64x64, if you could quickly determine these sizes.

I only suggest this because a routine which properly manages a list of arbitrary dirty rectangles, and combines them, and all that, is complicated, and might not be worth using on a screen which is only 240x160.
_________________
http://devkitadv.sourceforge.net