From d2acad39c87183c6b1debfbba1ded5127086557b Mon Sep 17 00:00:00 2001 From: md5 Date: Thu, 3 Mar 2011 12:45:03 +0200 Subject: SCI: Always clear looping and hold before jumpToTick() is called Fixes a crash in LSL3 Amiga --- engines/sci/sound/music.cpp | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'engines') diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index 2331f2f959..a028617e74 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -318,8 +318,21 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) { channelFilterMask = pSnd->soundRes->getChannelFilterMask(_pMidiDrv->getPlayId(), _pMidiDrv->hasRhythmChannel()); pSnd->pMidiParser->mainThreadBegin(); + // loadMusic() below calls jumpToTick. + // Disable sound looping and hold before jumpToTick is called, + // otherwise the song may keep looping forever when it ends in + // jumpToTick (e.g. LSL3, when going left from room 210). + uint16 prevLoop = pSnd->loop; + int16 prevHold = pSnd->hold; + pSnd->loop = 0; + pSnd->hold = -1; + pSnd->pMidiParser->loadMusic(track, pSnd, channelFilterMask, _soundVersion); pSnd->reverb = pSnd->pMidiParser->getSongReverb(); + + // Restore looping and hold + pSnd->loop = prevLoop; + pSnd->hold = prevHold; pSnd->pMidiParser->mainThreadEnd(); _mutex.unlock(); } @@ -434,23 +447,26 @@ void SciMusic::soundPlay(MusicEntry *pSnd) { if (pSnd->status != kSoundPaused) pSnd->pMidiParser->sendInitCommands(); pSnd->pMidiParser->setVolume(pSnd->volume); - if (pSnd->status == kSoundStopped) { + + // Disable sound looping and hold before jumpToTick is called, + // otherwise the song may keep looping forever when it ends in jumpToTick. + // This is needed when loading saved games, or when a game + // stops the same sound twice (e.g. LSL3 Amiga, going left from + // room 210 to talk with Kalalau). Fixes bugs #3083151 and #3106107. + uint16 prevLoop = pSnd->loop; + int16 prevHold = pSnd->hold; + pSnd->loop = 0; + pSnd->hold = -1; + + if (pSnd->status == kSoundStopped) pSnd->pMidiParser->jumpToTick(0); - } else { - // Disable sound looping before fast forwarding to the last position, - // when loading a saved game. Fixes bug #3083151. - uint16 prevLoop = pSnd->loop; - pSnd->loop = 0; - // Same for hold. Fixes bug #3106107. - int16 prevHold = pSnd->hold; - pSnd->hold = -1; + else // Fast forward to the last position and perform associated events when loading pSnd->pMidiParser->jumpToTick(pSnd->ticker, true, true, true); - // Restore looping - pSnd->loop = prevLoop; - // Restore hold - pSnd->hold = prevHold; - } + + // Restore looping and hold + pSnd->loop = prevLoop; + pSnd->hold = prevHold; pSnd->pMidiParser->mainThreadEnd(); _mutex.unlock(); } -- cgit v1.2.3