From 4c2b694b298af2c1a0decb4c304f0d316a3efe95 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 May 2019 14:55:29 +0300 Subject: [PATCH 1/3] Make SayDone return 1 on the frame speech is started (bug #4879) --- CHANGELOG.md | 1 + apps/openmw/mwsound/soundmanagerimp.cpp | 47 ++++++++++++++++++++++--- apps/openmw/mwsound/soundmanagerimp.hpp | 1 + 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 310e37d16f..f117a09bcb 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 19bbc17d3f..9ae4436f44 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); @@ -1068,8 +1076,15 @@ namespace MWSound ++snditer; } - SaySoundMap::iterator sayiter = mActiveSaySounds.begin(); - while(sayiter != mActiveSaySounds.end()) + SaySoundMap::iterator sayiter = mSaySoundsQueue.begin(); + while (sayiter != mSaySoundsQueue.end()) + { + mActiveSaySounds[sayiter->first] = sayiter->second; + mSaySoundsQueue.erase(sayiter++); + } + + sayiter = mActiveSaySounds.begin(); + while (sayiter != mActiveSaySounds.end()) { MWWorld::ConstPtr ptr = sayiter->first; Stream *sound = sayiter->second; @@ -1187,6 +1202,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 +1239,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 +1341,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 d9cf22c320..d0b98ffe42 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; From c975dab7c34c95222da1e1d9446c675d4daf152b Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 May 2019 18:46:53 +0300 Subject: [PATCH 2/3] Update say sound queue explicitly once per frame --- apps/openmw/mwsound/soundmanagerimp.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 9ae4436f44..2879afb2a7 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -994,6 +994,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; @@ -1076,14 +1085,7 @@ namespace MWSound ++snditer; } - SaySoundMap::iterator sayiter = mSaySoundsQueue.begin(); - while (sayiter != mSaySoundsQueue.end()) - { - mActiveSaySounds[sayiter->first] = sayiter->second; - mSaySoundsQueue.erase(sayiter++); - } - - sayiter = mActiveSaySounds.begin(); + SaySoundMap::iterator sayiter = mActiveSaySounds.begin(); while (sayiter != mActiveSaySounds.end()) { MWWorld::ConstPtr ptr = sayiter->first; From e095d519990a896d022d1ce4f8f2d8da8b7967d5 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 May 2019 19:23:42 +0300 Subject: [PATCH 3/3] More queue handling adjustments --- apps/openmw/mwsound/soundmanagerimp.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 2879afb2a7..77f25f3260 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -769,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); } @@ -785,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) @@ -1086,7 +1095,7 @@ namespace MWSound } SaySoundMap::iterator sayiter = mActiveSaySounds.begin(); - while (sayiter != mActiveSaySounds.end()) + while(sayiter != mActiveSaySounds.end()) { MWWorld::ConstPtr ptr = sayiter->first; Stream *sound = sayiter->second;