DAT (File Format)

From MK7
Jump to navigation Jump to search

DAT is the format of Time Trial ghost data in Mario Kart 7. This format is common between ghosts saved in the saved file, staff ghosts and ghosts received through StreetPass and SpotPass.

User-created ghosts are stored in the replay directory. There's also another directory named replay_, that serves as a backup for the replay directory. The SpotPass ghosts are located in the SpotPass data, which can be extracted using homebrew tools such as FBI (Ext Save Data > MARIO KART 7 > Browse SpotPass User Data). Staff ghosts are stored in the replay directory in the RomFS.

The file consists of a header describing metadata of the ghost such as vehicle and character used, the finishing time, etc. The main contents of the file is then the sequence of controller inputs made by the player, which can be used to replay the ghost. Following the ghost input data is a CRC-32 which the game uses to verify the file has not corrupted (this is not present in ghosts received through StreetPass and SpotPass).

The file always have a size of either 0x289C (with checksum) or 0x2898 (without checksum).

File Header

NOTE: All of the offsets described here correspond to the offsets of the file when converted from 32 bit little endian to 32 bit big endian.

An DAT file begins with the 0xC0 byte header.

Header of DAT file
Offset Size Description
0x00 4 "DGDC" in ASCII (CDGD in big endian); CTR Dash Ghost Data file identifier.
0x04 4 bits Unknown. Always 0.
0x04.4 1 bit Raced using 1st person view 80% of the time flag; 0 = No, 1 = Yes. If yes, a black wheel icon will appear in the ghost card.
0x04.5 3 bits Course lap type. 01 for section-based courses (Wuhu Loop / Maka Wuhu / Rainbow Road), and 03 for every other course. Strangely enough, the expert staff ghost for Maka Wuhu (replayF09.dat) and the easy and expert staff ghosts for Rainbow Road (replayS13.dat and replayF13.dat) are the only ghosts that set this value to 00.
0x05 10 bits Milliseconds field of finishing time.
0x06.2 7 bits Seconds field of finishing time.
0x07.1 7 bits Minutes field of finishing time.
0x08 1 bit Unknown. Always 0.
0x08.1 7 bits Minutes field of lap 2.
0x09 10 bits Milliseconds field of lap 1.
0x0A.2 7 bits Seconds field of lap 1.
0x0B.1 7 bits Minutes field of lap 1.
0x0C 1 bit Unknown. Always 1. The game sets a value to this field in the instruction at 0x0044fcc0 + 0x118. It copies the value from field 0x9C of System::PlayerData (which is the least significant bit of byte 0x06 from the save data file) here (and also expects the value to be 1).
Additionally, starting at 0x00474f5c + 0x16C, the game checks if this value is different from 0.
0x0C.1 7 bits Seconds field of lap 3.
0x0D 7 bits Minutes field of lap 3.
0x0D.7 10 bits Milliseconds field of lap 2.
0x0F.1 7 bits Seconds field of lap 2.
0x10 22 bits Unknown. Always 1. This field is set to 1 in the constructor of the ghost header, and System::GhostSaveDataHeader::isValid checks if said field is 1.
0x12.6 10 bits Milliseconds field of lap 3.
0x14 1 Unknown. Always 0.
0x15 4 bits Glider ID used by the ghost.
0x15.4 4 bits Tire ID used by the ghost.
0x16 5 bits Kart ID used by the ghost.
0x16.5 5 bits Character ID used by the ghost.
0x17.2 6 bits Course ID.
0x18 0x14 Mii's UTF-16 encoded name (in big endian).
0x2C 2 Unknown. Always 0. The game sets this field to 0 in the instruction 0x0044fcc0 + 0xE8
0x2E 2 Unknown. Always 0.
0x30 0x60 Driver's Mii data. The exact format of this Mii data is CFSD, as it contains a 2-byte checksum at the end of the data. Note that all ghosts save the Mii data, but, aside of the name, said data cannot be seen in-game unless the player has raced as a Mii.
0x90 2 Country code. Also used to determine whether the game should display the string "Nintendo" or "Retro Studios" for staff ghosts.
01 (Japan) = "Nintendo", otherwise "Retro Studios".
0x92 2 Unknown. Always 0.
0x94 2 Globe coordinates (latitude). The latitude of the physical coordinates on the Wi-Fi / Mario Kart Channel globe the Mii appears on.
0x96 2 Globe coordinates (longitude). The longitude of the physical coordinates on the Wi-Fi / Mario Kart Channel globe the Mii appears on.
0x98 4 Unknown. Always 0.
0x9C 4 Unknown. Modifying this value does not change anything in-game, so this may be some kind of revision number. All user-created ghosts set this value to 0x752F (29999), while the staff ghosts have different values depending on the ghost (they don't follow a specific pattern). Those values are: 0000, 0x4DFD (19965), 0x4E4B (20043), 0x4EC3 (20163), 0x4EEA (20202) and 0x4F9C (20380)
This field is set to 0x752F in the instruction 0x0044fcc0 + 0x138
0xA0 0x20 Unknown. Always 0.
0xC0 End of this header; start of data

Additional Information

NOTE: The following RAM addresses are for the EUR Rev0 v1.1 version of the game.

  • The function starting at 0x0044fcc0 writes the data of the ghost header upon saving a new ghost. r4 contains the pointer to the ghost header.
  • System::GhostSaveDataHeader::GhostSaveDataHeader() is the constructor of the ghost data header. Said function starts at 0x00450130. r0 contains the pointer to the ghost header.
  • System::GhostSaveData::GhostSaveData() is the constructor of the ghost data. Said function starts at 0x00444220. r0 contains the pointer to the ghost data.
  • System::GhostSaveDataHeader::isValid() starts at 0x005165d0.

Controller Input Data

The header is then followed by the input data. The controller input data must be less than or equal to 0x27D8 bytes in length. The input data is padded to exactly 0x27D8 bytes in length.

The input data begins with the following 4 byte header (in 16 bit little endian).

Header of DAT input data section
Offset Size Description
0x00 2 Length of face button input data.
0x02 2 Length of direction input data.
0x04 End of this header; start of face button input data.

Just like in Mario Kart Wii, the actual input data then follows in complete sections in the order of face button inputs and direction inputs. Each uses a 2 byte format, 1 byte representing the state of the specified input then the next representing the duration for which that input was held in frames. The sections follow on sequentially from each other. If an input state is held for more than 255 frames, it is continued as the next input. The meaning of the state byte differs per section as follows.

Face button input byte
Bit mask Description
0x01 A button is pressed.
0x02 B button is pressed.
0x04 X button is pressed.
0x08 Y button is pressed.
0x10 L button is pressed.
0x20 R button is pressed.
0x40 1st person view is enabled.
0x80 Unknown, probably unused.
Direction input byte
Bit mask Description
0x0F Forward/backward input (a range; 0xE is forward, 0x0 is backward, 0x7 is neutral).
0xF0 Left/right input (0xE0 is right, 0x00 is left, 0x70 is neutral).

CRC

All ghosts (except the ones received through StreetPass and SpotPass) have a CRC-32 of the file up to that point (in little endian) at offset 0x2898.

Tools

The following tools can handle DAT files: