Line 147: |
Line 147: |
| | | |
| = SuspendPoint = | | = SuspendPoint = |
− | 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. | + | The SuspendPoint is stored in a mostly standard cpio archive with a modified cpio entry header: |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Offset |
| + | ! Size |
| + | ! Description |
| + | |- |
| + | | 0x0 || 0x2 || Magic (070707 in little-endian octal) |
| + | |- |
| + | | 0x2 || 0x2 || Dev (0x3E16 or 0x0000 if trailer block) |
| + | |- |
| + | | 0x4 || 0x2 || Flags (0x1 means file data is zlib compressed) |
| + | |- |
| + | | 0x6 || 0x2 || Mode (unused) |
| + | |- |
| + | | 0x8 || 0x2 || Checksum |
| + | |- |
| + | | 0xA || 0x2 || DecompFileSize1 (lower half of decompressed file size) |
| + | |- |
| + | | 0xC || 0x2 || DecompFileSize2 (higher half of decompressed file size) |
| + | |- |
| + | | 0xE || 0x2 || Rdev (unused) |
| + | |- |
| + | | 0x10 || 0x2 || Mtime1 (unused) |
| + | |- |
| + | | 0x12 || 0x2 || Mtime2 (unused) |
| + | |- |
| + | | 0x14 || 0x2 || NameSize (size of file name) |
| + | |- |
| + | | 0x16 || 0x2 || FileSize1 (lower half of file size) |
| + | |- |
| + | | 0x18 || 0x2 || FileSize2 (higher half of file size) |
| + | |- |
| + | | 0x1A || NameSize || FileName |
| + | |- |
| + | | 0x1A + NameSize || FileSize || FileData |
| + | |} |
| + | |
| + | Normally the file data is used raw, but it can also be zlib compressed if '''flags''' is 0x1. 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 '''checksum'''. 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. |