diff options
-rw-r--r-- | engines/sci/sound/midiparser_sci.cpp | 34 | ||||
-rw-r--r-- | engines/sci/sound/midiparser_sci.h | 1 | ||||
-rw-r--r-- | engines/sci/sound/music.cpp | 20 |
3 files changed, 35 insertions, 20 deletions
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp index d6ff4f6cc8..83b5bf520f 100644 --- a/engines/sci/sound/midiparser_sci.cpp +++ b/engines/sci/sound/midiparser_sci.cpp @@ -103,6 +103,18 @@ bool MidiParser_SCI::loadMusic(SoundResource::Track *track, MusicEntry *psnd, in return true; } +bool MidiParser_SCI::jumpToOffset(uint32 offset) { + if (_activeTrack >= _numTracks) + return false; + + assert(!_jumpingToTick); // This function must not be called while within MidiParser::jumpToTick() + + resetTracking(); + _position._playPos = _tracks[_activeTrack] + offset; + parseNextEvent(_nextEvent); + return true; +} + byte MidiParser_SCI::midiGetNextChannel(long ticker) { byte curr = 0xFF; long closest = ticker + 1000000, next = 0; @@ -531,25 +543,9 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) { case 0xC: if (info.channel() == 0xF) {// SCI special case 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 - // isn't set at that point by sierra sci and it would cause the - // castle daventry text to get immediately removed, so we - // currently filter it. Sierra SCI ignores them as well at that - // time. However, this filtering should only be performed for - // SCI1 and newer games. Signalling is done differently in SCI0 - // though, so ignoring these signals in SCI0 games will result - // in glitches (e.g. the intro of LB1 Amiga gets stuck - bug - // #3297883). Refer to MusicEntry::setSignal() in sound/music.cpp. - // FIXME: SSCI doesn't start playing at the very beginning - // of the stream, but at a fixed location a few commands later. - // That is probably why this signal isn't triggered - // immediately there. - if (_soundVersion <= SCI_VERSION_0_LATE || _position._playTick) { - if (!_jumpingToTick) { - _pSnd->setSignal(info.basic.param1); - debugC(4, kDebugLevelSound, "signal %04x", info.basic.param1); - } + if (!_jumpingToTick) { + _pSnd->setSignal(info.basic.param1); + debugC(4, kDebugLevelSound, "signal %04x", info.basic.param1); } } else { _loopTick = _position._playTick; diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h index 5784dca1ab..098fbc2ccb 100644 --- a/engines/sci/sound/midiparser_sci.h +++ b/engines/sci/sound/midiparser_sci.h @@ -60,6 +60,7 @@ public: bool loadMusic(byte *, uint32) { return false; } + bool jumpToOffset(uint32 offset); void sendInitCommands(); void unloadMusic(); void setMasterVolume(byte masterVolume); diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index 8c6d0d6431..fe017868b5 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -518,7 +518,25 @@ void SciMusic::soundPlay(MusicEntry *pSnd) { pSnd->hold = -1; if (pSnd->status == kSoundStopped) - pSnd->pMidiParser->jumpToTick(0); + if (_soundVersion <= SCI_VERSION_0_LATE) { + // SCI0 sound subsystem seems to start at offset 0 + // Not starting at offset 0 for SCI0 games will result + // in glitches (e.g. the intro of LB1 Amiga gets stuck - bug + // #3297883). Refer to MusicEntry::setSignal() in sound/music.cpp. + pSnd->pMidiParser->jumpToOffset(0); + } else { + // SCI1 sound subsystem starts at offset 10 (and also sets loop offset to 0) + // 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 + // isn't set at that point by sierra sci and it would cause the + // castle daventry text to get immediately removed. + // Also Eco Quest 2 Gonzales Dances music (room 530) requires a signal + // to get set exactly at tick 0. We previously didn't handle signals + // on tick 0 for SCI1. Which then resulted in broken dance animations. + // See bug #3037267 + // FIXME: maybe also change looping logic to use offset instead of ticks + pSnd->pMidiParser->jumpToOffset(10); + } else { // Fast forward to the last position and perform associated events when loading pSnd->pMidiParser->jumpToTick(pSnd->ticker, true, true, true); |