diff options
-rw-r--r-- | scumm/imuse.cpp | 23 | ||||
-rw-r--r-- | scumm/instrument.cpp | 3 | ||||
-rw-r--r-- | scumm/instrument.h | 6 |
3 files changed, 30 insertions, 2 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp index 095f858913..08d47112ad 100644 --- a/scumm/imuse.cpp +++ b/scumm/imuse.cpp @@ -272,6 +272,7 @@ struct Part { void silence(); void set_instrument(uint b); void set_instrument(byte * data); + void load_global_instrument (byte b); void set_transpose(int8 transpose); void set_vol(uint8 volume); @@ -366,6 +367,7 @@ public: void on_timer() {} void set_instrument(uint slot, byte *instr); + void part_load_global_instrument (Part *part, byte slot); void part_set_param(Part *part, byte param, int value) {} void part_key_on(Part *part, byte note, byte velocity); void part_key_off(Part *part, byte note); @@ -2073,8 +2075,12 @@ byte *Player::parse_midi(byte *s) case 0xC: // Program Change value = *s++; part = get_part(chan); - if (part) - part->set_program(value); + if (part) { + if (_isGM || value >= 32) + part->set_program(value); + else + part->load_global_instrument (value); + } break; case 0xD: // Channel Pressure @@ -3277,6 +3283,11 @@ void Part::set_instrument(byte * data) changed(IMuseDriver::pcProgram); } +void Part::load_global_instrument (byte slot) +{ + _drv->part_load_global_instrument (this, slot); +} + void Part::key_on(byte note, byte velocity) { _drv->part_key_on(this, note, velocity); @@ -3695,6 +3706,14 @@ void IMuseDriver::set_instrument(uint slot, byte *data) } } +void IMuseDriver::part_load_global_instrument (Part *part, byte slot) +{ + if (slot >= 32) + return; + _glob_instr [slot].copy_to (&part->_instrument); + part->changed (pcProgram); +} + void IMuseDriver::part_changed(Part *part, uint16 what) { MidiChannel *mc; diff --git a/scumm/instrument.cpp b/scumm/instrument.cpp index bd7eec8a49..e8201ab8d7 100644 --- a/scumm/instrument.cpp +++ b/scumm/instrument.cpp @@ -133,6 +133,7 @@ public: Instrument_Program (Serializer *s); void saveOrLoad (Serializer *s); void send (MidiChannel *mc); + void copy_to (Instrument *dest) { dest->program (_program, _mt32); } }; class Instrument_Adlib : public InstrumentInternal { @@ -161,6 +162,7 @@ public: Instrument_Adlib (Serializer *s); void saveOrLoad (Serializer *s); void send (MidiChannel *mc); + void copy_to (Instrument *dest) { dest->adlib ((byte *) &_instrument); } }; class Instrument_Roland : public InstrumentInternal { @@ -230,6 +232,7 @@ public: Instrument_Roland (Serializer *s); void saveOrLoad (Serializer *s); void send (MidiChannel *mc); + void copy_to (Instrument *dest) { dest->roland ((byte *) &_instrument); } }; diff --git a/scumm/instrument.h b/scumm/instrument.h index e28bf5321c..a3ab367142 100644 --- a/scumm/instrument.h +++ b/scumm/instrument.h @@ -30,10 +30,15 @@ class Serializer; class MidiChannel; +class Instrument; + + + class InstrumentInternal { public: virtual void saveOrLoad (Serializer *s) = 0; virtual void send (MidiChannel *mc) = 0; + virtual void copy_to (Instrument *dest) = 0; }; class Instrument { @@ -52,6 +57,7 @@ public: Instrument() : _type (0), _instrument (0) { } void clear(); + void copy_to (Instrument *dest) { if (_instrument) _instrument->copy_to (dest); else dest->clear(); } void program (byte program, bool mt32); void adlib (byte *instrument); void roland (byte *instrument); |