diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp index b78066cdd45..8a5c856983a 100644 --- a/backends/midi/alsa.cpp +++ b/backends/midi/alsa.cpp @@ -213,9 +213,9 @@ void MidiDriver_ALSA::send(uint32 b) { } void MidiDriver_ALSA::sysEx(const byte *msg, uint16 length) { - unsigned char buf[256]; + unsigned char buf[266]; - assert(length + 2 <= 256); + assert(length + 2 <= ARRAYSIZE(buf)); // Add SysEx frame buf[0] = 0xF0; diff --git a/backends/midi/camd.cpp b/backends/midi/camd.cpp index bab047746b0..24d211281c0 100644 --- a/backends/midi/camd.cpp +++ b/backends/midi/camd.cpp @@ -115,9 +115,9 @@ void MidiDriver_CAMD::send(uint32 b) { } void MidiDriver_CAMD::sysEx(const byte *msg, uint16 length) { - unsigned char buf[256]; + unsigned char buf[266]; - assert(length + 2 <= 256); + assert(length + 2 <= ARRAYSIZE(buf)); // Add SysEx frame buf[0] = 0xF0; diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp index 0d72a1576a4..d89123292c3 100644 --- a/backends/midi/coreaudio.cpp +++ b/backends/midi/coreaudio.cpp @@ -190,9 +190,9 @@ void MidiDriver_CORE::send(uint32 b) { } void MidiDriver_CORE::sysEx(const byte *msg, uint16 length) { - unsigned char buf[256]; + unsigned char buf[266]; - assert(length + 2 <= 256); + assert(length + 2 <= ARRAYSIZE(buf)); assert(_auGraph != NULL); // Add SysEx frame diff --git a/backends/midi/seq.cpp b/backends/midi/seq.cpp index 920356147fc..9c7cc83d67e 100644 --- a/backends/midi/seq.cpp +++ b/backends/midi/seq.cpp @@ -146,11 +146,11 @@ void MidiDriver_SEQ::send(uint32 b) { } void MidiDriver_SEQ::sysEx (const byte *msg, uint16 length) { - unsigned char buf [1024]; + unsigned char buf [1330]; int position = 0; const byte *chr = msg; - assert(length + 2 <= 256); + assert(length + 2 <= 266); buf[position++] = SEQ_MIDIPUTC; buf[position++] = 0xF0; diff --git a/backends/midi/stmidi.cpp b/backends/midi/stmidi.cpp index 6cba1b819dc..f07b5b56cad 100644 --- a/backends/midi/stmidi.cpp +++ b/backends/midi/stmidi.cpp @@ -91,7 +91,10 @@ void MidiDriver_STMIDI::send(uint32 b) { } void MidiDriver_STMIDI::sysEx (const byte *msg, uint16 length) { - if (length > 254) { + // FIXME: LordHoto doesn't know if this will still work + // when sending 264 byte sysEx data, as needed by KYRA, + // feel free to revert it to 254 again if needed. + if (length > 264) { warning ("Cannot send SysEx block - data too large"); return; } diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp index d13fc4b79a5..47ef0f2ea9c 100644 --- a/backends/midi/timidity.cpp +++ b/backends/midi/timidity.cpp @@ -487,11 +487,11 @@ void MidiDriver_TIMIDITY::send(uint32 b) { void MidiDriver_TIMIDITY::sysEx(const byte *msg, uint16 length) { fprintf(stderr, "Timidity::sysEx\n"); - unsigned char buf[1024]; + unsigned char buf[1330]; int position = 0; const byte *chr = msg; - assert(length + 2 <= 256); + assert(length + 2 <= 266); buf[position++] = SEQ_MIDIPUTC; buf[position++] = 0xF0; diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp index d1f79f4fa36..f9da3e3e4d3 100644 --- a/backends/midi/windows.cpp +++ b/backends/midi/windows.cpp @@ -42,7 +42,7 @@ class MidiDriver_WIN : public MidiDriver_MPU401 { private: MIDIHDR _streamHeader; - byte _streamBuffer[256]; // SysEx blocks should be no larger than 256 bytes + byte _streamBuffer[266]; // SysEx blocks should be no larger than 266 bytes HANDLE _streamEvent; HMIDIOUT _mo; bool _isOpen; @@ -106,7 +106,7 @@ void MidiDriver_WIN::sysEx(const byte *msg, uint16 length) { return; } - assert(length+2 <= 256); + assert(length+2 <= 266); midiOutUnprepareHeader(_mo, &_streamHeader, sizeof(_streamHeader)); diff --git a/backends/midi/zodiac.cpp b/backends/midi/zodiac.cpp index f17f6796b7a..1b3b578aab2 100644 --- a/backends/midi/zodiac.cpp +++ b/backends/midi/zodiac.cpp @@ -112,7 +112,7 @@ void MidiDriver_Zodiac::send(uint32 b) { } void MidiDriver_Zodiac::sysEx(const byte *msg, uint16 length) { - unsigned char buf[256]; + unsigned char buf[266]; buf[0] = 0xF0; memcpy(buf + 1, msg, length); diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h index 4ef9f479c89..e1dde72b8de 100644 --- a/engines/kyra/kyra_v1.h +++ b/engines/kyra/kyra_v1.h @@ -110,6 +110,7 @@ class KyraEngine_v1 : public Engine { friend class Debugger; friend class ::KyraMetaEngine; friend class GUI; +friend class SoundMidiPC; // For _eventMan public: KyraEngine_v1(OSystem *system, const GameFlags &flags); virtual ~KyraEngine_v1(); diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp index a1d5b927160..73fad4a4c58 100644 --- a/engines/kyra/sound_midi.cpp +++ b/engines/kyra/sound_midi.cpp @@ -182,8 +182,16 @@ void MidiOutput::send(uint32 b) { _channels[channel].program = _sources[_curSource].channelProgram[channel] = param1; } else if (event == 0xB0) { // Controller change + for (int i = 0; i < 9; ++i) { + Controller &cont = _sources[_curSource].controllers[channel][i]; + if (cont.controller == param1) { + cont.value = param2; + break; + } + } + if (param1 == 0x07) { - param1 = (param1 * _sources[_curSource].volume) >> 8; + param2 = (param2 * _sources[_curSource].volume) >> 8; } else if (param1 == 0x6E) { // Lock Channel if (param2 >= 0x40) { // Lock Channel int chan = lockChannel(); @@ -206,15 +214,6 @@ void MidiOutput::send(uint32 b) { // on track change, we simply ignore it. return; } - - for (int i = 0; i < 9; ++i) { - Controller &cont = _sources[_curSource].controllers[channel][i]; - if (cont.controller == param1) { - cont.value = param2; - break; - } - } - } else if (event == 0x90 || event == 0x80) { // Note On/Off if (!(_channels[channel].flags & kChannelLocked)) { const bool remove = (event == 0x80) || (param2 == 0x00); @@ -258,11 +257,7 @@ void MidiOutput::send(uint32 b) { } void MidiOutput::sendIntern(const byte event, const byte channel, byte param1, const byte param2) { - if (event == 0xE0) { - _channels[channel].pitchWheel = (param2 << 8) | param1; - } else if (event == 0xC0) { - _channels[channel].program = param1; - + if (event == 0xC0) { // MT32 -> GM conversion if (!_isMT32 && _defaultMT32) param1 = _mt32ToGm[param1]; @@ -330,8 +325,6 @@ void MidiOutput::setSourceVolume(int source, uint8 volume, bool apply) { // Controller 0 in the state table should always be '7' aka // volume control byte realVol = (_channels[i].controllers[0].value * volume) >> 8; - _channels[i].controllers[0].value = realVol; - sendIntern(0xB0, i, 0x07, realVol); } } @@ -509,10 +502,26 @@ bool SoundMidiPC::init() { _output->setTimerCallback(this, SoundMidiPC::onTimer); - /*loadSoundFile("INTRO"); - playTrack(0); - while (_music->isPlaying()) - _vm->_system->delayMillis(10);*/ + if (_nativeMT32) { + if (_vm->gameFlags().gameID == GI_KYRA1) { + loadSoundFile("INTRO"); + } else if (_vm->gameFlags().gameID == GI_KYRA2) { + _vm->resource()->loadPakFile("AUDIO.PAK"); + loadSoundFile("HOF_SYX"); + } + + playTrack(0); + + Common::Event event; + while (isPlaying() && !_vm->shouldQuit()) { + _vm->_system->updateScreen(); + _vm->_eventMan->pollEvent(event); + _vm->_system->delayMillis(10); + } + + if (_vm->gameFlags().gameID == GI_KYRA2) + _vm->resource()->unloadPakFile("AUDIO.PAK"); + } return true; } @@ -594,9 +603,12 @@ void SoundMidiPC::loadSfxFile(Common::String file) { void SoundMidiPC::playTrack(uint8 track) { Common::StackLock lock(_mutex); - _output->initSource(0); + _fadeMusicOut = false; _output->setSourceVolume(0, _musicVolume, true); + + _output->initSource(0); + _output->setSourceVolume(0, _musicVolume, true); _music->setTrack(track); } @@ -620,7 +632,7 @@ void SoundMidiPC::playSoundEffect(uint8 track) { if (!_sfx[i]->isPlaying()) { _output->initSource(i+1); _sfx[i]->setTrack(track); - break; + return; } } } diff --git a/sound/mididrv.h b/sound/mididrv.h index 9d5a7d44078..dd1786a0945 100644 --- a/sound/mididrv.h +++ b/sound/mididrv.h @@ -216,7 +216,7 @@ public: * do NOT include the leading 0xF0 and the trailing 0xF7. * * Furthermore, the maximal supported length of a SysEx - * is 254 bytes. Passing longer buffers can lead to + * is 264 bytes. Passing longer buffers can lead to * undefined behavior (most likely, a crash). */ virtual void sysEx(const byte *msg, uint16 length) { }