diff options
-rw-r--r-- | engines/sci/sound/music.cpp | 27 | ||||
-rw-r--r-- | engines/sci/sound/music.h | 2 | ||||
-rw-r--r-- | engines/sci/sound/soundcmd.cpp | 17 |
3 files changed, 41 insertions, 5 deletions
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index 446e1e0131..5c67cefc40 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -241,17 +241,34 @@ void SciMusic::onTimer() { void SciMusic::soundPlay(MusicEntry *pSnd) { _mutex.lock(); - uint sz = _playList.size(), i; + uint playListCount = _playList.size(); + uint playListNo = playListCount; + bool alreadyPlaying = false; + // searching if sound is already in _playList - for (i = 0; i < sz && _playList[i] != pSnd; i++) - ; - if (i == sz) {// not found + for (uint i = 0; i < playListCount; i++) { + if (_playList[i] == pSnd) + playListNo = i; + if (_playList[i]->status == kSoundPlaying) + alreadyPlaying = true; + } + if (playListNo == playListCount) { // not found _playList.push_back(pSnd); sortPlayList(); } _mutex.unlock(); // unlock to perform mixer-related calls + if ((_soundVersion <= SCI_VERSION_0_LATE) && (alreadyPlaying)) { + // if any music is already playing, SCI0 queues music and plays it after the current music has finished + // done by SoundCommandParser::updateSci0Cues() + // Example of such case: iceman room 14 + // FIXME: this code is supposed to also take a look at priority and pause currently playing sound accordingly + pSnd->isQueued = true; + pSnd->status = kSoundPaused; + return; + } + if (pSnd->pStreamAud && !_pMixer->isSoundHandleActive(pSnd->hCurrentAud)) { if (pSnd->loop > 1) { pSnd->pLoopStream = new Audio::LoopingAudioStream(pSnd->pStreamAud, @@ -444,6 +461,8 @@ MusicEntry::MusicEntry() { soundRes = 0; resourceId = 0; + isQueued = false; + dataInc = 0; ticker = 0; signal = 0; diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h index 159e72b39e..8f08065b99 100644 --- a/engines/sci/sound/music.h +++ b/engines/sci/sound/music.h @@ -71,6 +71,8 @@ public: SoundResource *soundRes; uint16 resourceId; + bool isQueued; // for SCI0 only! + uint16 dataInc; uint16 ticker; uint16 signal; diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index 272d9804e1..925f3b2e1a 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -1049,16 +1049,31 @@ void SoundCommandParser::cmdSuspendSound(reg_t obj, int16 value) { #ifndef USE_OLD_MUSIC_FUNCTIONS void SoundCommandParser::updateSci0Cues() { - Common::StackLock(_music->_mutex); + bool noOnePlaying = true; + MusicEntry *pWaitingForPlay = NULL; + + _music->_mutex.lock(); const MusicList::iterator end = _music->getPlayListEnd(); for (MusicList::iterator i = _music->getPlayListStart(); i != end; ++i) { // Is the sound stopped, and the sound object updated too? If yes, skip // this sound, as SCI0 only allows one active song + if (((*i)->isQueued) && (!pWaitingForPlay)) { + pWaitingForPlay = (*i); + continue; + } if ((*i)->signal == 0 && (*i)->status != kSoundPlaying) continue; cmdUpdateCues((*i)->soundObj, 0); + noOnePlaying = false; + } + _music->_mutex.unlock(); + + if (noOnePlaying && pWaitingForPlay) { + // If there is a queued entry, play it now ffs: SciMusic::soundPlay() + pWaitingForPlay->isQueued = false; + _music->soundPlay(pWaitingForPlay); } } |