VBM

vbm is the movie capture format of Visual Boy Advance, a Game Boy / Super Game Boy / Game Boy Color / Game Boy Advance emulator.

VBM file format description

VBM file consists of a 64-byte header and various blocks that depend on settings.

Header format:

    000 4-byte signature: 56 42 4D 1A "VBM\x1A"
    004 4-byte little-endian unsigned int: version number, must be 1
    008 4-byte little-endian integer: movie "uid" - identifies the movie-savestate relationship,
               also used as the recording time in Unix epoch format
    00C 4-byte little-endian unsigned int: number of frames
    010 4-byte little-endian unsigned int: rerecord count
    014 1-byte flags (movie start flags):
       bit 0: if "1", movie starts from an embedded "quicksave" snapshot; if "0", it doesn't
       bit 1: if "1", movie starts from reset with an embedded SRAM; if "0", it doesn't
        (NOTE: if both bits 0 and 1 are "0", then movie begins from power on with no SRAM or save state.
              if both bits 0 and 1 are "1", the movie file is invalid.)
       other: reserved, set to 0
    015 1-byte flags (controller flags):
       bit 0: controller 1 in use
       bit 1: controller 2 in use (SGB games can be 2-player multiplayer)
       bit 2: controller 3 in use (SGB games can be 3- or 4-player multiplayer with multitap)
       bit 3: controller 4 in use (SGB games can be 3- or 4-player multiplayer with multitap)
       other: reserved
    016 1-byte flags:  (system flags - note that no matter what these are, the game always runs at 60 frames/sec)
       bit 0: if "1", movie is for the GBA system; if "0", it isn't.
       bit 1: if "1", movie is for the GBC system; if "0", it isn't.
       bit 2: if "1", movie is for the SGB system; if "0", it isn't. (If all 3 of these bits are "0", it's for regular GB.)
         (NOTE:  The above 3 bits are mutually exclusive, although a given ROM can be playable on multiple systems.)
       other: reserved, set to 0
    017 1-byte flags:  (values of some boolean emulator options)
       bit 0: (useBiosFile)
         if "1" and the movie is of a GBA game, the movie was made using a GBA BIOS file, otherwise it wasn't.
       bit 1: (skipBiosFile)
         if "0" and the movie was made with a GBA BIOS file, the BIOS intro is included in the movie, otherwise it isn't.
       bit 2: (rtcEnable)
         if "1", the emulator's "real time clock" feature was enabled; if "0", it wasn't.
       bit 3: (unsupported)
         must be "0" or the movie file is considered invalid (legacy)
       bit 4: (lagReduction)
         if "0" and the movie is of a GBA game, the movie was made using the old excessively laggy GBA timing, otherwise it wasn't.
       bit 5: (gbcHdma5Fix)
         if "0" and the movie is of a GBC game, the movie was made using the old buggy HDMA5 timing, otherwise it wasn't.
       other: reserved, set to 0
    018 4-byte little-endian unsigned int: theApp.winSaveType (value of that emulator option)
    01C 4-byte little-endian unsigned int: theApp.winFlashSize (value of that emulator option)
    020 4-byte little-endian unsigned int: gbEmulatorType (value of that emulator option)
    024 12-byte character array: the internal game title of the ROM
      used while recording, not necessarily null-terminated (ASCII?)
    030 1-byte: reserved, set to 0
    031 1-byte unsigned char: the internal CRC of the ROM used while recording
    032 2-byte little-endian unsigned short: the internal Checksum of the ROM used
       while recording, or a calculated CRC16 of the BIOS if GBA
    034 4-byte little-endian unsigned int: the Game Code of the ROM used
       while recording, or the Unit Code if not GBA
    038 4-byte little-endian unsigned int: offset to the savestate
       or SRAM inside file, set to 0 if unused
    03C 4-byte little-endian unsigned int: offset to the controller data inside file

Info (192 bytes)

After the header is 192 bytes of text.
The first 64 of these 192 bytes are for the author's name (or names).
The following 128 bytes are for a description of the movie.
Both parts must be null-terminated.

Bisqwit: Due to particularly bad design of the file format, the character encoding used in these strings is locale-dependent. That is, it might be Windows-1252 if the player was central-European, Windows-1251 if the player was Russian, Shift_JIS if the player was Japanese, or anything else. Which makes it impossible to reliably read what text is stored there. If the person replaying the movie has different locale than the person who made the movie, the non-English letters of the text most certainly appear as garbage.

Start Data

Located somewhere after the Info, as determined by the 4-byte save offset value at 0x038 in the Header.

It MUST be BEFORE the controller data, however, and obviously must not overlap the controller data.

Can be either a save-state snapshot or SRAM, as determined by the flags at byte 0x014 in the header.

Also has the possibility of not existing at all, which is the same as containing all-cleared SRAM (except it's not stored in the movie).

Controller Data

Located somewhere after the Info, as determined by the 4-byte controller offset value at 0x03C in the Header.

(If there is no "Start Data", this will probably begin at byte 0x100 in the file, but this is not guaranteed.)

A stream of 2-byte bitvectors which indicate which buttons are pressed at each point in time.

They will come in groups of however many controllers are active, in increasing order. Each value is determined by OR-ing together values for whichever of the following are pressed:

  0x0001 A
  0x0002 B
  0x0004 Select
  0x0008 Start
  0x0010 Right
  0x0020 Left
  0x0040 Up
  0x0080 Down
  0x0100 R
  0x0200 L
  0x0400 Reset
  0x0800 (unused/reserved)
  0x1000 Left motion sensor
  0x2000 Right motion sensor
  0x4000 Down motion sensor
  0x8000 Up motion sensor

See also: emulator homepages, frequently asked questions

Get Firefox!VBM last edited by P.JBoy on 2007-08-19 00:53:51
Page info and history | Latest diff | List referrers