LURE: Fix duplicate looping sounds

Under some circumstances, looping sounds could be repeatedly triggered and
multiple copies of the same sound would stack up and consume all the sound
channels. Additionally, this could cause a crash because the code did not deal
well with this situation.
The engine will now check if a sound is already playing before adding it when
loading a savegame. It will also not try to play a sound if not enough channels
are available.
This commit is contained in:
Coen Rampen 2023-11-23 22:08:23 +01:00
parent 2327dfc669
commit 4368a4f69d

View File

@ -114,7 +114,7 @@ void SoundManager::loadFromStream(Common::ReadStream *stream) {
SoundDescResource &rec = soundDescs()[soundIndex];
if ((rec.flags & SF_RESTORE) != 0)
// Requeue the sound for playing
addSound(soundIndex, false);
addSound2(soundIndex);
}
}
}
@ -542,13 +542,14 @@ void SoundManager::musicInterface_Play(uint8 soundNumber, bool isMusic, uint8 nu
}
}
}
if (source == -1)
if (source == -1) {
warning("Insufficient sources to play sound %i", soundNumber);
else
} else {
_sourcesInUse[source] = true;
MidiMusic *sound = new MidiMusic(_driver, soundNum, isMusic,
loop, source, numChannels, soundStart, dataSize, volume);
_playingSounds.push_back(MusicList::value_type(sound));
}
_soundMutex.unlock();
}
@ -801,8 +802,13 @@ void MidiMusic::setVolume(int volume) {
void MidiMusic::playMusic() {
debugC(ERROR_DETAILED, kLureDebugSounds, "MidiMusic::PlayMusic playing sound %d", _soundNumber);
if (Sound.isRoland() && !_isMusic)
_mt32Driver->allocateSourceChannels(_source, _numChannels);
if (Sound.isRoland() && !_isMusic) {
bool result = _mt32Driver->allocateSourceChannels(_source, _numChannels);
if (!result) {
stopMusic();
return;
}
}
_parser->loadMusic(_soundData, _soundSize);
_parser->setTrack(0);
_isPlaying = true;