-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSaveMetadata.txt
77 lines (64 loc) · 3.36 KB
/
SaveMetadata.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
CHECKSUMS:
As far as I can see, there are two kinds:
- 32bit/word checksum: generated by function at FE8U:08000360 (ARM!). Used in save metadata.
- 16bit/short checksum: generated by function at FE8U:080A2CFC (not ARM). Used in general metadata.
u16 ComputeChecksum16(const u16* data, int size)
{
unsigned addAcc = 0;
unsigned xorAcc = 0;
for (int i = 0; i < size/2; ++i)
{
addAcc += data[i];
xorAcc ^= data[i];
}
return (u16)(addAcc + xorAcc);
}
u32 ComputeChecksum32(const u16* data, int size)
{
unsigned addAcc = 0;
unsigned xorAcc = 0;
for (int i = 0; i < size/2; ++i)
{
addAcc += data[i];
xorAcc ^= data[i];
}
return (u32)((addAcc & 0xFFFF) + (xorAcc << 16));
}
E000000, general metadata:
+00 | char[8] | "AGB-FE9\0" (magic)
+08 | word | 0x40624 (magic)
+0C | ushort | 0x200A (magic)
+0E | byte | bitfield related to game completion:
& bit 0 | game was beat at least once
& bit 1 | ?
& bit 2/3/4 | game was beat on eirika easy(2)/normal(3)/difficult(4) at least once (Checked by 3rd trainee promotion things)
& bit 5/6/7 | game was beat on ephraim easy(5)/normal(6)/difficult(7) at least once (Checked by 3rd trainee promotion things)
+0F | byte | bitfield again
& bit 0 | ?
+14 | byte[$C] | Array of completed playthrough ids. Each time you complete the game, the playthrough id of your current save will be added to that array (unless it is already in it, or the array is already filled).
+20 | byte[$20] | "array" of 2bit entries, ordered the same way as support talk info table. each entry is the max support talk seen for that entry (3 is A, 2 is B, 1 is C, 0 is none). 0x20 bytes of 2 bit entries means 0x80 entries max (128).
+40 | byte[$20] | bit "array", indexed by character id. If the bit is set, it means the character is known (used for support viewer).
+60 | short | 16bit checksum of the first $50 bytes of this struct
+62 | byte | last game save slot
+63 | byte | if 1, save to second suspend slot?
E000064, array of 7 "save metadata" (one for each save block):
+00 | word | magic number:
0x40624 for save or suspend (blocks 0-4)
0x20112 for link arena stuff (block 5)
0x20223 for block 6
+04 | short | also magic number (fixed 0x200A for non-"blank" blocks, 0 otherwise)
+06 | byte | block type: 0 for saves; 1 for suspends; 2 for link arena data; 3 for whatever block 6 is; FF for no block
+08 | short | block start offset
+0A | short | block size
+0C | word | 32bit checksum of the whole save block
PLAYTHROUGH IDS:
Each time you start a new game, it will be assigned a "unique" playthrough id. This id is basically used to prevent you from completing the same save multiple times to get a higher completion count (only really relevant in FE6/FE7(J? idr))
it is "unique" because:
for number : [0 to 255]:
if number in completed_playthroughs:
continue
for save_metadata : save_metadatas:
if save_metadata.id == number
continue
playthrough_id = number
The playthrough id is stored to byte at ChapterData+18