Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # `trackblock` File Specification
- ## `trackblock` File Layout
- `trackblock` files contain a header, body with multiple segments and a footer.
- * Header
- * Body
- * Segments
- * Footer
- **Note:** The footer of each file contains 7104 bytes null bytes (`00`). This is considered normal. The reason for the file padding is unknown.
- ## `trackblock` Header
- ### Header Layout
- | Offset | Length | Type | Description |
- |--:|:-:|---|---|
- | `0x00` | 1 | Unsigned Byte | File Index? |
- | `0x01` | 1 | Unsigned Byte | File Index Repeated? |
- | `0x02` | 1 | Unsigned Byte | Unknown. Values include `2f`, `08`. |
- | `0x03` | 1 | Unsigned Byte | Unknown. Always `00` |
- | `0x04` | 1 | Unsigned Byte | Unknown. Values include `01` and `00` |
- | `0x05` | 1 | Unsigned Byte | Unknown. Values include `2c` and `cd` |
- | `0x06` | 2 | Unsigned Short | Unknown. Always `00 00` |
- | `0x08` | 4 | Unsigned Int | Unknown. Values include `00 00 00 00` and `00 00 00 10` |
- | `0x0c` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x10` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x14` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x18` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x1c` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x20` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x24` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x28` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x2c` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x30` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x34` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x38` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- | `0x3c` | 4 | Unsigned Int | Unknown. Always `00 00 00 00`. Padding? |
- ## `trackblock` Body
- Each file covers an average of 7.42 hours (based on 26 files).
- ### Segments
- Each file body is divided into 48 segments. Segments cover an average of about 10 minutes and contain an array of location and meta data
- #### Segment Header
- | Offset | Length | Type | Description |
- |--:|:-:|---|---|
- | `0x00` | 4 | Unsigned Int | Timestamp1 |
- | `0x04` | 4 | Unsigned Int | Timestamp2 |
- | `0x08` | 8 | | Padding |
- #### Parameters
- ##### Timestamps
- These values are not always equal. Possibly playtime vs playtime + idle time?
- #### Segment Body
- The segment body contains an array of 300 four-byte entries. There does not seem to be a set amount of time between each entry, but the time averages out to be around 2 seconds between each location logged.
- | Offset | Length | Type | Description |
- |--:|:-:|---|---|
- | `0x00` | 4 | Unsigned Int | Entry |
- Nintendo has compiled quite a bit of data into each entry. Each entry is a 32-bit unsigned integer describing coordinates and meta data (as flags).
- The following big-endian value
- ```
- Hex: 0x8E6ADF6E
- Int: 2389368686
- Bin: 0b10001110011010101101111101101110
- ```
- would be decompiled in the following manner:
- ```
- 7 6 5 4 3 2 1 X Coordinate 0 Y Coordinate
- 1 0 0 0 1 1 1 001101010110 1 111101101110
- ```
- | Bit | Length | Type | Description |
- |--:|:-:|---|---|
- | `0` | 12 | Unsigned Int | Y-coordinate |
- | `12` | 1 | Boolean | `flag_0` Y-coordinate sign |
- | `13` | 12 | Unsigned Int | X-coordinate |
- | `26` | 1 | Boolean | `flag_1` Horizontal shift |
- | `27` | 1 | Boolean | `flag_2` Y-coordinate sign |
- | `28` | 1 | Boolean | `flag_3` Teleport? |
- | `29` | 1 | Boolean | `flag_4` Player auto-placement? |
- | `30` | 1 | Boolean | `flag_5` Death |
- | `31` | 1 | Boolean | `flag_6` Horse Riding |
- | `32` | 1 | Boolean | `flag_7` MainField or Dungeon / AocField |
- #### Flags
- | Flag | `0` | `1` | Description |
- |--:|:-:|:-:|---|
- | `0` | -y | +y | Mirrors point across the x-axis |
- | `1` | `false` | `true` | Horizontal shift (`+4096`) |
- | `2` | -x | +x | Mirrors point across the y-axis |
- | `3` | `true` | `false` | Player auto-placement? |
- | `4` | `true` | `false` | Teleport? |
- | `5` | `true` | `false` | Death |
- | `6` | `true` | `false` | Riding a horse? |
- | `7` | `true` | `false` | `true` = MainField , `false` = Dungeon or AocField |
- #### Parsing Algorithm
- The following algorithm works for big endian
- ```c++
- for (int int = 0; int < 300; int++) {
- // Read unsigned int from file into unsigned int data
- unsigned int y = data & 0xfff
- unsigned int x = (data & 0x1ffe000) >> 13
- unsigned int flag = (data & 0xfc000000) >> 26
- unsigned int flag_0 = (data & 0x1000) >> 12
- unsigned int flag_1 = (data & 0x2000000) >> 25
- unsigned int flag_2 = flag & 0b000001
- unsigned int flag_3 = (flag & 0b000010) >> 1
- unsigned int flag_4 = (flag & 0b000100) >> 2
- unsigned int flag_5 = (flag & 0b001000) >> 3
- unsigned int flag_6 = (flag & 0b010000) >> 4
- unsigned int flag_7 = (flag & 0b100000) >> 5
- }
- ```
Add Comment
Please, Sign In to add comment