mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-30 07:23:05 +00:00
SCUMM: Implement support for special sfx in MI2 Mac.
This also increases the savegame version, since it introduces a new Instrument subclass.
This commit is contained in:
parent
58f542d434
commit
6ea51e8c45
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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); }
|
||||
|
@ -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) {
|
||||
|
@ -74,7 +74,8 @@ private:
|
||||
|
||||
enum {
|
||||
kDefaultInstrument = 0x3E7,
|
||||
kProgramChangeBase = 0x3E8
|
||||
kProgramChangeBase = 0x3E8,
|
||||
kSysExBase = 0x7D0
|
||||
};
|
||||
|
||||
Instrument getInstrument(int idx) const;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user