Robotrek/Notes

From Data Crystal
Jump to navigation Jump to search

Chip tiny.png The following article is a Notes Page for Robotrek.

Map Meta

There are two map meta tables: one at 0x040000, and another at 0x0D8000. These tables define how assets are loaded into each map/scene. Each map record in a meta table starts with a two-byte map ID, followed by an array of "asset" entries. There are 8 major types of assets, which are defined by the first byte of the asset entry itself. Each map record is terminated by a single byte 0x00 (asset 0). Each meta table ends with a single, empty map 0xFFFF record, followed by 0x2121. To find a map/marker, the entire meta table is scanned sequentially up to either the map or marker ID. This consumes a lot of CPU time.

{ mapId: Word, assets: meta[], terminator: Byte }
{ mapId: Word, assets: meta[], terminator: Byte }
...etc
{ mapId: 0xFFFF, assets: [], terminator: 0}
{ 0x2121 }

Control Commands

Meta asset 08 entries are Control commands. They define miscellaneous functions that are applied to the map loading process. The second byte of a Control command determines what function it serves. Each map record starts with a State Control (08 00) entry which defines a global post-marker, and a state index from which to load scene effect information.

Music Loading

Table D8000 begins with a special map with ID 7FFF which serves as a list of Music assets to be referenced by BGM Control (08 FC). Instead of defining a Music(02) asset in the map, there are instead BGM Control entries (to save space perhaps, 4 vs 6 bytes). A person could opt to use either it seems, at the cost of either space or CPU.

Separate Map Meta Tables

For some reason Quintet decided to use two tables for map definitions. Building on their process from Illusion of Gaia etc, since Robotrek has twice as many maps, they could not feasibly use a single table as the map load sequence would be painfully long. It is important to note that the map IDs from each table do not intersect, they are unique with the exception of map IDs 0000 and FFFF. Map 0000 from D8000 is loaded when the game boots.

Address Encoding

For some reason, each asset's data address is encoded using a process unique to this game, instead of using direct addresses. The process is somewhat complicated and involves shifting the upper bits 0x7F8000 << 1 and adding 0x8D or 0xC4 depending on which table is being read. The procedure for decoding them can be found here: https://github.com/Azarem/gaia-core/blob/main/src/rom/extraction/parser.ts#L291

Meta Asset Types
ID Type Parts Description
00 NULL Terminates map record
01 Strangemap { Byte, Word, Address } Loads a compressed "strangemap" into memory. Not much is known, only two of these data files exist and only four 01 records total.
02 Music state: Byte
musicId: Byte
data: Address
Immediately loads music stored at data address, but only if the musicId and data address are not currently being played.
04 Unknown ?? This does not seem to be used anywhere
08
00
State markerId: Byte
stateIndex: Byte
Each map starts with a State Control asset. This sets a markerId to be jumped to after all other entries are processed (or 0). The stateIndex determines which set of transparency / background / effect modes that are set when the map is loaded.
08
FC
BGM musicId: Byte
null: Byte
Immediately loads Music asset from map record 7FFF (first map in table D8000), determined by musicId
08
FD
Branch flagId: Byte
markerId: Byte
Branches/jumps to marker defined with markerId, but only if flagId is satisfied
08
FE
Marker markerId: Byte
null: Byte
Sets a marker to be used by Jump and Branch commands, defined by markerId
08
FF
Jump markerId: Byte
null: Byte
Immediately stops reading assets and instead jumps to marker defined with markerId
10 Tilemap layer: Byte
data: Address
Loads a tilemap
20 Tileset srcOffset: Byte
size: Byte
dstOffset: Byte
layer: Byte
data: Address
Copies tileset information into 0x7E2000 - 0x7E37FF after decompression. All tilesets are compressed. srcOffset bit 0x80 seems to denote that the tileset is not compressed but implementation was never added to handle this. srcOffset is << 6 and determines the offset from data in which to copy. size is also << 6 and determines the total size of the tileset data, but each tileset is exactly 0x800 bytes so this is not necessarily useful. dstOffset is << 6 and determines the offset from WRAM in which to copy data. layer determines which slot to copy the data into: 1, 2, 4 equates to 7E2000, 7E2800, and 7E3000, even though flag 4 seems to never be used. A tileset could potentially be copied into multiple layers.
40 Palette srcOffset: Byte
size: Byte
dstOffset: Byte
data: Address
Copies palette information, which is not compressed, into 0x7E3800. srcOffset << 1 determines the offset from data in which to copy. size is << 1 and determines the total size of the palette file, not necessarily the size being copied. dstOffset is << 1 and determines the offset into 0x7E3800 in which to copy. The total data length copied is (size - srcOffset) << 1.
80 Bitmap srcOffset: Byte
size: Byte
dstOffset: Byte
data: Address
Loads a bitmap into VRAM. srcOffset is << 9 bits (* 512), if srcOffset upper bit 0x80 is set it means the file is not compressed. Size is also << 9 bits (* 512) and determines the size of the bitmap data itself. dstOffset is the location in VRAM being copied to. The total length copied is (size - srcOffset & 0x7F) << 9