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 > Working with maps in ROM & dynamically changing tiles

#20813 - DiscoStew - Tue May 18, 2004 7:30 am

Before getting into working with sprites, I had done a little bit dealing with backgrounds. Now, after many months away from backgrounds, I'm getting back into it, but I've been trying to think of a good way of doing maps. Normally, the easiest way is to have a big map array designating where tiles are places. Then there are other forms, like abstract maps discussed in this thread. For the moment, I am going to take the easy route. Now...

What would be the best way to change a tile or group of tiles of a map if the map is stored in ROM? I've heard some say to place the entire map into EWRAM, but depending on how big the map is, that option doesn't sound very logical. Using the "load a new row/column of tiles every 8 pixels onto a wrapping background" method, would it be a good idea to compare every newly uploaded tile to an array that lists all the changes that have been made in the map? I know it sounds bad and a waste of processing, considering if a map had a lot of changes done to it. Maybe if I were to split each maps into sections, with each section having its own list of changes, there wouldn't have to be so much checking. Does that sound more logical? Just some simple examples of this would be a treasure chest going from closed to open (FF IV), or perhaps a tree, covered in leaves, changed to a leaf-less, burnt stump.

Perhaps someone out there has a better variation to do maps, including tile changes, than I do. If so, I'd like to hear about it.
_________________
DS - It's all about DiscoStew

#20841 - Akolade - Tue May 18, 2004 5:40 pm

I was faced with the same problem. My solution was to define such tiles as a special tile. Keep an array of all tiles which are "alterable". You must keep this array in RAM somewhere obviously. This array would keep track of the coordinates of the tile and the current tile # it's supposed to be set to. So whenever one of these tiles comes onscreen, you must check through this array and update the map according to the value in the array.
You will want to organize this array in a useful way so that you don't have to search through the entire thing everytime your map scrolls. One method would be to organize it in a "grid" so you only have to check the area you are currently in.
So, say your open chest is onscreen and you close it. You update it's entry in your "alterable tiles" array, and also update your map. If you were to leave the screen then come back, your game engine will see it's new tile# in the array and correctly set the tile on the map.

This method saves you from having to store the entire map in RAM. You only store values for tiles that can be altered, which I assume is only a small part of the map.

Hopefully that made sense!

#20844 - Miked0801 - Tue May 18, 2004 6:29 pm

Are you asking about edge loading scrolling or about subbing tiles that are currently displayed on the maps to something else (BG animation)? Once I know which, I'll give you a good answer as I've done both a bunch.

#20855 - Akolade - Tue May 18, 2004 6:51 pm

I think he means BG animation.

I'd love to hear your method as this is a topic I have found almost no documentation on. I am wondering if there is a better way.

For tiles that are constantly animated, of course, you would update the tile in memory itself, and not alter a map. For example, a fountain or something, assuming in your game all fountains sharing the same tiles are always running.

#20859 - DiscoStew - Tue May 18, 2004 8:15 pm

I don't know if you would call it BG animation, since it is not a continual animation. Just changing a single or multiple tiles to different values once. If the new tile is pointed to a continually changing tile, it shall be so. I'm thinking of more like an event-driven change, like how RPGMaker 2000 works, for those who know what I'm talking about. The difference would be that the map isn't loaded into RAM which would have been easy to work with.

I like Akolade's idea, but that would be a problem, for example, in something like SofM with grass. As the grass can be cut down, there could be a lot of it. Even if all grass tiles were listed as alterable, and the map was split into grids, depending on how much grass there is it would take a good amount of RAM. Still, I'd probably be better off trying that method.

I've even considered of replacing some of these alterable tiles to sprites, as my object handler would be very capable of doing that. The problem with that is that maybe the map layer is altered into a Mode 7 look.

There are many possibilities, so perhaps I shouldn't be complaining that one method doesn't work for all situations.
_________________
DS - It's all about DiscoStew

#20861 - Akolade - Tue May 18, 2004 8:40 pm

If it were something like grass, where it was changing from one state to another, you could probably get creative and use individual Bits to keep track of things. Really depends on the situation. You can't get around the fact that you are going to have to keep track of things SOMEWHERE in RAM. However, there are probably some creative ways to cut down on memory usage, like using Bits when possible.

#20874 - Miked0801 - Tue May 18, 2004 10:50 pm

Ok, BG animation then.

For us, we are currently using meta char maps that are 4x4 chars to 1 tile. That means any tile animation has to be subbed from an area that big (which isn't really a problem as if a smaller area is needed, just repeat the chars in the off areas.) Now that meta map is held entirely in EWRAM because we compress the hell out of it (these maps typically get 90-99.9% compression rates due to their cardinal data style (0,1,2,3...)). So we just store the X/Y position of where to sub, and the pattern of 4x4s to sub in. First, as we dynamically load chars, we free all chars within the animation area, then we change the tile pointer in slow ram, finally, we decompress the new char data into a holding buffer to update during VBlank (as the area we are playing with is on screen and loading directly will cause tearing.)

Another way of animating is what we call char animation. That is, we take every occurance of ROM char number X and replace it with ROM char Y. Great for fire, water, or other global map effects. Quick too as no map data ever changes.

A newer way of doing this that we will probably do in the coming months is to get away from meta tiles completely and only work with the map data that is already within 1 screen of the edge. This way only a small portion of the map is every displayed. To BG tile sub with this method, I'd create a list of every animation requested and probably linear search through the list cross checking vs each anims X/Y against what is currently visible. As we'd rarely have more than about 5 animations on a map, the linear sarch wouldn't hurt. If this became too slow, I'd create a hash table using something like (X * base 2 constant + Y) & ((base 2 table size like 64)-1) as my hash function. As animations are usually somewhat spread out in X and Y, this should create a good hash function.

Hope this helps.