Nintendo 64 - Nintendo Switch Online: Difference between revisions

No edit summary
No edit summary
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.