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 > Using a dynamic tile engine while still using compression?

#17140 - rooter - Tue Mar 02, 2004 9:06 am

Here is my problem...

Currently for my RPG engine I'm using a dynamic tile system - tiles are streamed in and out as needed. Simple enough and easy to work with as long as I'm not using compression.

Now, the problem is when compression comes in the picture it's not feasible to compress each individual tile (wouldnt be worth it), or the entire tileset (cant decompress a 2000 tile set for one tile when streaming ;P). Now the only solutions I can see are:

1) Don't use a dynamic tile system and limit myself so that the entire tileset will fit in VRAM and DMA it all in when I load a map.
2) Compress tiles in small blocks, and decompress them into ram as needed and copy the tile I need from said block into VRAM, so on and so forth, this seems like it would be extremely slow when I would be constantly scrolling.

Is there any feasible way to use the dynamic tile system while still using compression or should I just go with #1 and forget about it?

#17152 - poslundc - Tue Mar 02, 2004 4:14 pm

Do you really need to access all 2000 tiles at once?

Most RPGs have their maps designed in such a way so that when you enter a new room or exit off the screen onto the next one, the screen fades to black, the necessary set of tiles is loaded into VRAM, and the screen fades back up again.

Text backgrounds give you access to 1024 different tiles (in 16-colour mode) at a time. That's a lot of tiles for a single map. If you really need more than that, well, there are ways around it, but you might be better off reconsidering your design strategy.

Dan.

#17158 - rooter - Tue Mar 02, 2004 6:15 pm

poslundc wrote:
Do you really need to access all 2000 tiles at once?

Most RPGs have their maps designed in such a way so that when you enter a new room or exit off the screen onto the next one, the screen fades to black, the necessary set of tiles is loaded into VRAM, and the screen fades back up again.

Text backgrounds give you access to 1024 different tiles (in 16-colour mode) at a time. That's a lot of tiles for a single map. If you really need more than that, well, there are ways around it, but you might be better off reconsidering your design strategy.

Dan.
Right. I'd already resigned myself to just loading all the tiles in at once, but I figured I'd consult the forums first in case I was missing something obvious.

#17162 - DekuTree64 - Tue Mar 02, 2004 6:52 pm

You could also compress them as smaller sets and cache them in EWRAM when loading your level, and then copy individual tiles into VRAM as needed.
Although what I ended up doing was letting my maps have as many tilesets as they want, just loaded into VRAM consecutively during map loading. You also need to copy the screen data mappings into an array with the number of previously loaded tiles added to the entries though, but it's not too hard.
So for example, if you loaded a 64 tile tileset, which had some repeating tiles so it was only 50 graphical tiles, but still 64 map entries, then you'd load all those into VRAM tile positions 0+ and screen data array 0+, then when you load the next tileset, you'd load the gfx data to tiles 50+, copy the screen data to array positions 64+, adding 50 to each entry.
That seems to give plenty of flexibility without being too difficult to do. 1024 tiles is plenty for most levels, it's just when you end up with a lot of 'dead' tiles that are only used in a few maps, but still have to take up space in a general tileset that you run into problems.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#17165 - Paul Shirley - Tue Mar 02, 2004 7:35 pm

removed

Last edited by Paul Shirley on Sun Mar 28, 2004 9:05 pm; edited 1 time in total

#17170 - Miked0801 - Tue Mar 02, 2004 8:15 pm

Paul, you can compress tiles individually, you just got to use the correct type of compression (works here) :)

Use Huffman or another symbol compressor. This will allow you to decompress from the middle of a stream without penalty and huffman decompresses plenty fast enough. You won't see the same compression as an LZ type, but some is better than none and if you're streaming in data, you need all the compression you can get. To speed it up, store an offset (bit) to each char tile in an array and compress that too. BTW, the same technique can be used for RLE as well with care.

Mike

#17171 - rooter - Tue Mar 02, 2004 8:19 pm

Miked0801 wrote:
Paul, you can compress tiles individually, you just got to use the correct type of compression (works here) :)

Use Huffman or another symbol compressor. This will allow you to decompress from the middle of a stream without penalty and huffman decompresses plenty fast enough. You won't see the same compression as an LZ type, but some is better than none and if you're streaming in data, you need all the compression you can get. To speed it up, store an offset (bit) to each char tile in an array and compress that too. BTW, the same technique can be used for RLE as well with care.

Mike
Interesting... Thanks Mike, I'm going to look into this :) Question tough - are you saying to compress the entire tileset and somehow keep track of where each tiles offset or to compress each tile individually, combining them all into one array and keeping track of the offset for each everytime ?

#17178 - Miked0801 - Tue Mar 02, 2004 10:47 pm

Quote:

Interesting... Thanks Mike, I'm going to look into this :) Question tough - are you saying to compress the entire tileset and somehow keep track of where each tiles offset or to compress each tile individually, combining them all into one array and keeping track of the offset for each everytime


Yes. With Huffman (and RLE for that matter), each symbol (in this case byte) takes a known amount of bits to store. All you need to do then is trace through the compressed (whole tileset) data counting bits and storing where each tile begins. This table does eat into your compression a bit, but with care, tricks, and compression, you can keep the loss on your overall compression to about 1%. Just store this table at the beginning of your charset. Keep in mind that Huffman won't give nearly as good of compression as other types (probably with lookup table around 20%) so there is a cost. You will also take a fairly signifigant CPU hit on scroll fills so beware there. You need to really understand how this compression and scroll method works in order to get it to run at all fast.

I went through the same process as you not too long ago. Dictionary compression on 32 bytes (64 for 8-bit) is a waste. RLE doesn't work so good, Arithmetic takes too long. That kinda left Huffman :)