Changes

Jump to navigation Jump to search
no edit summary
Line 147: Line 147:     
= SuspendPoint =
 
= SuspendPoint =
The SuspendPoint is stored in a mostly standard cpio archive. The cpio parser code calculates a checksum over each file by XORing each u16 in the file, then comparing it with u16 cpio_entry_header+0x8. The result is stored as a flag in the output cpio file entry structure. This checksum is only set for SuspendPoints, not RomFs data - none of the cpio parser callers currently validate the checksum flag.
+
The SuspendPoint is stored in a mostly standard cpio archive. The magic is little-endian octal 070707. Normally the file data is used raw, however when u8 cpio_entry_header+0x4 (c_ino) is 0x1 and +0x5 is 0x0, the file data is zlib compressed. The cpio parser code calculates a checksum over each file (decompressed data when compression is enabled) by XORing each u16 in the file, then comparing it with u16 cpio_entry_header+0x8 (c_uid). The result is stored as a flag in the output cpio file entry structure. This checksum is only set for SuspendPoints, not RomFs data - none of the cpio parser callers currently validate the checksum flag.
    
This archive is stored in [[#SaveData]], and is also transferred over the network with online-play-friends when the user loads a suspend-point in the GUI. This is also done automatically when a network session is created, for emu-sync-state. Emu-sync-state only used with session-creation, after that the only way to trigger suspend-point usage is via the suspend-menu GUI.
 
This archive is stored in [[#SaveData]], and is also transferred over the network with online-play-friends when the user loads a suspend-point in the GUI. This is also done automatically when a network session is created, for emu-sync-state. Emu-sync-state only used with session-creation, after that the only way to trigger suspend-point usage is via the suspend-menu GUI.
Line 153: Line 153:  
The SuspendPoint loader code loops through the file entries, comparing the entry file extension (following '.' in the filename) with various supported extensions and handling it as needed. No files are mandatory, there are no errors thrown for missing files. The order of the files in the archive doesn't matter either. The saved files have filename ".{extension}". The following extensions are handled:
 
The SuspendPoint loader code loops through the file entries, comparing the entry file extension (following '.' in the filename) with various supported extensions and handling it as needed. No files are mandatory, there are no errors thrown for missing files. The order of the files in the archive doesn't matter either. The saved files have filename ".{extension}". The following extensions are handled:
 
* "json": Contains various emulator state, including CPU/IO registers etc. "g_nN64CpuPC" is used with the g_nN64CpuPC global var. IO regs are copied to/from global state directly, without calling any IO handler funcs.
 
* "json": Contains various emulator state, including CPU/IO registers etc. "g_nN64CpuPC" is used with the g_nN64CpuPC global var. IO regs are copied to/from global state directly, without calling any IO handler funcs.
* "bin": N64 DRAM. While this is zlib compressed, in some cases it's used raw - it's unknown what exactly triggers decompression.
+
* "bin": N64 DRAM. This has the field set for enabling zlib compression in the cpio file entry.
 
* "sav": Savedata image for the emulated game.
 
* "sav": Savedata image for the emulated game.
 
* "imem"
 
* "imem"

Navigation menu