, a SNES emulator.
ZMV file is structured as follows:
| Header|| Fixed size, see below.|
| Beginning savestate|| Always present, but not always used, see below.|
| Stream|| Consists of the key input and chapter data for the movie.|
| Internal chapter index|| This is an array of pointers to all the chapters embedded in the "stream". The length of this array is described in the header.|
| External chapters|| Consists of a number of "external chapters". The length of this array is described next.|
| External chapter count|| Surprise, this field isn't in the header.|
| Author name|| Author name.|
000 3-byte signature: 5A 4D 56 "ZMV"
003 2-byte little-endian unsigned int: zsnes version number
005 4-byte little-endian integer: CRC32 of the ROM
009 4-byte little-endian unsigned int: number of frames
00D 4-byte little-endian unsigned int: number of rerecords
011 4-byte little-endian unsigned int: number of frames removed by rerecord
015 4-byte little-endian unsigned int: number of frames advanced step by step
019 1-byte: average recording frames per second
01A 4-byte little-endian unsigned int: number of key combos
01E 2-byte little-endian unsigned int: number of internal chapters
020 2-byte little-endian unsigned int: length of the author name field in bytes
022 3-byte little-endian unsigned int: size of an uncompressed save state in bytes
025 1-byte: reserved
026 1-byte flags: initial input configuration
bit 7: first input enabled
bit 6: second input enabled
bit 5: third input enabled
bit 4: fourth input enabled
bit 3: fifth input enabled
bit 2: mouse in first port
bit 1: mouse in second port
bit 0: super scope in second port
027 1-byte flags:
if "00", movie begins from savestate
if "10", movie begins from reset
if "01", movie begins from power-on
if "11", movie begins from power-on with SRAM clear
bit 5: if "0", movie is NTSC (60 fps); if "1", movie is PAL (50 fps)
other: reserved, set to 0
028 3-byte little-endian unsigned int: initial save state size, highest bit specifies compression, next 23 specifies size
Next follows a ZST format savestate.
This save state is only loaded if the movie begins from savestate or the version of ZSNES used to make the movie is the different than the one playing it.
On reset or power on without SRAM clear where the version matches, only the SRAM is loaded from the Savestate.
After the optional savestate, comes the actual stream of movie data.
The number of events in the stream is equal to
(number_of_frames + number_of_internal_chapters).
Each event is at least 1 byte long.
The first byte of the event has the following format:
000 1-byte flags:
bit 7: "1" if controller 1 changed, "0" otherwise
bit 6: "1" if controller 2 changed, "0" otherwise
bit 5: "1" if controller 3 changed, "0" otherwise
bit 4: "1" if controller 4 changed, "0" otherwise
bit 3: "1" if controller 5 changed, "0" otherwise
bit 2: "1" if this is a "chapter" update, "0" if it's a "controller" update
bit 1: "1" if this is RLE data instead of any of the above
bit 0: "1" if this is command data instead any of the above
If the event is a command, the other seven bits define the command. The command could be "reset now" or similar things.
If the event is RLE data, next follows 4 bytes which is the frame to repeat current input until (inclusive).
If the event is a "chapter" update, the packet follows with a ZST format savestate. Using a header of:
000 3-byte little endian unsigned int: save state size in format defined above
001 above size: save state
above size+001 4-byte little endian unsigned int: frame number save state loads to
above size+005 2-byte: controller status bit field, see below
above size+007 9-byte: previous controller input bits
If the event is a "controller" update, next comes the controller data
for each changed controller, 12 bits per controller, or 20 bits in the case of the super scope, zeropadding up to full bytes. The minimum length of the controller data is 2 bytes, and the maximum length is 9 bytes. Controller format:
bit 11: A
bit 10: X
bit 9: L
bit 8: R
bit 7: B
bit 6: Y
bit 5: Select
bit 4: Start
bit 3: Up
bit 2: Down
bit 1: Left
bit 0: Right
For example, if this frame contained input for controllers 1 and 2:
bit 7: P1 B
bit 6: P1 Y
bit 5: P1 Select
bit 4: P1 Start
bit 3: P1 Up
bit 2: P1 Down
bit 1: P1 Left
bit 0: P1 Right
bit 7: P2 B
bit 6: P2 Y
bit 5: P2 Select
bit 4: P2 Start
bit 3: P1 A
bit 2: P1 X
bit 1: P1 L
bit 0: P1 R
bit 7: P2 Up
bit 6: P2 Down
bit 5: P2 Left
bit 4: P2 Right
bit 3: P2 A
bit 2: P2 X
bit 1: P2 L
bit 0: P2 R
The number of "controller" update events in the stream should be equal
to the "number of frames" field in the file header.
The number of "chapter" update events in the stream should be equal
to the "number of internal chapters" field in the file header.
Internal chapter index
Position in file: (file_size - author_name_length - 2 - external_chapter_count * (zst_size + 4+2+9+4) - internal_chapter_count*4)
Internal chapters are "chapters" made during the movie recording.
The internal chapter index is an index for quickly finding all the internal
chapters in the movie stream. Finding the internal chapter index is another
Each item in the internal chapter index is 4 bytes long, and follows this format:
000 4-byte little-endian unsigned int: offset of the chapter in the file
The offset is counted from the file beginning (zerobased), and points to the
chapter data in the movie stream (after the flag byte).
Position in file: ( file_size - author_name_length - 2 - external_chapter_count * (zst_size + 4+2+9+4) )
External chapters are "chapters" made during the movie playback.
Each item in the external chapter begins with a savestate,
followed by this table:
000 4-byte little-endian unsigned int: frame number
004 2-byte: bit field of controller status
006 9-byte array: previous input data (1 scope  + 4 regular [12*4] + 4 padded bits)
00F 4-byte little-endian unsigned int: offset to movie stream from beginning of file
The size of an external chapter is therefore (zst_size + 4+2+9+4) bytes.
External chapter count.
Position in file: (file_size - author_name_length - 2)
This is a 2-byte field.
000 2-byte little-endian unsigned int: number of external chapters
Position in file: (file_size - author_name_length)
Last in the file comes the author name field, which is an
string, no zero terminator. The length of this field is described in the header.
The number of characters in this field can be calculated only by iterating it.
(Surprise, the length of this field is in the header, even though
the number of external chapters isn't.)
See also: Emulator resources
, frequently asked questions