-
Notifications
You must be signed in to change notification settings - Fork 8
MPKMeta block format
MPKEdit supports a block-extension format to store additional metadata in .MPK files, mostly intended for adding user comments to save files, but may be extended in the future. When saving comments to .MPK files, the MPKMeta block is appended to the end of the .MPK.
The current MPKMeta version is 0x00
. The format is described below.
This data may be stripped by emulators that aren't aware of its existence (although some emulators I tested leave it alone). It however will be stripped when transferring to a real MPK. It's mostly useful for adding comments to your saves and archiving online somewhere.
In the future it would be great if N64 emulators supported this format directly, to allow automatic note timestamps or in-app commenting. I'm still drafting the timestamp specs, but if you are an emulator author and think keeping track of each note index being written to is plausible for timestamping, please get in touch. :)
Offset | Size | Description |
---|---|---|
0x00 | 7 |
MPKMeta magic string |
0x07 | 1 | Format version code (Current = 0x00 ). Return an error for any unsupported version codes, because future versions may not be backwards compatible. |
0x08 | 4 | Hash of entire MPKMeta block, with hashfield always zero (using first 32-bit chunk of MurmurHash3_128). |
0x0C | 3 | Unused |
0x0F | 1 | Number of Metadata Entries (1-16) |
When comments are present, a 16-byte header is expected to be at the end of a 32 KB .MPK file. A 32-bit hash is calculated from the start of this block, all the way to the end of the file. There is no "end of file" marker for MPKMeta, instead, the data length can be calculated through parsing the individual entries.
0x0F
represents the number of Meta entries, a value between 1-16, which correspond to the Note slots. Meta entries are stored immediately after the 16-byte header.
Offset | Size | Description |
---|---|---|
0x00 | 1 | Entry sanity byte (Result of XORing 0xA5 and offsets 1-4 of Note Entry) |
0x01 | 1 | IndexTable offset for specified note |
0x02 | 3 | Last 3 bytes of Game Code (eg. 'OPE' of NOPE) |
0x05 | 2 | Comment length in bytes (1-4080) (Ideally only use first 12 bits) |
0x07 | 1-4080 | Raw UTF-8 text comment data |
The Entry sanity byte is computed as follows: It is the XOR sum of 0xA5
with bytes at offset 0x01
, 0x02
, 0x03
and 0x04
of the current entry. It's essentially a very simple checksum to let the parser know the Metadata Entry is valid. The second byte (offset 0x01
) specifies the IndexTable location for the note in question. And bytes 2-4 specify the Note game code and region.
These 4 bytes (offset 0x1
and 0x2
) are required for MPKEdit to pair comment data to actual save data in the .MPK file itself. If MPKEdit cannot find the data, the comment is discarded.
Note: The size of the comment cannot exceed 4080 bytes, and only 12 bits are required to store this number. It is possible that the upper 4 bits could be repurposed in a future format version.
Firstly, the header is 16 bytes, and stores the number of Meta Entries present. Each Meta entry consists of 7 bytes plus a variable-length comment (no more than 4080 bytes). The length of the comment is conveniently stored in the meta entry. The size of the meta entry (7 bytes) is subject to change if any new features get added, removed, or changed, in a future format revision. So that should be kept in mind when supporting multiple format variants.
Thus the formula for calculating the full block would be: 16 + EntryCount * (7 + commentLength)
.
One of course has to parse the full entry list to obtain and sum all the individual commentLength
values.