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. There is absolutely no way to correlate the amount of input data with the length of the movie, because the N64 may check input many times in 1 frame or it may not check any input at all for a large number of frames, or anything in-between.
Mupen64 will trigger a power off/on 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. This feature is only available in Mupen64 ReRecordingV2 and later versions.
[1]: Added in v1.1.9 which is about to get released