Difference between revisions of "Hey! Pikmin save file"

From Pikmin Technical Knowledge Base
Jump to navigation Jump to search
Line 17: Line 17:
  
 
=== NEWS ===
 
=== NEWS ===
 +
What "news" the player has seen. "News" are the cutscenes that take place inside the S.S. Dolphin II, where the ship explains something to Olimar.
 
{| 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 24: Line 25:
 
| <code>0x0010</code> || <code>0x0000</code> || 4 bytes || Block magic word || Always <code>NEWS</code>.
 
| <code>0x0010</code> || <code>0x0000</code> || 4 bytes || Block magic word || Always <code>NEWS</code>.
 
|-
 
|-
 +
| <code>0x0014</code> || <code>0x0004</code> || 4 bytes || Unknown ||
 +
|-
 +
| <code>0x0018</code> || <code>0x0008</code> || 4 bytes || Unknown news controller 1 || 0 when the player hasn't heard the news about 1-A yet, 1 when they have.
 +
|-
 +
| <code>0x001C</code> || <code>0x000C</code> || 4 bytes || Unknown news controller 2 || 0 when the player hasn't heard the news about 1-A yet, 8 when they have.
 
|}
 
|}
  

Revision as of 23:09, 30 December 2017

This article is a stub.

The file format for a Hey! Pikmin saved game. Note: this comes from analyses of the .sav files generated by Citra.

Format

The save data is split into several blocks that start with 4-byte magic words.

SAVE

Offset Length Field Notes
File Block
0x0000 0x0000 4 bytes Block magic word Always SAVE.
0x000C 0x000C 4 bytes Save data checksum Calculated using this method.

NEWS

What "news" the player has seen. "News" are the cutscenes that take place inside the S.S. Dolphin II, where the ship explains something to Olimar.

Offset Length Field Notes
File Block
0x0010 0x0000 4 bytes Block magic word Always NEWS.
0x0014 0x0004 4 bytes Unknown
0x0018 0x0008 4 bytes Unknown news controller 1 0 when the player hasn't heard the news about 1-A yet, 1 when they have.
0x001C 0x000C 4 bytes Unknown news controller 2 0 when the player hasn't heard the news about 1-A yet, 8 when they have.

OPTI

The player's preferences in the options menu.

Offset Length Field Notes
File Block
0x0020 0x0000 4 bytes Block magic word Always OPTI.
0x0024 0x0004 4 bytes Unknown[unsure]
0x0028 0x0008 1 byte Music volume 0 to 3.
0x0029 0x0009 1 byte Sound effects volume 0 to 3.
0x002A 0x000A 2 bytes Unknown[unsure]

PBUF

Offset Length Field Notes
File Block
0x002C 0x0000 4 bytes Block magic word Always PBUF.

PARK

Offset Length Field Notes
File Block
0x0080 0x0000 4 bytes Block magic word Always PARK.

MINI

Offset Length Field Notes
File Block
0x04A4 0x0000 4 bytes Block magic word Always MINI.

CRNT

Offset Length Field Notes
File Block
0x0588 0x0000 4 bytes Block magic word Always CRNT.

GAME

Offset Length Field Notes
File Block
0x09A8 0x0000 4 bytes Block magic word Always GAME.
0x09AC 0x0004 4 bytes Unknown[unsure]
0x09B0 0x0008 4 bytes Sparklium total Values over 99999 will make the game assume it's just 99999
0x09B4 0x000C 44 bytes Unknown[unsure]

EVNT

Offset Length Field Notes
File Block
0x09E0 0x0000 4 bytes Block magic word Always EVNT.

HELP

Offset Length Field Notes
File Block
0x0AE8 0x0000 4 bytes Block magic word Always HELP.

RINF

Offset Length Field Notes
File Block
0x0BF0 0x0000 4 bytes Block magic word Always 0xRINF.

RSLT

Offset Length Field Notes
File Block
0x0C2C 0x0000 4 bytes Block magic word Always RSLT.

SPER

Offset Length Field Notes
File Block
0x0C38 0x0000 4 bytes Block magic word Always SPER.

STRE

Offset Length Field Notes
File Block
0x0C48 0x0000 4 bytes Block magic word Always STRE.

PLRP

Offset Length Field Notes
File Block
0x0C90 0x0000 4 bytes Block magic word Always PLRP.

DATE

Time at which the save was made.

Offset Length Field Notes
File Block
0x0CE0 0x0000 4 bytes Block magic word Always DATE.
0x0CE4 0x0004 8 bytes Unknown[unsure]
0x0CEC 0x000C 1 byte Month 1 to 12.
0x0CED 0x000D 1 byte Day 1 to 31.
0x0CEE 0x000E 1 byte Hours 0 to 23.
0x0CEF 0x000F 1 byte Minutes 0 to 59.
0x0CF0 0x0010 1 byte Seconds 0 to 59.
0x0CF1 0x0011 11 bytes Unknown[unsure]

TTDS

Offset Length Field Notes
File Block
0x0CFC 0x0000 4 bytes Block magic word Always TTDS.

WMAP

Offset Length Field Notes
File Block
0x0D08 0x0000 4 bytes Block magic word Always WMAP.

SAMI

Offset Length Field Notes
File Block
0x0D80 0x0000 4 bytes Block magic word Always SAMI.

Checksum

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)

Tools