VBM is the movie capture format of Visual Boy Advance
VBM file format description
|000||4-byte signature||56 42 4D 1A "VBM\x1A"|
|004||4-byte little-endian unsigned int||major 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|
|bit 1||if "1", movie starts from reset with an embedded SRAM|
|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)|
|016||1-byte flags||system flags (game always runs at 60 frames/sec)|
|bit 0||if "1", movie is for the GBA system|
|bit 1||if "1", movie is for the GBC system|
|bit 2||if "1", movie is for the SGB system|
|If all 3 of these bits are "0", it is for regular GB.|
|At most one of bits 0, 1, 2 can be "1"|
|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.|
|bit 1: skipBiosFile||if "0" and the movie was made with a GBA BIOS file, the BIOS intro is included in the movie.|
|bit 2: rtcEnable||if "1", the emulator "real time clock" feature was enabled.|
|bit 3: gbInputHack||if "1" and the movie is of a GB, GBC, or SGB game, the movie was made with the Null Input Kludge on, otherwise it was not.|
|bit 4: lagReduction||if "0" and the movie is of a GBA game, the movie was made using the old excessively laggy GBA timing.|
|bit 5: gbcHdma5Fix||if "0" and the movie is of a GBC game, the movie was made using the old buggy HDMA5 timing.|
|bit 6: echoRAMFix||if "1" and the movie is of a GB, GBC, or SGB game, the movie was made with Echo RAM Fix on, otherwise it was made with Echo RAM Fix off.|
|bit 7: sramInitFix||if "1" and the movie is of a GBA game, the movie was made with SRAM Init Fix on, otherwise it was not.|
|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 unsigned char||minor version/revision number of current VBM version, the latest is "1"|
|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.
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).
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:
01 00 A 02 00 B 04 00 Select 08 00 Start 10 00 Right 20 00 Left 40 00 Up 80 00 Down 00 01 R 00 02 L 00 04 Reset (old timing, only for backward-compatibility purpose) 00 08 Reset (new timing since version 1.1) 00 10 Left motion sensor (deprecated as never implemented) 00 20 Right motion sensor (deprecated as never implemented) 00 40 Down motion sensor (deprecated as never implemented) 00 80 Up motion sensor (deprecated as never implemented)