Skip to content

Instantly share code, notes, and snippets.

@zephenryus
Last active October 16, 2018 06:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zephenryus/e46c797ccecf6134d4245bb9f2e5e2a5 to your computer and use it in GitHub Desktop.
Save zephenryus/e46c797ccecf6134d4245bb9f2e5e2a5 to your computer and use it in GitHub Desktop.

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

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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment