diff --git a/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioManager.cpp b/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioManager.cpp index b4f530734eb..aea0aef00cc 100644 --- a/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioManager.cpp +++ b/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioManager.cpp @@ -220,6 +220,8 @@ void MiniAudioManager::update() //------------------------------------------------------------------------------------------------- void MiniAudioManager::stopAudio(AudioAffect which) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (BitIsSet(which, AudioAffect_Sound)) ma_sound_group_stop(&m_soundGroup); if (BitIsSet(which, AudioAffect_Sound3D)) @@ -233,6 +235,8 @@ void MiniAudioManager::stopAudio(AudioAffect which) //------------------------------------------------------------------------------------------------- void MiniAudioManager::pauseAudio(AudioAffect which) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (BitIsSet(which, AudioAffect_Sound)) ma_sound_group_stop(&m_soundGroup); if (BitIsSet(which, AudioAffect_Sound3D)) @@ -246,6 +250,8 @@ void MiniAudioManager::pauseAudio(AudioAffect which) //------------------------------------------------------------------------------------------------- void MiniAudioManager::resumeAudio(AudioAffect which) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (BitIsSet(which, AudioAffect_Sound)) ma_sound_group_start(&m_soundGroup); if (BitIsSet(which, AudioAffect_Sound3D)) @@ -486,6 +492,8 @@ void MiniAudioManager::playAudioEvent(AudioEventRTS *event) //------------------------------------------------------------------------------------------------- void MiniAudioManager::stopAudioEvent(AudioHandle handle) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; // Handle special music stop commands @@ -521,6 +529,8 @@ void MiniAudioManager::stopAudioEvent(AudioHandle handle) //------------------------------------------------------------------------------------------------- void MiniAudioManager::killAudioEventImmediately(AudioHandle audioEvent) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; // First look for it in the request list. std::list::iterator ait; for (ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ait++) @@ -551,6 +561,8 @@ void MiniAudioManager::killAudioEventImmediately(AudioHandle audioEvent) //------------------------------------------------------------------------------------------------- void MiniAudioManager::pauseAudioEvent(AudioHandle handle) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; // TODO: implement individual sound pause } @@ -607,6 +619,8 @@ void MiniAudioManager::releasePlayingAudio(PlayingAudio *release) //------------------------------------------------------------------------------------------------- void MiniAudioManager::stopAllAudioImmediately(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; PlayingAudio *playing; @@ -632,6 +646,8 @@ void MiniAudioManager::stopAllAudioImmediately(void) //------------------------------------------------------------------------------------------------- void MiniAudioManager::freeAllMiniAudioHandles(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; ma_engine_stop(&m_engine); } @@ -659,6 +675,8 @@ void MiniAudioManager::adjustPlayingVolume(PlayingAudio *audio) //------------------------------------------------------------------------------------------------- void MiniAudioManager::stopAllSpeech(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ) { PlayingAudio *playing = (*it); @@ -825,6 +843,8 @@ void MiniAudioManager::openDevice(void) //------------------------------------------------------------------------------------------------- void MiniAudioManager::closeDevice(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; // Stop all audio first to prevent use-after-free in audio callbacks stopAllAudioImmediately(); @@ -857,6 +877,8 @@ Bool MiniAudioManager::isCurrentlyPlaying(AudioHandle handle) //------------------------------------------------------------------------------------------------- void MiniAudioManager::notifyOfAudioCompletion(UnsignedInt audioCompleted, UnsignedInt flags) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; PlayingAudio *playing = findPlayingAudioFrom(audioCompleted, flags); if (!playing) return; if (!playing->m_audioEventRTS || !playing->m_audioEventRTS->getAudioEventInfo()) return; @@ -1068,6 +1090,8 @@ Bool MiniAudioManager::isPlayingLowerPriority(AudioEventRTS *event) const //------------------------------------------------------------------------------------------------- Bool MiniAudioManager::killLowestPrioritySoundImmediately(AudioEventRTS *event) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; AudioEventRTS *lowestPriorityEvent = findLowestPrioritySound(event); if (!lowestPriorityEvent) return FALSE; @@ -1086,6 +1110,8 @@ Bool MiniAudioManager::killLowestPrioritySoundImmediately(AudioEventRTS *event) //------------------------------------------------------------------------------------------------- void MiniAudioManager::adjustVolumeOfPlayingAudio(AsciiString eventName, Real newVolume) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; for (auto it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { PlayingAudio *playing = *it; if (playing && playing->m_audioEventRTS && playing->m_audioEventRTS->getEventName() == eventName) { @@ -1098,6 +1124,8 @@ void MiniAudioManager::adjustVolumeOfPlayingAudio(AsciiString eventName, Real ne //------------------------------------------------------------------------------------------------- void MiniAudioManager::removePlayingAudio(AsciiString eventName) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; for (auto it = m_playingSounds.begin(); it != m_playingSounds.end(); ) { PlayingAudio *playing = *it; if (playing && playing->m_audioEventRTS && playing->m_audioEventRTS->getEventName() == eventName) { @@ -1111,6 +1139,8 @@ void MiniAudioManager::removePlayingAudio(AsciiString eventName) //------------------------------------------------------------------------------------------------- void MiniAudioManager::removeAllDisabledAudio(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; for (auto it = m_playingSounds.begin(); it != m_playingSounds.end(); ) { PlayingAudio *playing = *it; if (playing && playing->m_audioEventRTS && playing->m_audioEventRTS->getVolume() == 0.0f) { @@ -1266,6 +1296,8 @@ void MiniAudioManager::setSpeakerSurround(Bool surround) //------------------------------------------------------------------------------------------------- Real MiniAudioManager::getFileLengthMS(AsciiString strToLoad) const { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (strToLoad.isEmpty()) return 0.0f; static ma_vfs_callbacks vfs = {}; @@ -1299,6 +1331,8 @@ Real MiniAudioManager::getFileLengthMS(AsciiString strToLoad) const //------------------------------------------------------------------------------------------------- void MiniAudioManager::closeAnySamplesUsingFile(const void *fileToClose) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; // miniaudio manages file lifecycle internally after decoding } diff --git a/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioStream.cpp b/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioStream.cpp index ea62693330b..b1239e9b557 100644 --- a/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioStream.cpp +++ b/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioStream.cpp @@ -22,6 +22,8 @@ #include "MiniAudioDevice/MiniAudioStream.h" #include "Lib/BaseType.h" +// GeneralsX @bugfix meerzulee 19/07/2026 ScopedFPUGuard for FP env guards on audio entry points (see #215) +#include "GameLogic/FPUControl.h" #include static ma_result MiniAudioStream_read(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead) @@ -71,6 +73,8 @@ MiniAudioStream::~MiniAudioStream() bool MiniAudioStream::bufferData(uint8_t *data, size_t data_size, ma_format format, int samplerate, int channels) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (data_size == 0) return false; std::lock_guard lock(m_mutex); @@ -94,6 +98,8 @@ bool MiniAudioStream::isPlaying() void MiniAudioStream::update() { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; bool shouldCreate = false; { std::lock_guard lock(m_mutex); @@ -109,6 +115,8 @@ void MiniAudioStream::update() void MiniAudioStream::reset() { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (m_sound) { ma_sound_stop(m_sound); ma_sound_uninit(m_sound); @@ -129,6 +137,8 @@ void MiniAudioStream::reset() void MiniAudioStream::play() { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::lock_guard lock(m_mutex); m_playing = true; if (m_sound) ma_sound_start(m_sound); @@ -163,18 +173,24 @@ void MiniAudioStream::createSound() void MiniAudioStream::pause() { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; m_playing = false; if (m_sound) ma_sound_stop(m_sound); } void MiniAudioStream::stop() { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; pause(); reset(); } void MiniAudioStream::setVolume(float vol) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (m_sound) ma_sound_set_volume(m_sound, vol); } diff --git a/Core/GameEngineDevice/Source/OpenALAudioDevice/OpenALAudioManager.cpp b/Core/GameEngineDevice/Source/OpenALAudioDevice/OpenALAudioManager.cpp index 0b1e3f37b15..9aff5c45cea 100644 --- a/Core/GameEngineDevice/Source/OpenALAudioDevice/OpenALAudioManager.cpp +++ b/Core/GameEngineDevice/Source/OpenALAudioDevice/OpenALAudioManager.cpp @@ -544,6 +544,8 @@ void OpenALAudioManager::update() //------------------------------------------------------------------------------------------------- void OpenALAudioManager::stopAudio(AudioAffect which) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; // All we really need to do is: // 1) Remove the EOS callback. // 2) Stop the sample, (so that when we later unload it, bad stuff doesn't happen) @@ -599,6 +601,8 @@ void OpenALAudioManager::stopAudio(AudioAffect which) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::pauseAudio(AudioAffect which) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; PlayingAudio* playing = NULL; @@ -665,6 +669,8 @@ void OpenALAudioManager::pauseAudio(AudioAffect which) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::resumeAudio(AudioAffect which) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; PlayingAudio* playing = NULL; @@ -996,6 +1002,8 @@ void OpenALAudioManager::playAudioEvent(AudioEventRTS* event) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::stopAudioEvent(AudioHandle handle) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; #ifdef INTENSIVE_AUDIO_DEBUG DEBUG_LOG(("OPENAL (%d) - Processing stop request: %d\n", TheGameLogic->getFrame(), handle)); #endif @@ -1073,6 +1081,8 @@ void OpenALAudioManager::stopAudioEvent(AudioHandle handle) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::killAudioEventImmediately(AudioHandle audioEvent) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; //First look for it in the request list. std::list::iterator ait; for (ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ait++) @@ -1144,6 +1154,8 @@ void OpenALAudioManager::killAudioEventImmediately(AudioHandle audioEvent) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::pauseAudioEvent(AudioHandle handle) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; // pause audio } @@ -1219,6 +1231,8 @@ void OpenALAudioManager::releasePlayingAudio(PlayingAudio* release) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::stopAllAudioImmediately(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; PlayingAudio* playing; @@ -1275,6 +1289,8 @@ void OpenALAudioManager::stopAllAudioImmediately(void) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::freeAllOpenALHandles(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; // First, we need to ensure that we don't have any sample handles open. To that end, we must stop // all of our currently playing audio. stopAllAudioImmediately(); @@ -1341,6 +1357,8 @@ void OpenALAudioManager::adjustPlayingVolume(PlayingAudio* audio) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::stopAllSpeech(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; PlayingAudio* playing; for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ) { @@ -1561,6 +1579,8 @@ void OpenALAudioManager::openDevice(void) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::closeDevice(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; unselectProvider(); alcMakeContextCurrent(nullptr); @@ -1614,6 +1634,8 @@ Bool OpenALAudioManager::isCurrentlyPlaying(AudioHandle handle) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::notifyOfAudioCompletion(UnsignedInt audioCompleted, UnsignedInt flags) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; PlayingAudio* playing = findPlayingAudioFrom(audioCompleted, flags); if (!playing) { DEBUG_CRASH(("Audio has completed playing, but we can't seem to find it. - jkmcd")); @@ -1749,6 +1771,8 @@ UnsignedInt OpenALAudioManager::getProviderIndex(AsciiString providerName) const //------------------------------------------------------------------------------------------------- void OpenALAudioManager::selectProvider(UnsignedInt providerNdx) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (!isOn(AudioAffect_Sound3D)) { return; @@ -1849,6 +1873,8 @@ void OpenALAudioManager::selectProvider(UnsignedInt providerNdx) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::unselectProvider(void) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (!(isOn(AudioAffect_Sound3D) && isValidProvider())) { return; } @@ -2159,6 +2185,8 @@ Bool OpenALAudioManager::isPlayingLowerPriority(AudioEventRTS* event) const //------------------------------------------------------------------------------------------------- Bool OpenALAudioManager::killLowestPrioritySoundImmediately(AudioEventRTS* event) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; //Actually, we want to kill the LOWEST PRIORITY SOUND, not the first "lower" priority //sound we find, because it could easily be AudioEventRTS* lowestPriorityEvent = findLowestPrioritySound(event); @@ -2211,6 +2239,8 @@ Bool OpenALAudioManager::killLowestPrioritySoundImmediately(AudioEventRTS* event //------------------------------------------------------------------------------------------------- void OpenALAudioManager::adjustVolumeOfPlayingAudio(AsciiString eventName, Real newVolume) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; PlayingAudio* playing = NULL; @@ -2249,6 +2279,8 @@ void OpenALAudioManager::adjustVolumeOfPlayingAudio(AsciiString eventName, Real //------------------------------------------------------------------------------------------------- void OpenALAudioManager::removePlayingAudio(AsciiString eventName) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; PlayingAudio* playing = NULL; @@ -2298,6 +2330,8 @@ void OpenALAudioManager::removePlayingAudio(AsciiString eventName) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::removeAllDisabledAudio() { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; std::list::iterator it; PlayingAudio* playing = NULL; @@ -2746,6 +2780,8 @@ void OpenALAudioManager::setSpeakerSurround(Bool surround) //------------------------------------------------------------------------------------------------- Real OpenALAudioManager::getFileLengthMS(AsciiString strToLoad) const { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (strToLoad.isEmpty()) { return 0.0f; } @@ -2763,6 +2799,8 @@ Real OpenALAudioManager::getFileLengthMS(AsciiString strToLoad) const //------------------------------------------------------------------------------------------------- void OpenALAudioManager::closeAnySamplesUsingFile(const void* fileToClose) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; ALuint bufferHandle = (ALuint)(uintptr_t)fileToClose; if (!bufferHandle) { return; @@ -3110,6 +3148,8 @@ void OpenALAudioManager::releaseHandleForBink(void) //------------------------------------------------------------------------------------------------- void OpenALAudioManager::friend_forcePlayAudioEventRTS(const AudioEventRTS* eventToPlay) { + // GeneralsX @bugfix meerzulee 19/07/2026 FP env guard for audio entry point (see #215) + ScopedFPUGuard fpuGuard; if (!eventToPlay->getAudioEventInfo()) { getInfoForAudioEvent(eventToPlay); if (!eventToPlay->getAudioEventInfo()) {