aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/sound/music.cpp27
-rw-r--r--engines/sci/sound/music.h2
-rw-r--r--engines/sci/sound/soundcmd.cpp17
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);
}
}