BMS file
A .bms
file holds data for sequenced music in Pikmin 2. BMS files are similar to MIDI files, but have many more advanced features. Custom BMS files can be made with Flaaffy by Arookas (which can be found here), however Yoshi2's fork of Flaaffy is better suited to making BMS files for Pikmin 2. You can find that here. You can also use JAIMaker for a GUI based converter.
Documentation[edit]
To do: Actually document every byte of a bms header and music data and what it all means.
A BMS file is made up of a sequence of commands which are a single byte, and can include a range of arguments. Each command has a fixed number of arguments. Values are read as big endian.
Instruction | Mnemonic | Type | Additional Arguments |
---|---|---|---|
0x00 - 0x80 | NOTE_ON | NoteOn | Variable |
0x80 | CMD_WAIT8 | Wait | int8 LEN, |
0x81 | NOTE_OFF | NoteOff | None |
0x88 | CMD_WAIT16 | Wait | int16 LEN |
0x90 | SETPARAM_90 | Param | byte Destination Register, byte Value |
0x91 | SETPARAM_91 | Param | byte Destination Register, byte Value |
0x92 | SETPARAM_92 | Param | byte Destination Register, byte Value |
0x94 | PERF_U8_NODUR | Perf | byte PERFValue, byte value |
0x96 | PERF_U8_DUR_U8 | Perf | byte PERFValue, byte value, byte duration |
0x97 | PERF_U8_DUR_U16 | Perf | byte PERFValue, byte value, short duration |
0x98 | PERF_S8_NODUR | Perf | byte PERFValue, sbyte value |
0x9A | PERF_S8_DUR_U8 | Perf | byte PERFValue, sbyte value, byte duration |
0x9B | PERF_S8_DUR_U16 | Perf | byte PERFValue, sbyte value, short duration |
0x9C | PERF_S16_NODUR | Perf | byte PERFValue, short value |
0x9D | PERF_S16_DUR_U8 | Perf | byte PERFValue, short value, byte duration |
0x9E | PERF_S16_DUR_U8_9E | Perf | byte PERFValue, short value, byte duration |
0x9F | PERF_S16_DUR_U16 | Perf | byte PERFValue, short value, short duration |
0xA0 | PARAM_SET_R | Param | byte dest_register, byte src_register |
0xA1 | PARAM_ADD_R | Param | byte dest_register, byte src_register |
0xA2 | PARAM_MUL_R | Param | byte dest_register, byte src_register |
0xA3 | PARAM_CMP_R | Param | byte dest_register, byte src_register |
0xA4 | PARAM_SET_8 | Param | byte register, byte value |
0xA5 | PARAM_ADD_8 | Param | byte register, byte value |
0xA6 | PARAM_MUL_8 | Param | byte register, byte value |
0xA7 | PARAM_CMP_8 | Param | byte register, byte value |
0xA8 | PARAM_LOAD_UNK | ? | ? |
0xA9 | PARAM_BITWISE | Param | |
0xAA | PARAM_LOADTBL | Param | |
0xAB | PARAM_SUBTRACT | Param | |
0xAC | PARAM_SET_16 | Param | byte register, short value |
0xAD | PARAM_ADD_16 | Param | byte register, short value |
0xAE | PARAM_MUL_16 | Param | byte register, short value |
0xAF | PARAM_CMP_16 | Param | byte register, short value |
0xB0 | OPOVERRIDE_1 | Override | It's complicated. |
0xB1 | OPOVERRIDE_2 | Override | |
0xB4 | OPOVERRIDE_4 | Override | |
0xB8 | OPOVERRIDE_R | Override | |
0xC1 | OPENTRACK | Track | byte trackID <= 0xF, int24 trackID |
0xC2 | OPENTRACKBROS | Track | |
0xC4 | CALL | Flow | byte condition, int24 address |
0xC5 | RETURN_NOARG | Flow | |
0xC6 | RETURN | Flow | byte condition |
0xC8 | JMP | Flow | int24 address |
0xC9 | LOOP_S | Flow | byte count |
0xCA | LOOP_E | Flow | |
0xCB | READPORT | Port | byte srcPort, byte dstRegister |
0xCC | WRITEPORT | Port | byte srcPort, byte dstRegister |
0xCD | CHECKPORTIMPORT | Port | byte srcPort |
0xCE | CHECKPORTEXPORT | Port | byte srcPort |
0xCF | CMD_WAITR | Wait | byte register |
0xD1 | PARENTWRITEPORT | Port | |
0xD2 | CHILDWRITEPORT | Port | |
0xD4 | SETLASTNOTE | byte lastNoteValue | |
0xD5 | TIMERELATE | ||
0xD6 | SIMPLEOSC | Oscillator | |
0xD7 | SIMPLEENV | Envelope | |
0xD8 | SIMPLEADSR | ||
0xD9 | TRANSPOSE | ||
0xDA | CLOSETRACK | Track | byte trackID |
0xDB | OUTSWITCH | ||
0xDC | UPDATESYNC | ||
0xDD | BUSCONNECT | Port | |
0xDE | PAUSESTATUS | Flow | |
0xDF | SETINTERRUPT | Interrupt | byte InterruptID, int24 Callback_Address |
0xE0 | DISINTERRUPT | Interrupt | |
0xE1 | CLRI | Interrupt | |
0xE2 | SETI | Interrupt | |
0xE3 | RETI | Interrupt | |
0xE4 | INTTIMER | Interrupt | |
0xE5 | VIBDEPTH | ||
0xE6 | VIBDEPTHMIDI | ||
0xE7 | SYNCCPU | Flow | short syncdata? |
0xE8 | FLUSHALL | ||
0xE9 | FLUSHRELEASE | ||
0xEA | WAIT_VLQ | Wait | VLC delay |
0xEB | PANPOWSET | ||
0xEC | IIRSET | ||
0xED | FIRSET | ||
0xEE | EXTSET | ||
0xEF | PANSWSET | ||
0xF0 | OSCROUTE | ||
0xF1 | IIRCUTOFF | ||
0xF2 | OSCFULL | ||
0xF3 | VOLUMEMODE | ||
0xF4 | VIBPITCH | ||
0xFA | CHECKWAVE | ||
0xFB | PRINTF | PrintF | Variable |
0xFC | NOP | Misc | Skips this opcode, can be used for patching things out |
0xFD | TEMPO | Flow | int16 Tempo |
0xFE | TIMEBASE | Flow | int16 Timebase |
0xFF | FINISH | Track |
List of BMS files[edit]
A full list of all the BMS files in Pikmin 2 can be found here.
Interactive music[edit]
A lot of BMS music in Pikmin 2 is interactive, meaning that parts of it change depending on what you do in the game. A tutorial to do this can be found here. Cave music is a different process, and can be found here.