If you are still using the old URL (datacrystal.romhacking.net), please update your bookmarks! The old URL may stop working soon.
The current URL is datacrystal.tcrf.net.
The current URL is datacrystal.tcrf.net.
Final Fantasy/World map data: Difference between revisions
Jump to navigation
Jump to search
(→top: replaced: {{x}} → x) |
|||
(6 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
[[Final Fantasy | {{subpage}} | ||
[[Final Fantasy]] (and [[Final Fantasy II]] as well) uses a 256x256-tile world map in this data format. The map data is not stored raw, but uses simple compression in a kind of run-length encoding. The ROM (in [[iNES]] format) stores its world map data starting at {{$|4010}}. | |||
== Row pointers == | == Row pointers == | ||
From $4010 to $4210 there are 256 little-endian 16-bit integer values representing addresses in the NES memory map (with the $4010 ROM bank currently in place) that mark the left-hand-side beginnings of each 256-tile row of the map. | From {{$|4010}} to {{$|4210}} there are 256 little-endian 16-bit integer values representing addresses in the NES memory map (with the {{$|4010}} ROM bank currently in place) that mark the left-hand-side beginnings of each 256-tile row of the map. (Because memory pointers are used in this fashion, it is entirely possible for more than one pointer to point to the identical memory location if they use identical row data, such as a 256-tile row of ocean.) Since this bank will loaded into the NES memory map at readable address {{$|8000}}, all memory pointers in the ROM must point to the row's ROM file address + {{0x|3FF0}}. To translate a memory pointer back into a ROM file address, you subtract {{0x|3FF0}} instead. | ||
== Row data == | == Row data == | ||
Because the row pointers point to active NES memory in which the $4010 must be active, ''all'' of the map data is confined to this bank. | Because the row pointers point to active NES memory in which the {{$|4010}} must be active, ''all'' of the map data is confined to this bank. Unrelated data begins at file address {{$|7F50}}, so all row data referenced by pointers must be located starting at {{$|4210}} and ending before {{$|7F50}}, giving you {{0x|3D40}} bytes to store your map row data. | ||
Row data is stored sequentially as such: | Row data is stored sequentially as such: | ||
* Byte values indicate a row's tiles from the left-edge, from left-to-right through the tiles, ending at the row's right edge. | * Byte values indicate a row's tiles from the left-edge, from left-to-right through the tiles, ending at the row's right edge. | ||
* A single byte ranging | * A single byte ranging {{0x|00}} to {{0x|7F}} describes a single tile of a specific value. The next byte describes the tile to its right. | ||
* A byte ranging | * A byte ranging {{0x|80}} to {{0x|FE}} is the same as its value subtracted by {{0x|80}} (or exclusive-or'ed by {{0x|80}}), but the immediately following byte indicates repetition of the tile value. A repetition byte value of {{0x|01}} means no repetition, {{0x|0x02}} means repeat once, {{0x|0x03}} means repeat twice, {{0x|04}} means repeat three times, and so on. {{0x|00}} means to repeat 256 times, so that it can fill an entire row. A repetition value of {{0x|FF}} is prohibited. | ||
* A byte value of | * A byte value of {{0x|FF}} after the row's final tile terminates the row data. | ||
So, for example: | So, for example: | ||
: | :{{0x|04}} | ||
::1 tile valued | ::1 tile valued {{0x|04}} | ||
: | :{{0x|73}} | ||
::1 tile valued | ::1 tile valued {{0x|73}} | ||
: | :{{0x|96}} {{0x|01}} | ||
::1 tile valued | ::1 tile valued {{0x|16}} | ||
: | :{{0x|96}} {{0x|05}} | ||
::5 consecutive tiles valued | ::5 consecutive tiles valued {{0x|16}} | ||
: | :{{0x|96}} {{0x|00}} {{0x|FF}} | ||
::256 consecutive tiles (an entire row) valued | ::256 consecutive tiles (an entire row) valued {{0x|16}}, and a row terminator | ||
== FF1 Overworld Tile Values == | == FF1 Overworld Tile Values == | ||
Line 154: | Line 156: | ||
7C = Village Wall 1 | 7C = Village Wall 1 | ||
7D = Village Wall 2 | 7D = Village Wall 2 | ||
7E = | 7E = Village Wall 3 | ||
7F = Village Fence - Bottom Right | |||
</pre> | </pre> | ||
==FF2 tile values== | ==FF2 tile values== | ||
{{todo|This}} | |||
Latest revision as of 18:10, 28 January 2024
This is a sub-page of Final Fantasy.
Final Fantasy (and Final Fantasy II as well) uses a 256x256-tile world map in this data format. The map data is not stored raw, but uses simple compression in a kind of run-length encoding. The ROM (in iNES format) stores its world map data starting at $4010
.
Row pointers
From $4010
to$4210
there are 256 little-endian 16-bit integer values representing addresses in the NES memory map (with the$4010
ROM bank currently in place) that mark the left-hand-side beginnings of each 256-tile row of the map. (Because memory pointers are used in this fashion, it is entirely possible for more than one pointer to point to the identical memory location if they use identical row data, such as a 256-tile row of ocean.) Since this bank will loaded into the NES memory map at readable address$8000
, all memory pointers in the ROM must point to the row's ROM file address + 0x3FF0
. To translate a memory pointer back into a ROM file address, you subtract 0x3FF0
instead.
Row data
Because the row pointers point to active NES memory in which the $4010
must be active, all of the map data is confined to this bank. Unrelated data begins at file address $7F50
, so all row data referenced by pointers must be located starting at $4210
and ending before $7F50
, giving you 0x3D40
bytes to store your map row data.
Row data is stored sequentially as such:
- Byte values indicate a row's tiles from the left-edge, from left-to-right through the tiles, ending at the row's right edge.
- A single byte ranging
0x00
to0x7F
describes a single tile of a specific value. The next byte describes the tile to its right. - A byte ranging
0x80
to0xFE
is the same as its value subtracted by0x80
(or exclusive-or'ed by0x80
), but the immediately following byte indicates repetition of the tile value. A repetition byte value of0x01
means no repetition,0x0x02
means repeat once,0x0x03
means repeat twice,0x04
means repeat three times, and so on.0x00
means to repeat 256 times, so that it can fill an entire row. A repetition value of0xFF
is prohibited. - A byte value of
0xFF
after the row's final tile terminates the row data.
So, for example:
0x04
- 1 tile valued
0x04
- 1 tile valued
0x73
- 1 tile valued
0x73
- 1 tile valued
0x96
0x01
- 1 tile valued
0x16
- 1 tile valued
0x96
0x05
- 5 consecutive tiles valued
0x16
- 5 consecutive tiles valued
0x96
0x00
0xFF
- 256 consecutive tiles (an entire row) valued
0x16
, and a row terminator
- 256 consecutive tiles (an entire row) valued
FF1 Overworld Tile Values
00 = Grass 01 = Castle 1 - Lower Left 02 = Castle 1 - Lower Right 03 = Forest - Top Left 04 = Forest - Top 05 = Forest - Top Right 06 = Grass - Bottom Right 07 = Grass - Bottom 08 = Grass - Bottom Left 09 = Castle 1 - Top Left 0A = Castle 1 - Top Right 0B = Castle 2 - Top Left 0C = Castle 2 - Top Right 0D = Tower of Illusion - Top 0E = Grotto 1 0F = Dock - Vertical Left 10 = Mountain - Top Left 11 = Mountain - Top 12 = Mountain - Top Right 13 = Forest - Left 14 = Forest - Bottom 15 = Forest - Right 16 = Grass - Right 17 = Ocean 18 = Grass - Left 19 = Castle 1 - Middle Left 1A = Castle 1 - Middle Right 1B = Castle 2 - Bottom Left 1C = Castle 2 - Bottom Right 1D = Tower of Illusion - Bottom 1E = Tower of Illusion - Shadow 1F = Dock - Vertical Right 20 = Mountain - Left 21 = Mountain 22 = Mountain - Right 23 = Forest - Bottom Left 24 = Forest - Bottom 25 = Forest - Bottom Right 26 = Grass - Top Right 27 = Grass - Top 28 = Grass - Top Left 29 = Castle 2 - Bottom Left 2A = Castle 2 - Bottom Right 2B = Grotto 2 2C = Village Fence - Top Left 2D = Village Fence - Top 2E = Village Fence - Top Right 2F = Grotto 3 30 = Mountain - Bottom Left 31 = Mountain - Bottom 32 = Grotto 4 33 = Mountain - Bottom Right 34 = Grotto 5 35 = Grotto 6 36 = Desert 37 = Desert 38 = Castle 2 - Bottom Left 39 = Castle 2 - Bottom Right 3A = Grotto 7 3B = Village Fence - Top Left Exterior 3C = Village Fence - Top Left Interior 3D = Village Area (gray) 3E = Village Fence - Top Right Interior 3F = Village Fence - Top Right Exterior 40 = River - Top Left 41 = River - Top Right 42 = Desert - Top Left 43 = Desert - Top Right 44 = River 45 = Desert 46 = Waterfall 47 = Castle Ruins - Top Left 48 = Castle Ruins - Top Right 49 = Village 1 4A = Village 2 4B = Village Fence - Middle Left 4C = Village 3 4D = Village 4 4E = Village 5 4F = Village Fence - Middle Right 50 = River - Bottom Left 51 = River - Bottom Right 52 = Desert - Bottom Left 53 = Desert - Bottom Right 54 = Tall Grass 55 = Swamp 56 = Castle Ruins - Bottom Left 57 = Castle Ruins - Bottom Middle Left 58 = Castle Ruins - Bottom Middle Right 59 = Castle Ruins - Bottom Right 5A = Village 6 5B = Village Fence - Middle Left 2 5C = Village Fence - Bottom Left 5D = Village 7 5E = Village Fence - Bottom Right 5F = Village Fence - Middle Right 2 60 = Tall Grass - Top Left 61 = Tall Grass - Top Right 62 = Swamp - Top Left 63 = Swamp - Top Right 64 = Volcano - Top Left 65 = Volcano - Top Right 66 = Hole 1 67 = Hole 2 68 = Hole 3 69 = Hole 4 6A = Hole 5 6B = Village Fence - Middle Left 3 6C = Hole 6 6D = Village 8 6E = Hole 7 6F = Village Fence - Middle Right 3 70 = Tall Grass - Bottom Left 71 = Tall Grass - Bottom Right 72 = Swamp - Bottom Left 73 = Swamp - Bottom Right 74 = Volcano - Bottom Left 75 = Volcano - Bottom Right 76 = Grass 77 = Dock - Bottom Right 78 = Dock - Bottom 79 = Dock - Bottom Left 7A = Dock - Top Left 7B = Village Fence - Bottom Left 7C = Village Wall 1 7D = Village Wall 2 7E = Village Wall 3 7F = Village Fence - Bottom Right
FF2 tile values
To do: This |