m64 is the movie capture format of Mupen64.
M64 files consist of a 1024-byte header with various blocks that depend on settings, followed by some input data.
Header format
000 4-byte signature: 4D 36 34 1A "M64\x1A" 004 4-byte little-endian unsigned int: version number, should be 3 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 (vertical interrupts) 010 4-byte little-endian unsigned int: rerecord count 014 1-byte unsigned int: frames (vertical interrupts) per second 015 1-byte unsigned int: number of controllers 016[1] 1-byte unsigned int: extended version number (movies created with mupen <1.1.9 have this set to 0, as this used to be a reserved value) 017[1] 1-byte unsigned int: extended flags, only valid if the extended version number is non-0. bit 1: whether the movie was recorded with the WiiVC emulation mode (valid on following version numbers: 1) rest: reserved 018 4-byte little-endian unsigned int: number of input samples for any controllers 01C 2-byte unsigned int: movie start type value 1: movie begins from snapshot (the snapshot will be loaded from an externalfile with the movie filename and a .st extension) value 2: movie begins from power-on value 4: movie begins from eeprom other values: invalid movie 01E 2-byte unsigned int: reserved, should be 0 020 4-byte unsigned int: controller flags bit 0: controller 1 present bit 4: controller 1 has mempak bit 8: controller 1 has rumblepak +1..3 for controllers 2..4. 024[1] 32-byte struct: extended data, only valid if the extended version number is non-0. 4-byte unsigned int: special authorship information, such as the program which created the movie. movies authored with mupen have this set to 0x4D55504E ("MUPN") (valid on following version numbers: 1) 4-byte unsigned int: additional data regarding bruteforcing (valid on following version numbers: 1) 4-byte unsigned int: high word of the rerecord count (valid on following version numbers: 1) rest: reserved 044[1] 128 bytes: reserved, should be 0 0C4 32-byte ASCII string: internal name of ROM used when recording, directly from ROM 0E4 4-byte unsigned int: CRC32 of ROM used when recording, directly from ROM 0E8 2-byte unsigned int: country code of ROM used when recording, directly from ROM 0EA 56 bytes: reserved, should be 0 122 64-byte ASCII string: name of video plugin used when recording, directly from plugin 162 64-byte ASCII string: name of sound plugin used when recording, directly from plugin 1A2 64-byte ASCII string: name of input plugin used when recording, directly from plugin 1E2 64-byte ASCII string: name of rsp plugin used when recording, directly from plugin 222 222-byte UTF-8 string: author name info 300 256-byte UTF-8 string: author movie description info
Controller Data
After the header, starting at byte 0x400 in the file, comes the input data. (NOTE: If the version number at 0x004 is 1 or 2, then the input data starts at byte 0x200 instead.) The input data is a stream of 4-byte bitvectors which indicate which buttons and/or analog directions are pressed at each point in time.
typedef union {
DWORD Value;
struct {
unsigned R_DPAD : 1;
unsigned L_DPAD : 1;
unsigned D_DPAD : 1;
unsigned U_DPAD : 1;
unsigned START_BUTTON : 1;
unsigned Z_TRIG : 1;
unsigned B_BUTTON : 1;
unsigned A_BUTTON : 1;
unsigned R_CBUTTON : 1;
unsigned L_CBUTTON : 1;
unsigned D_CBUTTON : 1;
unsigned U_CBUTTON : 1;
unsigned R_TRIG : 1;
unsigned L_TRIG : 1;
unsigned Reserved1 : 1;
unsigned Reserved2 : 1;
signed X_AXIS : 8;
signed Y_AXIS : 8;
};
} BUTTONS;
000-001 | 002 | 003 |
---|---|---|
Buttons | Analog X | Analog Y |
Analog values are signed (-128 to 127), with down and right being positive. Note that TAS Input Plugin (which is used for all TASes) actually inverts the y-axis when saving to and loading from .m64 files, so up is positive instead.
For buttons, each value is determined by OR-ing together values for whichever of the following are pressed:
0x0001 C-Right 0x0002 C-Left 0x0004 C-Down 0x0008 C-Up 0x0010 R 0x0020 L 0x0040 (reserved) 0x0080 (reserved) 0x0100 Digital Pad Right 0x0200 Digital Pad Left 0x0400 Digital Pad Down 0x0800 Digital Pad Up 0x1000 Start 0x2000 Z 0x4000 B 0x8000 A
They will come in groups of however many controllers the game happens to check (note that it will never check disabled/disconnected controllers), in whatever order the game happens to check them.
Mupen64 1.0.3 or newer will trigger a core reset when the value for the controller info is specifically set to Reserved1 = 0x01, and Reserved2 = 0x01. The controller info is then cleared from being sent to the PIF RAM to avoid errors.
[1]: Added in v1.1.9