I have the Amiibos, and a 'before' save. On the principle of making the fewest changes needed for a comparison I'm in the ideal place.
But first off, for inserting data, we need to know how the file format works, and the following applies to all three files in a save.
————————————————————————————————————————————————————
The data is all read sequentially, each bit of data read will tell you how much you need to read next, but (with one exception) you're never
explicitly told how many bytes. Therefore to
properly parse the file you need to first read it in its entirety.
The first 4 bytes specify (int32) the number of blocks within a the file. Repeat the following steps for each block.[1]
- Read the first 4 bytes of the block (int32) — this will tell you how many chunks of data are in this block. Repeat the following steps for each chunk.
- Read the first 4 bytes of the chunk — this is the ID of the chunk i.e. what data it represents.
- Read the next byte — this tells you what type of data the chunk contains.
- Read the next x bytes — This is the data. Length varies depending on data type.
- If you have read all the chunks specified the block has ended, there is no ending marker and the next block starts immediately with its chunk count as in step 1.
- If you have read all the block specified the file has ended. Any data beyond this point appears to be ignorable garbage.
Data Types (that I've identified so far):
0x62[1 byte] - int8
0x63[
x bytes] - array (int8?) — Read the first 4 bytes of data [int32] first, this will tell you the length in bytes of the remaining data for this chunk. This is the only time the file specifically says read
x bytes.
0x66[4 bytes] - float
0x69[4 bytes] - int32
0x73[
x bytes] - string — Just a standard null terminated string, read until you encounter 0x00
0x75[4 bytes] - Varies as to what it seems to represent, but always 4 bytes long
0x76[12 bytes] - I've got no idea what this is, but the only example I've seen was 12 bytes long so that's all I've got to go on so far.
The first chunk within a block will always be in the following form:
Code:
C5 9C 2C EE 75 xx xx xx xx
That is:
Chunk ID: C5 9C 2C EE
Data Type: 75
Block ID: xx xx xx xx
Chunk IDs should be unique to a block, but the same chunk ID can appear in two different blocks. (Most notably the ID 'C5 9C 2C EE' seen above, which specifies that this chunk contains the block ID)
Block IDs should be unique within a file.
————————————————————————————————————————————————————
So now we should have the information we need to insert data successfully.
First work out how many new chunks you're adding.
Increment the chunk count for this block to represent the new count.
Insert the new chunks.
I'm doing more work right now on exactly what's what within pkprfl.bmssv (which seem to be where all this stuff is stored) does what. But I thought I'd post this for now and edit more later.
[1] There may be data beyond the end of the last block. Best as I can tell the game writes blindly to the file, and doesn't truncate it if the new data written is shorter that what already existed. This data can be ignored.