zmv is the movie capture format of ZSNES, a SNES emulator.

ZMV file format description

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:
     bits 7,6:
         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

Savestate

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.

Stream

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:
   byte 1:
       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
   byte 2:
       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
   byte 3:
       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 story though...
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).

External chapters

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 [20] + 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

Author name

Position in file: (file_size - author_name_length)
Last in the file comes the author name field, which is an UTF-8 encoded text 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.)


OtherEmulators/ZMV last edited by feos on 7/25/2015 2:19 PM
Page History Latest diff List referrers View Source