-
Notifications
You must be signed in to change notification settings - Fork 0
World Maps
Note: All ROM offsets in this document are hexadecimal offsets into an unheadered v1.1 ROM.
The Overworld, Underworld, and Moon maps are encoded and rendered the same way, and are thus referred to as "World Maps".
Graphics data consists of 8x8 blocks of pixels called characters. Pixels are 4 bits (4bpp), so each character is 32 bytes in length. The low-order bits are the "first" pixel, and the high-order bits the "second" pixel in each byte. Each World Map uses 256 characters, for a total of 8 KiB of graphics.
There are 64 total colors available for rendering World Maps, stored as 16-bit color values in the format xbbbbbgggggrrrrr
(the high bit is ignored). Each character uses 16 consecutive colors from the overall palette. One byte per character specifies the offset of the first color for that character, and the other 15 follow. Note, Mode 7 allows for 256 total colors, but the rest of the colors are used for other things, like the player's character, airships, triggered event sprites, etc.
World Maps use tilesets of 128 16x16 tiles, made up of 4 characters each. A table of 512 bytes defines the characters that make up each tile, but the character references are interleaved. The first 128 bytes are the upper-left character of each tile, the next 128 bytes are the upper-right character, then the lower-left, and finally the lower-right.
Additionally, each of the 128 tiles has a set of flags that define in-game properties of the tile, such as whether it can be walked on or landed on with the airship, etc. "Walk Plateau" is used to prevent the player from walking directly from a plateau tile to a ground tile. For the "ramp" tile on the Moon, both the Walk and Walk Plateau bits are set, so the player can walk from the ground onto the ramp or from the ramp onto the plateau. "Obscures Half" means the player character is half obscured by forest/water/etc.
Property | Bit |
---|---|
Walk | 0x0001 |
Chocobo Walk | 0x0002 |
Black Chocobo Fly | 0x0004 |
Black Chocobo Land | 0x0008 |
Hovercraft | 0x0010 |
Airship Fly | 0x0020 |
Walk Plateau | 0x0040 |
Big Whale Fly | 0x0080 |
Obscures Half | 0x0800 |
Airship Land | 0x1000 |
Enemies Present | 0x4000 |
Trigger | 0x8000 |
Map | CHR Graphics (8 KiB) | Overall Palette (128 bytes) | CHR Palettes (256 bytes) | Tile Formations (512 bytes) | Tile Properties (256 bytes) |
---|---|---|---|---|---|
Overworld | 0x0E8000 |
0x0A0900 |
0x0A0600 |
0x0A0000 |
0x0A0A80 |
Underworld | 0x0EA000 |
0x0A0980 |
0x0A0700 |
0x0A0200 |
0x0A0B80 |
Moon | 0x0EC000 |
0x0A0A00 |
0x0A0800 |
0x0A0400 |
0x0A0C80 |
World Maps use Run-Length Encoding (RLE), but unlike Dungeon Maps, they are compressed one row at a time, as the SNES does not have enough memory to decompress the entire map at once. Pointers to the beginning of each row are stored at the beginning of the map data for each World Map. Each 2-byte row pointer is an offset from the beginning of the tilemap data itself, i.e. 0x0000
is the very beginning of the tilemap (this differs from the FF1 World Map, where the pointers are actual addresses into the world map's ROM bank).
Since a tileset contains 128 tiles, tile values range from 0x00
through 0x7F
. A byte containing any of these values represents one tile. A byte from 0x80
through 0xFE
represents a run of tiles, with the tile index being the value of the byte - 0x80
(i.e. with the high bit masked out). The following byte is the length of the run - 1, so 92 05
would be a run of 6 of tile 0x12
. Rows are terminated with 0xFF
, and as such, there is no way to encode a run of the 0x7F
tile.
The Overworld has a special case for compressing snow-capped mountains. The 0x00
, 0x10
, 0x20
, and 0x30
values all represent a run of 4 distinct tiles:
-
0x00
:00 70 71 72
-
0x10
:10 73 74 75
-
0x20
:20 76 77 78
-
0x30
:30 79 7A 7B
These special tiles are always placed adjacent to each other vertically, so they represent a 4x4 area of snow-capped mountain tiles in just 4 bytes. This tile formation is only found on the Overworld, and the Underworld and Moon maps do not use this encoding rule.
The Overworld and Underworld maps are 256x256 tiles, and the Moon map is 64x64. Though the Underworld has the same dimensions as the Overworld, it only really uses about half of the available horizontal and vertical space, so it compresses down to about half the size.
Map | Row Pointers | Start of Tilemap | Allocated Space |
---|---|---|---|
Overworld | 0x0B0000 |
0x0B0480 |
0x4000 bytes (16 KiB) |
Underworld | 0x0B0200 |
0x0B4480 |
0x1D00 bytes (7.25 KiB) |
Moon | 0x0B0400 |
0x0B6180 |
0x0A00 bytes (2.25 KiB) |