68
edits
m (Grammar fixes; this needs lots of work, it's practically incoherent) |
(Added offsets for Platinum, corrected an offset for D/P and cleaned up a bit) |
||
Line 1: | Line 1: | ||
{{Incomplete}} | {{Incomplete}} | ||
A {{game2|Diamond|Pearl|Platinum}} .SAV file is broken up into two pairs of blocks. Each pair has one small block, and one big block. | A {{game2|Diamond|Pearl|Platinum}} .SAV file is broken up into two pairs of blocks. Each pair has one small block, and one big block. The offsets for Platinum are different from Diamond and Pearl. | ||
In Diamond and Pearl, the first small block starts at 0x00000 and ends at 0x0C0FF, the first big block starts at 0x0C100 and ends at 0x1E2DF. | |||
In Platinum, the first small block starts at 0x00000 and ends at 0x0CF2B, the first big block starts at 0x0CF2C and ends at 0x1F10F. | |||
The second pair of blocks are at the same address plus 0x40000 for all the three games. | |||
One block pair is always a backup of the other block pair. | One block pair is always a backup of the other block pair. | ||
The last 0x14 | The last 0x14 bytes of each block (small and big) are used as a footer, with the following structure: | ||
{| border="1" style="border: 1px solid #999; border-collapse: collapse;" | |||
|- style="background: #ccc;" align="center" | |||
! Offset | |||
! Contents | |||
|- style="background: #eee;" align="center" | |||
| 0x00-0x03 | |||
| Used to connect a small block with a big block | |||
|- style="background: #ddd;" align="center" | |||
| 0x04-0x07 | |||
| Number of the save | |||
|- style="background: #eee;" align="center" | |||
| 0x08-0x0B | |||
| Size of the block | |||
|- style="background: #ddd;" align="center" | |||
| 0x0C-0x0F | |||
| K | |||
|- style="background: #eee;" align="center" | |||
| 0x10-0x11 | |||
| T | |||
|- style="background: #ddd;" align="center" | |||
| 0x12-0x13 | |||
| Checksum of the block | |||
|} | |||
| | The game uses a [[wp:Cyclic redundancy check|CRC-16-CCITT]] algorithm for the checksums. These checksums are calculated from a whole block without taking the footer. | ||
== Example == | |||
SMALL BLOCK 1 | |||
D1 01 00 00 | 42 04 00 00 | 00 C1 00 00 | 23 06 06 20 | 00 00 | 7E 7A | |||
BIG BLOCK 1 | |||
D0 01 00 00 | F1 02 00 00 | E0 21 01 00 | 23 06 06 20 | 01 00 | 0D 39 | |||
BIG BLOCK 2 | SMALL BLOCK 2 | ||
D0 01 00 00 | 41 04 00 00 | 00 C1 00 00 | 23 06 06 20 | 00 00 | 0C 7F | |||
BIG BLOCK 2 | |||
D1 01 00 00 | F2 02 00 00 | E0 21 01 00 | 23 06 06 20 | 01 00 | F6 8A | |||
| | Since the value of {{tt|0x0C0F0 - 0x0C0F3|0x04 - 0x07}} is higher in small block 1 (42 04 00 00 > 41 04 00 00), that is the current small block. Then, by matching the value of {{tt|0x0C0EC - 0x0C0EF|0x00 - 0x03}} (which is D1 01 00 00) to the big block. This means that the current big block is actually big block 2 (assuming the big block's checksum is correct). | ||
{{data structure}} | {{data structure}} |
edits