diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/groovie/music.cpp | 64 |
1 files changed, 56 insertions, 8 deletions
diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp index a5dd5d809a..3f08ea19ad 100644 --- a/engines/groovie/music.cpp +++ b/engines/groovie/music.cpp @@ -609,18 +609,66 @@ void MusicPlayerXMI::setTimbreAD(byte channel, const Timbre &timbre) { } } + +#include "common/pack-start.h" // START STRUCT PACKING + +struct RolandInstrumentSysex { + byte roland_id; + byte device_id; + byte model_id; + byte command; + byte address[3]; + byte instrument[0xF6]; + byte checksum; +} PACKED_STRUCT; + +#include "common/pack-end.h" // END STRUCT PACKING + +void setRolandInstrument(MidiDriver *drv, byte channel, byte *instrument) { + RolandInstrumentSysex sysex; + memcpy(&sysex.instrument, instrument, 0xF6); + + // Show the timbre name as extra debug information + Common::String name((char *)instrument, 10); + debugC(5, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Setting MT32 timbre '%s' to channel %d", name.c_str(), channel); + + sysex.roland_id = 0x41; + sysex.device_id = channel; // Unit# + sysex.model_id = 0x16; // MT32 + sysex.command = 0x12; // Data set + + // Remap instrument to appropriate address space. + int address = 0x008000; + sysex.address[0] = (address >> 14) & 0x7F; + sysex.address[1] = (address >> 7) & 0x7F; + sysex.address[2] = (address ) & 0x7F; + + // Compute the checksum. + byte checksum = 0; + byte *ptr = sysex.address; + for (int i = 4; i < (int)sizeof(RolandInstrumentSysex) - 1; ++i) + checksum -= *ptr++; + sysex.checksum = checksum & 0x7F; + + // Send sysex + drv->sysEx((byte *)&sysex, sizeof(RolandInstrumentSysex)); + + + // Wait the time it takes to send the SysEx data + uint32 delay = (sizeof(RolandInstrumentSysex) + 2) * 1000 / 3125; + + // Plus an additional delay for the MT-32 rev00 + delay += 40; + + g_system->delayMillis(delay); +} + void MusicPlayerXMI::setTimbreMT(byte channel, const Timbre &timbre) { // Verify the timbre size - if (timbre.size != 0xF6) { + if (timbre.size != 0xF6) error("Groovie::Music: Invalid size for an MT-32 timbre: %d", timbre.size); - } - - // Show the timbre name as extra debug information - Common::String name((char*)timbre.data, 10); - debugC(5, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Using MT32 timbre: %s", name.c_str()); - // TODO: Support MT-32 custom instruments - warning("Groovie::Music: Setting MT32 custom instruments isn't supported yet"); + setRolandInstrument(_driver, channel, timbre.data); } |