diff options
| -rw-r--r-- | engines/scumm/imuse/imuse_part.cpp | 13 | ||||
| -rw-r--r-- | engines/scumm/imuse/instrument.cpp | 60 | ||||
| -rw-r--r-- | engines/scumm/imuse/instrument.h | 4 | ||||
| -rw-r--r-- | engines/scumm/imuse/mac_m68k.cpp | 5 | ||||
| -rw-r--r-- | engines/scumm/imuse/mac_m68k.h | 3 | ||||
| -rw-r--r-- | engines/scumm/saveload.h | 2 | 
6 files changed, 83 insertions, 4 deletions
diff --git a/engines/scumm/imuse/imuse_part.cpp b/engines/scumm/imuse/imuse_part.cpp index 73e7704469..d4e4740451 100644 --- a/engines/scumm/imuse/imuse_part.cpp +++ b/engines/scumm/imuse/imuse_part.cpp @@ -27,6 +27,7 @@  #include "common/util.h"  #include "scumm/imuse/imuse_internal.h"  #include "scumm/saveload.h" +#include "scumm/scumm.h"  namespace Scumm { @@ -365,7 +366,17 @@ void Part::set_instrument(uint b) {  	_bank = (byte)(b >> 8);  	if (_bank)  		error("Non-zero instrument bank selection. Please report this"); -	_instrument.program((byte)b, _player->isMT32()); +	// HACK: Horrible hack to allow tracing of program change source. +	// The Mac version of Monkey Island 2 uses a different program "bank" +	// when it gets program change events through the iMuse SysEx handler. +	// We emulate this by introducing a special instrument, which sets +	// the instrument via sysEx_customInstrument. This seems to be +	// exclusively used for special sound effects like the "spit" sound. +	if (g_scumm->_game.id == GID_MONKEY2 && g_scumm->_game.platform == Common::kPlatformMacintosh) { +		_instrument.macSfx(b); +	} else { +		_instrument.program((byte)b, _player->isMT32()); +	}  	if (clearToTransmit())  		_instrument.send(_mc);  } diff --git a/engines/scumm/imuse/instrument.cpp b/engines/scumm/imuse/instrument.cpp index 11bb4e7605..61c73b1e2d 100644 --- a/engines/scumm/imuse/instrument.cpp +++ b/engines/scumm/imuse/instrument.cpp @@ -278,6 +278,21 @@ private:  	byte _instrument[23];  }; +class Instrument_MacSfx : public InstrumentInternal { +private: +	byte _program; + +public: +	Instrument_MacSfx(byte program); +	Instrument_MacSfx(Serializer *s); +	void saveOrLoad(Serializer *s); +	void send(MidiChannel *mc); +	void copy_to(Instrument *dest) { dest->macSfx(_program); } +	bool is_valid() { +		return (_program < 128); +	} +}; +  ////////////////////////////////////////  //  // Instrument class members @@ -326,6 +341,14 @@ void Instrument::pcspk(const byte *instrument) {  	_instrument = new Instrument_PcSpk(instrument);  } +void Instrument::macSfx(byte prog) { +	clear(); +	if (prog > 127) +		return; +	_type = itMacSfx; +	_instrument = new Instrument_MacSfx(prog); +} +  void Instrument::saveOrLoad(Serializer *s) {  	if (s->isSaving()) {  		s->saveByte(_type); @@ -349,6 +372,9 @@ void Instrument::saveOrLoad(Serializer *s) {  		case itPcSpk:  			_instrument = new Instrument_PcSpk(s);  			break; +		case itMacSfx: +			_instrument = new Instrument_MacSfx(s); +			break;  		default:  			warning("No known instrument classification #%d", (int)_type);  			_type = itNone; @@ -528,4 +554,38 @@ void Instrument_PcSpk::send(MidiChannel *mc) {  	mc->sysEx_customInstrument('SPK ', (byte *)&_instrument);  } +//////////////////////////////////////// +// +// Instrument_MacSfx class members +// +//////////////////////////////////////// + +Instrument_MacSfx::Instrument_MacSfx(byte program) : +	_program(program) { +	if (program > 127) { +		_program = 255; +	} +} + +Instrument_MacSfx::Instrument_MacSfx(Serializer *s) { +	_program = 255; +	if (!s->isSaving()) { +		saveOrLoad(s); +	} +} + +void Instrument_MacSfx::saveOrLoad(Serializer *s) { +	if (s->isSaving()) { +		s->saveByte(_program); +	} else { +		_program = s->loadByte(); +	} +} + +void Instrument_MacSfx::send(MidiChannel *mc) { +	if (_program > 127) { +		return; +	} +	mc->sysEx_customInstrument('MAC ', &_program); +}  } // End of namespace Scumm diff --git a/engines/scumm/imuse/instrument.h b/engines/scumm/imuse/instrument.h index a855c64155..7e09e86fa5 100644 --- a/engines/scumm/imuse/instrument.h +++ b/engines/scumm/imuse/instrument.h @@ -52,7 +52,8 @@ public:  		itProgram = 1,  		itAdLib = 2,  		itRoland = 3, -		itPcSpk = 4 +		itPcSpk = 4, +		itMacSfx = 5  	};  	Instrument() : _type(0), _instrument(0) { } @@ -72,6 +73,7 @@ public:  	void adlib(const byte *instrument);  	void roland(const byte *instrument);  	void pcspk(const byte *instrument); +	void macSfx(byte program);  	byte getType() { return _type; }  	bool isValid() { return (_instrument ? _instrument->is_valid() : false); } diff --git a/engines/scumm/imuse/mac_m68k.cpp b/engines/scumm/imuse/mac_m68k.cpp index 9d6bdd0544..4d7a6a64c0 100644 --- a/engines/scumm/imuse/mac_m68k.cpp +++ b/engines/scumm/imuse/mac_m68k.cpp @@ -111,6 +111,7 @@ void MacM68kDriver::send(uint32 d) {  }  void MacM68kDriver::sysEx_customInstrument(byte channel, uint32 type, const byte *instr) { +	assert(false);  }  MidiChannel *MacM68kDriver::allocateChannel() { @@ -416,6 +417,10 @@ void MacM68kDriver::MidiChannel_MacM68k::priority(byte value) {  }  void MacM68kDriver::MidiChannel_MacM68k::sysEx_customInstrument(uint32 type, const byte *instr) { +	assert(instr); +	if (type == 'MAC ') { +		_instrument = _owner->getInstrument(*instr + kSysExBase); +	}  }  void MacM68kDriver::MidiChannel_MacM68k::init(MacM68kDriver *owner, byte channel) { diff --git a/engines/scumm/imuse/mac_m68k.h b/engines/scumm/imuse/mac_m68k.h index a8686e776f..59e2f68b9b 100644 --- a/engines/scumm/imuse/mac_m68k.h +++ b/engines/scumm/imuse/mac_m68k.h @@ -74,7 +74,8 @@ private:  	enum {  		kDefaultInstrument = 0x3E7, -		kProgramChangeBase = 0x3E8 +		kProgramChangeBase = 0x3E8, +		kSysExBase         = 0x7D0  	};  	Instrument getInstrument(int idx) const; diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index d5f7ea526e..a640bc1e17 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -47,7 +47,7 @@ namespace Scumm {   * only saves/loads those which are valid for the version of the savegame   * which is being loaded/saved currently.   */ -#define CURRENT_VER 92 +#define CURRENT_VER 93  /**   * An auxillary macro, used to specify savegame versions. We use this instead  | 
