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

EmulatorResources/Mupen/M64 last edited by Aurumaker72 4 days ago
Page History Latest diff List referrers View Source