Tile Configurations

So from what I’ve seen, not many people know much about tile configurations and how they work. Let’s change that!

If you have any knowledge whatsoever about tile configurations and how they work, please share it here on this topic.

From what I’ve seen, it is possible that each configuration acts as a table for each individual tile in its set. Also, not all of the tile configurations are the same size. Leading to the notion that the size is dependent on how many tiles in a set are used in game and how many remain blank.

I thought I read something about that a long time ago in I think it was Hextator’s doc but I can’t seem to find it and where’s the fun in that anyway so I looked on my own.

“Tile Config” is compressed (probably lzss but it shouldn’t matter), and when decompressed it has two fixed size parts: the first 0x2000 bytes define how each tile looks (bg tile bases), while the second 0x400 assigns terrain indices to each tile.

(This means that the size should be a fixed 0x2400? Maybe some tile sets don’t use the full 0x400 terrain bytes when they don’t need to? I decompressed tile config in chapter data slot 3 and got a 0x2400 byte file so idk)

appearance

the 0x2000 bytes are an array of 0x400 (1024, one per possible raw tile index, in order) 8 byte entries that are layed out the following way:

  +0 | short (2byte) | tile base for top left corner of tile
  +2 | short (2byte) | tile base for top right corner of tile
  +4 | short (2byte) | tile base for bottom left corner of tile
  +6 | short (2byte) | tile base for bottom right corner of tile

“tile base” is the term I use to refer to the base value that will be eventually modified to be output to a bg map (see gbatek for details about that), where the tile number is as with obj1 gfx mapped at tile 0 and obj2 gfx mapped at tile 0x200, palette as with map palette mapped at 0.

This structure is standard enough that you can just put the tile config pointer in the GBAGE Tile Control window with the corresponding obj gfx and palette and you’ll get something correct.

The function that does the “transformation” (reading from the tile config and putting to a bg map) is at FE8U:8019B18.

terrain

This one’s easier. the 0x400 bytes is a 0x400 entry array of bytes, with each entry being which terrain this tile is assigned to.

The function that updates the terrain map from tile config is at FE8U:8019A64. At FE8U:859A9D0 is a pointer to the second part of the decompressed tile config, where the terrain lookup is located.


Raw tile indices are kinda weird because they have a “step” of 4 (the first tile index is 0, the second is 4, the third is 8, etc). The arrays are indexed by floor(<raw tile index> / 4) (Well, the terrain array is, the “appearance” array will result in weird tile mixes graphics for raw tiles non divisible by 4).

Tile Config is decompressed at FE8U:80198D8 to FE8U:2030B8C and should stay there for as long as the game is running.

2 Likes

How were you able to decompress the configuration?

I found a note I left when I was making FEBuilderGBA.
The way to decide whether the tile is Plain, River or Woods is as follows.

For example, if the chipset is 0x208
What the terrain is,
1 * 2 bytes from chipset_config[(0x208 >> 2) + 0x2000].

//The calculation formulas obtained when decomposing the disassembler are as follows.
//chipset_config[ ((0x208 >> 3)*2) + 0x2000 ]
//
//Also, chipset_config is compressed with lz77, please decompress beforehand.
//

struct terrain
{
    u8 terrain_data1;
    u8 terrain_data2;
}; //sizeof() == 2

terrain_data expresses the terrain as one byte like a meadow or a treasure box.
Which one of the two data is referred to is determined by the 0x4th bit of the map chip.

if ( 0x208 & 0x4 ) terrain_data2
else               terrain_data1

terrain_data is the terrain ID used in the movement cost table and terrain name table.
terrain name table is SJIS C language string in FE8J. (null termination.).
However, in FE8U, it is a text ID.(ushort[])

I used this tool because I had that on hand but anything that can decompress standard gba lz77 data should work.

With FEBuilderGBA, you can compress and decompress lz77 from MENU -> Tool->LZ77 Tool.