diff --git a/CHANGELOG.md b/CHANGELOG.md index 310e37d16..f117a09bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ Bug #4867: Arbitrary text after local variable declarations breaks script compilation Bug #4876: AI ratings handling inconsistencies Bug #4877: Startup script executes only on a new game start + Bug #4879: SayDone returns 0 on the frame Say is called Bug #4888: Global variable stray explicit reference calls break script compilation Bug #4896: Title screen music doesn't loop Bug #4902: Using scrollbars in settings causes resolution to change diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 19bbc17d3..77f25f326 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -520,7 +520,7 @@ namespace MWSound Stream *sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())); if(!sound) return; - mActiveSaySounds.insert(std::make_pair(ptr, sound)); + mSaySoundsQueue.emplace(ptr, sound); } float SoundManager::getSaySoundLoudness(const MWWorld::ConstPtr &ptr) const @@ -568,7 +568,15 @@ namespace MWSound void SoundManager::stopSay(const MWWorld::ConstPtr &ptr) { - SaySoundMap::iterator snditer = mActiveSaySounds.find(ptr); + SaySoundMap::iterator snditer = mSaySoundsQueue.find(ptr); + if(snditer != mSaySoundsQueue.end()) + { + mOutput->finishStream(snditer->second); + mUnusedStreams.push_back(snditer->second); + mSaySoundsQueue.erase(snditer); + } + + snditer = mActiveSaySounds.find(ptr); if(snditer != mActiveSaySounds.end()) { mOutput->finishStream(snditer->second); @@ -761,7 +769,10 @@ namespace MWSound for(SoundBufferRefPair &snd : snditer->second) mOutput->finishSound(snd.first); } - SaySoundMap::iterator sayiter = mActiveSaySounds.find(ptr); + SaySoundMap::iterator sayiter = mSaySoundsQueue.find(ptr); + if(sayiter != mSaySoundsQueue.end()) + mOutput->finishStream(sayiter->second); + sayiter = mActiveSaySounds.find(ptr); if(sayiter != mActiveSaySounds.end()) mOutput->finishStream(sayiter->second); } @@ -777,6 +788,12 @@ namespace MWSound } } + for(SaySoundMap::value_type &snd : mSaySoundsQueue) + { + if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell) + mOutput->finishStream(snd.second); + } + for(SaySoundMap::value_type &snd : mActiveSaySounds) { if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell) @@ -986,6 +1003,15 @@ namespace MWSound void SoundManager::updateSounds(float duration) { + // We update active say sounds map for specific actors here + // because for vanilla compatibility we can't do it immediately. + SaySoundMap::iterator queuesayiter = mSaySoundsQueue.begin(); + while (queuesayiter != mSaySoundsQueue.end()) + { + mActiveSaySounds[queuesayiter->first] = queuesayiter->second; + mSaySoundsQueue.erase(queuesayiter++); + } + static float timePassed = 0.0; timePassed += duration; @@ -1187,6 +1213,12 @@ namespace MWSound sound->setBaseVolume(volumeFromType(sound->getPlayType())); mOutput->updateStream(sound); } + for(SaySoundMap::value_type &snd : mSaySoundsQueue) + { + Stream *sound = snd.second; + sound->setBaseVolume(volumeFromType(sound->getPlayType())); + mOutput->updateStream(sound); + } for(Stream *sound : mActiveTracks) { sound->setBaseVolume(volumeFromType(sound->getPlayType())); @@ -1218,7 +1250,16 @@ namespace MWSound mActiveSounds.erase(snditer); mActiveSounds.emplace(updated, std::move(sndlist)); } - SaySoundMap::iterator sayiter = mActiveSaySounds.find(old); + + SaySoundMap::iterator sayiter = mSaySoundsQueue.find(old); + if(sayiter != mSaySoundsQueue.end()) + { + Stream *stream = sayiter->second; + mSaySoundsQueue.erase(sayiter); + mSaySoundsQueue.emplace(updated, stream); + } + + sayiter = mActiveSaySounds.find(old); if(sayiter != mActiveSaySounds.end()) { Stream *stream = sayiter->second; @@ -1311,6 +1352,13 @@ namespace MWSound mUnderwaterSound = nullptr; mNearWaterSound = nullptr; + for(SaySoundMap::value_type &snd : mSaySoundsQueue) + { + mOutput->finishStream(snd.second); + mUnusedStreams.push_back(snd.second); + } + mSaySoundsQueue.clear(); + for(SaySoundMap::value_type &snd : mActiveSaySounds) { mOutput->finishStream(snd.second); diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index d9cf22c32..d0b98ffe4 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -93,6 +93,7 @@ namespace MWSound SoundMap mActiveSounds; typedef std::map SaySoundMap; + SaySoundMap mSaySoundsQueue; SaySoundMap mActiveSaySounds; typedef std::vector TrackList;