aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2013-04-02 10:03:15 +0300
committerFilippos Karapetis2013-04-02 10:03:48 +0300
commitc6320a28e483e52b489cae8e86774008e030492b (patch)
treeae0152880df8d95ea8f3dc109167fa156a404146
parenta1168e932c498f806f664e73f9ffe2bd8ecc1c12 (diff)
downloadscummvm-rg350-c6320a28e483e52b489cae8e86774008e030492b.tar.gz
scummvm-rg350-c6320a28e483e52b489cae8e86774008e030492b.tar.bz2
scummvm-rg350-c6320a28e483e52b489cae8e86774008e030492b.zip
SCI: Add a more generic solution for the problem found in bug #3605269
We now accept signals from all channels if channel 15 is missing. This is a very rare edge case, but our behavior is now somewhat closer to what the original interpreter seems to be doing. Mordack's appearance animation is now synced properly. The more generic workaround works for songs 1840 and 1843, but not for 1849, which is still problematic and we still resort to manually changing its dataInc selector
-rw-r--r--engines/sci/sound/midiparser_sci.cpp10
-rw-r--r--engines/sci/sound/soundcmd.cpp15
2 files changed, 14 insertions, 11 deletions
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 4e54797960..0e5672460d 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -475,7 +475,13 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
case 0xC:
info.basic.param1 = *(_position._playPos++);
info.basic.param2 = 0;
- if (info.channel() == 0xF) {// SCI special case
+ // Normally, song signalling events are sent through the special SCI
+ // channel 15. There are some songs where that special channel is
+ // missing completely, and the signals are sent through the other
+ // channels. Such a case is the Windows version of KQ5CD, songs 1840,
+ // 1843 and 1849 (bug #3605269). Therefore, we check if channel 15 is
+ // present, and if not, we accept signals from all other channels.
+ if (info.channel() == 0xF || !_channelUsed[15]) { // SCI special channel
if (info.basic.param1 != kSetSignalLoop) {
// At least in kq5/french&mac the first scene in the intro has
// a song that sets signal to 4 immediately on tick 0. Signal
@@ -491,6 +497,8 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
_position._playTick || info.delta) {
_signalSet = true;
_signalToSet = info.basic.param1;
+ debugC(kDebugLevelSound, "Setting signal of song %d to %d from channel %d",
+ _pSnd->resourceId, _signalToSet, info.channel());
}
} else {
_loopTick = _position._playTick + info.delta;
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 9450e7796d..db357054d4 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -177,16 +177,11 @@ void SoundCommandParser::processPlaySound(reg_t obj) {
writeSelectorValue(_segMan, obj, SELECTOR(state), kSoundPlaying);
}
- // WORKAROUND: Songs 1840, 1843 and 1849 in the Windows version of KQ5CD
- // are all missing their channel 15 (all played during its ending
- // sequences, when fighting with Mordack). This makes the game scripts
- // wait indefinitely for the missing signals in these songs. In the
- // original interpreter, this bug manifests as an "Out of heap" error. We
- // signal the game scripts to stop waiting forever by setting the song's
- // dataInc selector to something other than 0. This causes Mordack's
- // appearing animation to occur a bit earlier than expected, but at least
- // the game doesn't freeze at that point. Fixes bug #3605269.
- if (g_sci->getGameId() == GID_KQ5 && (resourceId == 1840 || resourceId == 1843 || resourceId == 1849))
+ // WORKAROUND: Song 1849 in the Windows version of KQ5CD does not have
+ // correct signalling data, causing the game scripts to wait indefinitely
+ // for the missing signal. We signal the game scripts to stop waiting
+ // forever by setting the song's dataInc selector to something other than 0
+ if (g_sci->getGameId() == GID_KQ5 && resourceId == 1849)
writeSelectorValue(_segMan, obj, SELECTOR(dataInc), 1);
musicSlot->loop = readSelectorValue(_segMan, obj, SELECTOR(loop));