aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2017-09-05 01:08:51 -0500
committerColin Snover2017-09-12 20:08:02 -0500
commit9ac219648ea24449146549769fcb8723c0ac825e (patch)
tree00b8894ad091659bd6a4806b7c5f9c82f6d2d1e4
parentd5df72998c33a03b58b0206dd39685280f25d39d (diff)
downloadscummvm-rg350-9ac219648ea24449146549769fcb8723c0ac825e.tar.gz
scummvm-rg350-9ac219648ea24449146549769fcb8723c0ac825e.tar.bz2
scummvm-rg350-9ac219648ea24449146549769fcb8723c0ac825e.zip
SCI: Omit SysEx delays when sending to MT-32 emulator
Real MIDI devices, and MT-32 in particular, need delays between SysEx messages to ensure sufficient time to receive and process the incoming data buffer. Sending too much data too quickly to these devices can cause them to crash with a buffer overflow. The MT-32 emulator, on the other hand, has no problem receiving SysEx data instantly, so skipping the delays means that games that send lots of data to the MT-32 will start up much faster.
-rw-r--r--engines/sci/sound/drivers/midi.cpp51
1 files changed, 33 insertions, 18 deletions
diff --git a/engines/sci/sound/drivers/midi.cpp b/engines/sci/sound/drivers/midi.cpp
index 6821b2219f..3f6149daf9 100644
--- a/engines/sci/sound/drivers/midi.cpp
+++ b/engines/sci/sound/drivers/midi.cpp
@@ -134,6 +134,12 @@ public:
kMaxSysExSize = 264
};
+ enum Mt32Type {
+ kMt32TypeNone,
+ kMt32TypeReal,
+ kMt32TypeEmulated
+ };
+
MidiPlayer_Midi(SciVersion version);
virtual ~MidiPlayer_Midi();
@@ -191,7 +197,7 @@ private:
keyShift(0), volAdjust(0), pan(0x40), hold(0), volume(0x7f) { }
};
- bool _isMt32;
+ Mt32Type _mt32Type;
bool _useMT32Track;
bool _hasReverb;
bool _playSwitch;
@@ -214,12 +220,17 @@ private:
byte _sysExBuf[kMaxSysExSize];
};
-MidiPlayer_Midi::MidiPlayer_Midi(SciVersion version) : MidiPlayer(version), _playSwitch(true), _masterVolume(15), _isMt32(false), _hasReverb(false), _useMT32Track(true) {
+MidiPlayer_Midi::MidiPlayer_Midi(SciVersion version) : MidiPlayer(version), _playSwitch(true), _masterVolume(15), _mt32Type(kMt32TypeNone), _hasReverb(false), _useMT32Track(true) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI);
_driver = MidiDriver::createMidi(dev);
- if (MidiDriver::getMusicType(dev) == MT_MT32 || ConfMan.getBool("native_mt32"))
- _isMt32 = true;
+ if (MidiDriver::getMusicType(dev) == MT_MT32 || ConfMan.getBool("native_mt32")) {
+ if (MidiDriver::getDeviceString(dev, MidiDriver::kDriverId) == "mt32") {
+ _mt32Type = kMt32TypeEmulated;
+ } else {
+ _mt32Type = kMt32TypeReal;
+ }
+ }
_sysExBuf[0] = 0x41;
_sysExBuf[1] = 0x10;
@@ -439,13 +450,13 @@ void MidiPlayer_Midi::send(uint32 b) {
// We return 1 for mt32, because if we remap channels to 0 for mt32, those won't get played at all
// NOTE: SSCI uses channels 1 through 8 for General MIDI as well, in the drivers I checked
int MidiPlayer_Midi::getFirstChannel() const {
- if (_isMt32)
+ if (_mt32Type != kMt32TypeNone)
return 1;
return 0;
}
int MidiPlayer_Midi::getLastChannel() const {
- if (_isMt32)
+ if (_mt32Type != kMt32TypeNone)
return 8;
return 15;
}
@@ -998,8 +1009,10 @@ void MidiPlayer_Midi::resetMt32() {
Common::MemoryReadStream s((const byte *)"\x01\x00", 2);
sendMt32SysEx(0x7f0000, s, 2, true);
- // This seems to require a longer delay than usual
- g_system->delayMillis(150);
+ if (_mt32Type != kMt32TypeEmulated) {
+ // This seems to require a longer delay than usual
+ g_sci->sleep(150);
+ }
}
int MidiPlayer_Midi::open(ResourceManager *resMan) {
@@ -1038,7 +1051,7 @@ int MidiPlayer_Midi::open(ResourceManager *resMan) {
}
}
- if (_isMt32) {
+ if (_mt32Type != kMt32TypeNone) {
// MT-32
resetMt32();
@@ -1145,7 +1158,7 @@ int MidiPlayer_Midi::open(ResourceManager *resMan) {
}
void MidiPlayer_Midi::close() {
- if (_isMt32) {
+ if (_mt32Type != kMt32TypeNone) {
// Send goodbye message
sendMt32SysEx(0x200000, SciSpan<const byte>(_goodbyeMsg, 20), true);
}
@@ -1156,15 +1169,17 @@ void MidiPlayer_Midi::close() {
void MidiPlayer_Midi::sysEx(const byte *msg, uint16 length) {
_driver->sysEx(msg, length);
- // Wait the time it takes to send the SysEx data
- uint32 delay = (length + 2) * 1000 / 3125;
+ if (_mt32Type != kMt32TypeEmulated) {
+ // Wait the time it takes to send the SysEx data
+ uint32 delay = (length + 2) * 1000 / 3125;
- // Plus an additional delay for the MT-32 rev00
- if (_isMt32)
- delay += 40;
+ // Plus an additional delay for the MT-32 rev00
+ if (_mt32Type == kMt32TypeReal)
+ delay += 40;
- g_system->updateScreen();
- g_sci->sleep(delay);
+ g_system->updateScreen();
+ g_sci->sleep(delay);
+ }
}
byte MidiPlayer_Midi::getPlayId() const {
@@ -1173,7 +1188,7 @@ byte MidiPlayer_Midi::getPlayId() const {
case SCI_VERSION_0_LATE:
return 0x01;
default:
- if (_isMt32)
+ if (_mt32Type != kMt32TypeNone)
return 0x0c;
else
return _useMT32Track ? 0x0c : 0x07;