Table of contents
- Text format
- Overall file structure
- Savestate / SRAM / clean detection
- Members
- gametype
- port<n> (<n> is a number)
- setting.<name>
- gamename
- authors
- systemid
- controlsversion
- coreversion
- projectid
- <slot>.sha256
- moviesram.<name>
- saveframe
- lagcounter
- pollcounters
- hostmemory
- ramcontent.<name>
- savestate
- savestate.anchor
- screenshot
- sram.<name>
- rerecords:
- rrdata
- starttime.second
- starttime.subsecond
- savetime.second
- savetime.subsecond
- input
- subtitles
- Binary format
- Types:
- Overall file structure:
- Blocks
- Block type 0xf5e0fad7: ANCHOR_SAVE:
- Block type 0xafff97b4: AUTHOR
- Block type 0xe4344c7e: CORE_VERSION
- Block type 0xe80d6970: GAMENAME
- Block type 0x3bf9d187: HOSTMEMORY
- Block type 0xd261338f: MACRO
- Block type 0xf3dca44b: MOVIE
- Block type 0xbbc824b7: MOVIE_SRAM
- Block type 0x18c3a975: MOVIE_TIME
- Block type 0x359bfbab: PROJECT_ID
- Block type 0xd3ec3770: RAMCONTENT
- Block type 0x0428acfc: ROMHASH
- Block type 0xa3a07f71: RRDATA
- Block type 0xae9bfb2f: SAVE_SRAM
- Block type 0x2e5bc2ac: SAVESTATE
- Block type 0xc6760d0e: SCREENSHOT
- Block type 0x6a7054d3: SUBTITLE
Text format
Overall file structure
The movie / savestate files are .zip archives with the following restictions
- Members must be each be uncompressed or compressed using deflate.
- Encryption must not be used.
- No patching or any other exotic stuff.
Savestate / SRAM / clean detection
- If file named "savestate" is present, it is a savestate, otherwise
- If file named "savestate.anchor" is present, it starts from savestate, otherwise
- If file with name starting with "moviesram." is present, it starts from SRAM, otherwise
- It starts from clean state
Members
The various standard members of the savestate.
gametype
Type: One line
If misisng: Load error
Gives the type of system and region.
If misisng: Load error
Gives the type of system and region.
- snes_ntsc: NTSC SNES
- snes_pal: PAL SNES
- bsx: BS-X, non-slotted cartridge (always NTSC)
- bsxslotted: BS-X slotted cartridge (always NTSC)
- sufamiturbo: Sufami Turbo (always NTSC)
- sgb_ntsc: NTSC SGB
- sgb_pal: PAL SGB
- gdmg: Game Boy
- ggbc: Game Boy Color
- ggbca: Game Boy Color (GBA initial reg. values)
PAL framerate: 322445/6448 fps.
NTSC framerate: 10738636/178683 fps.
Game Boy framerate: 262144/4389 fps.
NTSC framerate: 10738636/178683 fps.
Game Boy framerate: 262144/4389 fps.
port<n> (<n> is a number)
Type: One line
If misisng: Set to default
Gives the type of port <n> (1-based).
If misisng: Set to default
Gives the type of port <n> (1-based).
- none: No controller present
- gamepad: Standard Gamepad
- multitap: Multitap (4 gamepads). Note: Causes most games to not work or crash.
- mouse: Mouse
- superscope: Super Scope
- justifier: 1 justifier
- justifiers: 2 justifiers
Valid values depend on core type.
setting.<name>
Type: One line
If missing: Sett to default
Gives value of a setting. Valid values depend on core type.
If missing: Sett to default
Gives value of a setting. Valid values depend on core type.
gamename
Type: One line
If missing: Game name will be blank.
Name of the game. Purely for comment purposes
If missing: Game name will be blank.
Name of the game. Purely for comment purposes
authors
Type: Textual
If missing: Authors list will be blank.
Authors of the run, one per line. The part before '|' (if any) is real name, the part after is nickname.
If missing: Authors list will be blank.
Authors of the run, one per line. The part before '|' (if any) is real name, the part after is nickname.
systemid
Type: One line
If missing: Load error
Must contain 'lsnes-rr1' (note: Even with rr0 and rr2 versions).
If missing: Load error
Must contain 'lsnes-rr1' (note: Even with rr0 and rr2 versions).
controlsversion
Type: One line, mandatory
If missing: Load error
Must contain '0'.
If missing: Load error
Must contain '0'.
coreversion
Type: One line, mandatory
If missing: Load error
Bsnes core version string. Mismatch is error on loading savestate, warning on loading movie.
If missing: Load error
Bsnes core version string. Mismatch is error on loading savestate, warning on loading movie.
projectid
Type: One line
If missing: Load error
Hexadecimal movie identifier. Used for recognizing movies.
If missing: Load error
Hexadecimal movie identifier. Used for recognizing movies.
<slot>.sha256
Type one line
If missing: Corresponding ROM is assumed absent
SHA-256 hashes of ROM images. The <slot> may be either 'rom', 'romxml', 'slota'...'slotz' or 'slotaxml'...'slotzxml'.
If missing: Corresponding ROM is assumed absent
SHA-256 hashes of ROM images. The <slot> may be either 'rom', 'romxml', 'slota'...'slotz' or 'slotaxml'...'slotzxml'.
The 'xml' slots are markup, and can be present only if corresponding non-'xml' slot is.
Valid slots vary depending on the system:
- SNES/GB/GBC: rom
- BS-X/SGB: rom, slota
- Sufami Turbo: rom, slota, slotb.
Hash failure is error on loading savestate, warning on loading movie.
moviesram.<name>
Type: Raw binary
If absent: Start with said SRAM clean.
Contains initial contents of given SRAM.
If absent: Start with said SRAM clean.
Contains initial contents of given SRAM.
As of bsnes v085, the following are used:
- moviesram.bss: SRAM on BS-X cartridge
- moviesram.bsp: PSRAM on BS-X cartridge
- moviesram.rtc: State of RTC on cartridge
- moviesram.nec: State of DSP ram on cartridge (if non-volatile)
- moviesram.slota.sts: State of Sufami Turbo slot A SRAM.
- moviesram.slotb.sts: State of Sufami Turbo slot B SRAM.
- moviesram.srm: SNES cartridge SRAM.
Gambatte uses the following:
- moviesram.main: Main SRAM.
- moviesram.rtc: RTC.
The cartridge may have only some of possible SRAMs or even none.
saveframe
Type: One line
If absent: Error if savestate, otherwise ignored
Contains the number of frame game was saved on. Ignored if not loading savestate.
If absent: Error if savestate, otherwise ignored
Contains the number of frame game was saved on. Ignored if not loading savestate.
lagcounter
Type: One line
If absent: Error if savestate, otherwise ignored
Contains the number of lag frames that have occured so far. Ignored if not loading savestate.
If absent: Error if savestate, otherwise ignored
Contains the number of lag frames that have occured so far. Ignored if not loading savestate.
pollcounters
Type: Text
If absent: Error if savestate, otherwise ignored
Contains the poll counters and data ready flags of (currently 100) controls.
If absent: Error if savestate, otherwise ignored
Contains the poll counters and data ready flags of (currently 100) controls.
hostmemory
Type: Raw binary
If absent: Resume with hostmemory clean
Contains the Lua host memory. Ignored if not loading savestate.
If absent: Resume with hostmemory clean
Contains the Lua host memory. Ignored if not loading savestate.
ramcontent.<name>
Type: Raw binary
If absent: Fill with defaults
Contains initial content of RAM memory block <name>.
If absent: Fill with defaults
Contains initial content of RAM memory block <name>.
savestate
Type: Raw binary
If absent: Load as movie
Contains the bsnes core savestate.
If absent: Load as movie
Contains the bsnes core savestate.
The last 32 bytes are SHA-256 checksum of everything previous (the actual core savestate).
savestate.anchor
Type: Raw binary
If absent: Start from clean state or SRAM
Contains the bsnes core savestate for initial state.
If absent: Start from clean state or SRAM
Contains the bsnes core savestate for initial state.
The last 32 bytes are SHA-256 checksum of everything previous (the actual core savestate).
screenshot
Type: Raw binary
If absent: Load error
Contains screenshot of current screen.
If absent: Load error
Contains screenshot of current screen.
sram.<name>
Type: Raw binary
If absent: Ignored
Contains the contents of SRAM at the time of savestate. Ignored when loading.
If absent: Ignored
Contains the contents of SRAM at the time of savestate. Ignored when loading.
rerecords:
Type: One line
If absent: Ignored
Contains the rerecord count. Ignored when loading.
If absent: Ignored
Contains the rerecord count. Ignored when loading.
rrdata
Type: Raw binary
If absent: Load error
Contains the data related to tracking rerecords. The rerecord count is computed from this.
If absent: Load error
Contains the data related to tracking rerecords. The rerecord count is computed from this.
The data compresses a set of IDs, each 32 bytes in length. Those are compressed into sequence of records (concatenated), each encoding starting ID and number of consequtive IDs (big-endian integers modulo 2^256 where next is increment by 1).
Each record consists of three parts:
- Opcode byte
- * Bits 0-4: The number of initial bytes omitted from the ID.
- * Bits 5-6: Number of bytes in sequence length.
- * Bit 7: Unused.
- First ID in sequence
- * The omitted bytes are taken from "next ID" field.
- Sequence length
- * If 0 bytes, the sequence length is 1.
- * If 1 byte, the sequence length minus 2.
- * If 2 bytes, big endian sequence length minus 258.
- * If 3 bytes, big endian sequence length minus 65794.
If more than 16,843,009 consequtive IDs are needed, multiple records are used to encode that.
After each record, the next ID field is set to the ID that comes after the last ID actually added. This field starts as all zeroes.
starttime.second
Type: One line
If absent: Default to 1,000,000,000.
Contains the RTC starting time second part (since Unix epoch).
If absent: Default to 1,000,000,000.
Contains the RTC starting time second part (since Unix epoch).
starttime.subsecond
Type: One line
If absent: Default to 0.
Contains the RTC starting time subsecond part (in units of SMP cycles).
If absent: Default to 0.
Contains the RTC starting time subsecond part (in units of SMP cycles).
savetime.second
Type: One line
If absent: Default to 1,000,000,000.
Contains the RTC current time second part (since Unix epoch).
If absent: Default to 1,000,000,000.
Contains the RTC current time second part (since Unix epoch).
savetime.subsecond
Type: One line
If absent: Default to 0.
Contains the RTC current time subsecond part (in units of SMP cycles).
If absent: Default to 0.
Contains the RTC current time subsecond part (in units of SMP cycles).
input
Type: Textual
If absent: Load error
Contains the input, one subframe per line.
If absent: Load error
Contains the input, one subframe per line.
If line starts with <tab>, <CR>, <LF>, space, '.' or '|', it is part of previous frame, otherwise it starts a new frame (the first non-empty line must start a new frame).
Format:
F.|BYsSudlrAXLR
Where udlr are the directional buttons and LR are their respective buttons. If F is replaced with a '.' or whitespace, then this is a subframe instead of a frame. If the second character is not a '.' or whitespace, then this frame contains a reset. Certain resets are delayed resets, which have the following format:
FR X Y|BYsSudlrAXLR
Where 10000 * X + Y = the number of instructions to wait before resetting. When using LSMV's Gameboy (Gambatte) core, the format of a frame is as follows:
F.|ABsSrlud
subtitles
Type: Textual
If absent: Assume empty
Contains subtitles, one per line in format <firstframe> <length> <text>
If absent: Assume empty
Contains subtitles, one per line in format <firstframe> <length> <text>
Backslash is written as \\, linefeed is written as \n
Binary format
Types:
- Byte: 1 byte unsigned number.
- 32-bit: 4 byte unsigned big-endian number.
- varint: Variable-length number, all but the last byte have bit 7 set, last 7 bits of each byte form the number in little endian order.
- string: Varint containing number of bytes in string, followed by UTF-8 value of that length.
- implicit-string: UTF-8 string taking remainder of block (these can only be inside blocks).
- implicit-blob: Binary data taking the remainder of block (these can only be inside blocks).
Overall file structure:
In order:
- Opaque: "lsmv" 0x1A
- string: Sysregion code (see gametype).
- Zero or more settings, for each:
- * Byte: 1
- * string: Name of setting.
- * string: Value of setting.
- Byte: 0
- Zero or more blocks, for each:
- * 32-bit: 0xaddb2d86
- * 32-bit: Block type.
- * Varint: Block payload length.
- * Opaque: Specified number of bytes making block payload.
Blocks
Block type 0xf5e0fad7: ANCHOR_SAVE:
- implicit-blob: The savestate (last 32 bytes are SHA-256 checksum of previous).
Block type 0xafff97b4: AUTHOR
- string: Real name
- implicit-string: Nickname
Block type 0xe4344c7e: CORE_VERSION
- implicit-string: Core version string.
Block type 0xe80d6970: GAMENAME
- implicit-string: Game name.
Block type 0x3bf9d187: HOSTMEMORY
- implicit-blob: Lua Host memory contents.
Block type 0xd261338f: MACRO
- varint: Frame number in macro
- implicit-string: Macro name.
Block type 0xf3dca44b: MOVIE
- implicit-blob: Raw binary movie data
The frames are concatenated. Length of each frame and precise format depends on the core and settings.
Block type 0xbbc824b7: MOVIE_SRAM
- string: Name of SRAM.
- implicit-blob: Initial contents for the SRAM.
Block type 0x18c3a975: MOVIE_TIME
- varint: Seconds part of movie starting time.
- varint: Subseconds part of movie starting time.
Block type 0x359bfbab: PROJECT_ID
- implicit-string: Project ID.
Block type 0xd3ec3770: RAMCONTENT
- string: Name of memory area.
- implicit-blob: Initial contents of that memory area.
Block type 0x0428acfc: ROMHASH
- byte: Number of slot
- * High 7 bits are slot number 0...26
- * Low bit is 0 for ROM slots, 1 for markup slots.
- implicit-string: Hash value
Block type 0xa3a07f71: RRDATA
- implicit-blob: rrdata (see the textual file format).
Block type 0xae9bfb2f: SAVE_SRAM
- string: Name of SRAM.
- implicit-blob: contents for the SRAM at time of savestate.
Block type 0x2e5bc2ac: SAVESTATE
- Varint: Save frame
- Varint: Lag counter
- Varint: Current RTC second.
- Varint: Current RTC subsecond.
- 32-bit*n: Poll counters (Bit 31 is data ready bit). Number depends on the settings/core.
- Byte: Polled this frame flag.
- implicit-blob: Contents of the savestate.
Block type 0xc6760d0e: SCREENSHOT
- implicit-blob: Screen contents.
Block type 0x6a7054d3: SUBTITLE
- Varint: Starting frame
- Varint: Duration
- Implicit-string: Text (without escaping)