Editing Hey! Pikmin save file
Jump to navigation
Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 3: | Line 3: | ||
== Format == | == Format == | ||
− | The save data is split into several blocks that start with 4-byte magic words | + | The save data is split into several blocks that start with 4-byte magic words. |
=== SAVE === | === SAVE === | ||
Line 11: | Line 11: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0000</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>SAVE</code>. |
|- | |- | ||
− | | <code> | + | | <code>000C</code> || <code>000C</code> || 4 bytes || Save data checksum || {{unsure|Calculated using an unknown algorithm.}} |
|} | |} | ||
=== NEWS === | === NEWS === | ||
− | |||
{| class="wikitable sortable" | {| class="wikitable sortable" | ||
! colspan="2" | Offset || rowspan="2" | Length || rowspan="2" | Field || rowspan="2" | Notes | ! colspan="2" | Offset || rowspan="2" | Length || rowspan="2" | Field || rowspan="2" | Notes | ||
Line 23: | Line 22: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0010</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>NEWS</code>. |
|- | |- | ||
− | |||
− | |||
− | |||
− | |||
− | |||
|} | |} | ||
=== OPTI === | === OPTI === | ||
− | |||
{| class="wikitable sortable" | {| class="wikitable sortable" | ||
! colspan="2" | Offset || rowspan="2" | Length || rowspan="2" | Field || rowspan="2" | Notes | ! colspan="2" | Offset || rowspan="2" | Length || rowspan="2" | Field || rowspan="2" | Notes | ||
Line 39: | Line 32: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0020</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>OPTI</code>. |
− | |||
− | |||
− | |||
− | |||
|- | |- | ||
− | | <code> | + | | <code>0028</code> || <code>0008</code> || 1 byte || Music volume || <code>01</code>, <code>02</code>, or <code>03</code>. |
|- | |- | ||
− | |||
|} | |} | ||
=== PBUF === | === PBUF === | ||
− | |||
{| class="wikitable sortable" | {| class="wikitable sortable" | ||
! colspan="2" | Offset || rowspan="2" | Length || rowspan="2" | Field || rowspan="2" | Notes | ! colspan="2" | Offset || rowspan="2" | Length || rowspan="2" | Field || rowspan="2" | Notes | ||
Line 57: | Line 44: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>002C</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>PBUF</code>. |
|- | |- | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
|} | |} | ||
Line 74: | Line 54: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0080</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>PARK</code>. |
|- | |- | ||
|} | |} | ||
Line 84: | Line 64: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>04A4</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>MINI</code>. |
|- | |- | ||
|} | |} | ||
Line 94: | Line 74: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0588</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>CRNT</code>. |
|- | |- | ||
|} | |} | ||
Line 104: | Line 84: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>09A8</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>GAME</code>. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
|- | |- | ||
|} | |} | ||
Line 120: | Line 94: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>09E0</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>EVNT</code>. |
|- | |- | ||
|} | |} | ||
Line 130: | Line 104: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0AE8</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>HELP</code>. |
|- | |- | ||
|} | |} | ||
Line 140: | Line 114: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0BF0</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>RINF</code>. |
|- | |- | ||
|} | |} | ||
Line 150: | Line 124: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0C2C</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>RSLT</code>. |
|- | |- | ||
|} | |} | ||
Line 160: | Line 134: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0C38</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>SPER</code>. |
|- | |- | ||
|} | |} | ||
Line 170: | Line 144: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0C48</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>STRE</code>. |
|- | |- | ||
|} | |} | ||
Line 180: | Line 154: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0C90</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>PLRP</code>. |
|- | |- | ||
|} | |} | ||
=== DATE === | === DATE === | ||
− | |||
− | |||
{| class="wikitable sortable" | {| class="wikitable sortable" | ||
! colspan="2" | Offset || rowspan="2" | Length || rowspan="2" | Field || rowspan="2" | Notes | ! colspan="2" | Offset || rowspan="2" | Length || rowspan="2" | Field || rowspan="2" | Notes | ||
Line 192: | Line 164: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0CE0</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>DATE</code>. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
|- | |- | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
|} | |} | ||
Line 217: | Line 174: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0CFC</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>TTDS</code>. |
|- | |- | ||
|} | |} | ||
Line 227: | Line 184: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0D08</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>WMAP</code>. |
|- | |- | ||
|} | |} | ||
Line 237: | Line 194: | ||
! File || Block | ! File || Block | ||
|- | |- | ||
− | | <code> | + | | <code>0D80</code> || <code>0000</code> || 4 bytes || Block magic word || Always <code>SAMI</code>. |
|- | |- | ||
|} | |} | ||
== Checksum == | == Checksum == | ||
− | The checksum seems to be a CRC32 of the | + | The checksum seems to be a CRC32 of the 0xd87 bytes that follow after the checksum (i.e. just one byte short of the entire remaining data), with crc32 as implemented by e.g. zlib. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | == | + | The following python code can recalculate the checksum if the data after the checksum is modified: |
− | + | import struct | |
+ | from zlib import crc32 | ||
+ | |||
+ | filepath = "radish0.sav" # put the script in the same folder as the save file | ||
+ | with open(filepath, "rb") as f: | ||
+ | header = f.read(0xC) | ||
+ | chksum = struct.unpack("I", f.read(4))[0] | ||
+ | |||
+ | data = f.read() | ||
+ | |||
+ | calculated_chksum = crc32(data[0:0xd87]) | ||
+ | with open(filepath, "wb") as f: | ||
+ | f.write(header) | ||
+ | f.write(struct.pack("I", calculated_chksum)) | ||
+ | f.write(data) | ||
[[Category:File formats]] | [[Category:File formats]] | ||
[[Category:Hey! Pikmin]] | [[Category:Hey! Pikmin]] |