From 3df676173119729ef3163e902a75fd3aae00e57b Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Mon, 21 Jul 2025 22:27:19 +0200 Subject: [PATCH 1/2] [GEN] Backport all Audio changes, incl. localization lookup changes in AudioEventRTS from Zero Hour (#1330) --- .../Code/GameEngine/Include/Common/GameAudio.h | 1 + .../Code/GameEngine/Include/Common/MiscAudio.h | 5 ++++- .../Source/Common/Audio/AudioEventRTS.cpp | 17 ++++++++++------- .../Source/Common/INI/INIMiscAudio.cpp | 4 +++- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Generals/Code/GameEngine/Include/Common/GameAudio.h b/Generals/Code/GameEngine/Include/Common/GameAudio.h index 1e73606c11b..baf3da6bad6 100644 --- a/Generals/Code/GameEngine/Include/Common/GameAudio.h +++ b/Generals/Code/GameEngine/Include/Common/GameAudio.h @@ -316,6 +316,7 @@ class AudioManager : public SubsystemInterface // For tracking purposes virtual AudioHandle allocateNewHandle( void ); + // Remove all AudioEventInfo's with the m_isLevelSpecific flag virtual void removeLevelSpecificAudioEventInfos( void ); diff --git a/Generals/Code/GameEngine/Include/Common/MiscAudio.h b/Generals/Code/GameEngine/Include/Common/MiscAudio.h index 69b09a05648..63d2b783335 100644 --- a/Generals/Code/GameEngine/Include/Common/MiscAudio.h +++ b/Generals/Code/GameEngine/Include/Common/MiscAudio.h @@ -69,8 +69,11 @@ struct MiscAudio AudioEventRTS m_crateMoney; ///< When money crate is picked up. AudioEventRTS m_unitPromoted; ///< Unit is promoted. AudioEventRTS m_repairSparks; ///< Battle drone repairs unit. + AudioEventRTS m_sabotageShutDownBuilding; ///< When Saboteur hits a building + AudioEventRTS m_sabotageResetTimerBuilding; ///< When Saboteur hits a building AudioEventRTS m_aircraftWheelScreech; ///< When a jet lands on a runway. }; -#endif /* _MISCAUDIO_H_ */ \ No newline at end of file +#endif /* _MISCAUDIO_H_ */ + diff --git a/Generals/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp b/Generals/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp index c80bbe5830d..4b7eebd6b84 100644 --- a/Generals/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp +++ b/Generals/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp @@ -800,20 +800,23 @@ AsciiString AudioEventRTS::generateFilenameExtension( AudioType audioTypeToPlay //------------------------------------------------------------------------------------------------- void AudioEventRTS::adjustForLocalization(AsciiString &strToAdjust) { - if (TheFileSystem->doesFileExist(strToAdjust.str())) - { - return; - } - const char *str = strToAdjust.reverseFind('\\'); if (!str) { return; } + // try the localized version first so that we're guarenteed to get it + // even if the generic data directory holds a version of the file + AsciiString localizedFilePath = generateFilenamePrefix(m_eventInfo->m_soundType, TRUE); AsciiString filename = str; + localizedFilePath.concat(filename); + + if (TheFileSystem->doesFileExist(localizedFilePath.str())) { + strToAdjust = localizedFilePath; + } + // else there was no localized version, so leave the path we received unchanged - strToAdjust = generateFilenamePrefix(m_eventInfo->m_soundType, TRUE); - strToAdjust.concat(filename); + return; } //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp b/Generals/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp index ef775ebdb3f..d189db39bdb 100644 --- a/Generals/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp +++ b/Generals/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp @@ -63,7 +63,9 @@ const FieldParse MiscAudio::m_fieldParseTable[] = { "CrateMoney", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_crateMoney ) }, { "UnitPromoted", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_unitPromoted ) }, { "RepairSparks", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_repairSparks ) }, - { "AircraftWheelScreech", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_aircraftWheelScreech ) }, + { "SabotageShutDownBuilding", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_sabotageShutDownBuilding ) }, + { "SabotageResetTimeBuilding", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_sabotageResetTimerBuilding ) }, + { "AircraftWheelScreech", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_aircraftWheelScreech ) }, { 0, 0, 0, 0 } }; From f4663b4fb0789e91014ea6ef8cb7a460457e65db Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Mon, 21 Jul 2025 22:49:22 +0200 Subject: [PATCH 2/2] [CORE] Move Audio files to Core (#1330) --- Core/GameEngine/CMakeLists.txt | 46 +- .../GameEngine/Include/Common/AudioAffect.h | 0 .../Include/Common/AudioEventInfo.h | 0 .../GameEngine/Include/Common/AudioEventRTS.h | 0 .../Include/Common/AudioHandleSpecialValues.h | 0 .../Include/Common/AudioRandomValue.h | 0 .../GameEngine/Include/Common/AudioRequest.h | 0 .../GameEngine/Include/Common/AudioSettings.h | 0 .../Include/Common/DynamicAudioEventInfo.h | 0 .../GameEngine/Include/Common/GameAudio.h | 0 .../GameEngine/Include/Common/GameMusic.h | 0 .../GameEngine/Include/Common/GameSounds.h | 0 .../GameEngine/Include/Common/MiscAudio.h | 0 .../GameEngine/Include/Common/simpleplayer.h | 0 .../GameEngine/Include/Common/urllaunch.h | 0 .../Source/Common/Audio/AudioEventRTS.cpp | 0 .../Source/Common/Audio/AudioRequest.cpp | 0 .../Common/Audio/DynamicAudioEventInfo.cpp | 0 .../Source/Common/Audio/GameAudio.cpp | 0 .../Source/Common/Audio/GameMusic.cpp | 0 .../Source/Common/Audio/GameSounds.cpp | 0 .../Source/Common/Audio/simpleplayer.cpp | 0 .../Source/Common/Audio/urllaunch.cpp | 0 .../Source/Common/INI/INIAudioEventInfo.cpp | 0 .../Source/Common/INI/INIMiscAudio.cpp | 0 .../System/Debug}/AudioDebugDisplay.cpp | 0 Core/GameEngineDevice/CMakeLists.txt | 4 +- .../MilesAudioDevice/MilesAudioManager.h | 0 .../MilesAudioDevice/MilesAudioManager.cpp | 0 Generals/Code/GameEngine/CMakeLists.txt | 40 +- .../GameEngine/Include/Common/AudioAffect.h | 48 - .../Include/Common/AudioEventInfo.h | 137 - .../GameEngine/Include/Common/AudioEventRTS.h | 217 -- .../Include/Common/AudioHandleSpecialValues.h | 45 - .../Include/Common/AudioRandomValue.h | 47 - .../GameEngine/Include/Common/AudioRequest.h | 61 - .../GameEngine/Include/Common/AudioSettings.h | 94 - .../GameEngine/Include/Common/GameAudio.h | 428 --- .../GameEngine/Include/Common/GameMusic.h | 118 - .../GameEngine/Include/Common/GameSounds.h | 103 - .../GameEngine/Include/Common/MiscAudio.h | 79 - .../GameEngine/Include/Common/simpleplayer.h | 123 - .../GameEngine/Include/Common/urllaunch.h | 27 - .../Source/Common/Audio/AudioEventRTS.cpp | 847 ----- .../Source/Common/Audio/AudioRequest.cpp | 34 - .../Source/Common/Audio/GameAudio.cpp | 1166 ------ .../Source/Common/Audio/GameMusic.cpp | 126 - .../Source/Common/Audio/GameSounds.cpp | 329 -- .../Source/Common/Audio/simpleplayer.cpp | 708 ---- .../Source/Common/Audio/urllaunch.cpp | 338 -- .../Source/Common/INI/INIAudioEventInfo.cpp | 215 -- .../Source/Common/INI/INIMiscAudio.cpp | 78 - .../Debug Displayers/AudioDebugDisplay.cpp | 114 - Generals/Code/GameEngineDevice/CMakeLists.txt | 4 +- .../MilesAudioDevice/MilesAudioManager.h | 332 -- .../MilesAudioDevice/MilesAudioManager.cpp | 3386 ----------------- GeneralsMD/Code/GameEngine/CMakeLists.txt | 50 +- .../Code/GameEngineDevice/CMakeLists.txt | 4 +- 58 files changed, 75 insertions(+), 9273 deletions(-) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/AudioAffect.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/AudioEventInfo.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/AudioEventRTS.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/AudioHandleSpecialValues.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/AudioRandomValue.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/AudioRequest.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/AudioSettings.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/DynamicAudioEventInfo.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/GameAudio.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/GameMusic.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/GameSounds.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/MiscAudio.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/simpleplayer.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Include/Common/urllaunch.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/Audio/AudioEventRTS.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/Audio/AudioRequest.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/Audio/DynamicAudioEventInfo.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/Audio/GameAudio.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/Audio/GameMusic.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/Audio/GameSounds.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/Audio/simpleplayer.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/Audio/urllaunch.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/Common/INI/INIMiscAudio.cpp (100%) rename {GeneralsMD/Code/GameEngine/Source/GameClient/System/Debug Displayers => Core/GameEngine/Source/GameClient/System/Debug}/AudioDebugDisplay.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp (100%) delete mode 100644 Generals/Code/GameEngine/Include/Common/AudioAffect.h delete mode 100644 Generals/Code/GameEngine/Include/Common/AudioEventInfo.h delete mode 100644 Generals/Code/GameEngine/Include/Common/AudioEventRTS.h delete mode 100644 Generals/Code/GameEngine/Include/Common/AudioHandleSpecialValues.h delete mode 100644 Generals/Code/GameEngine/Include/Common/AudioRandomValue.h delete mode 100644 Generals/Code/GameEngine/Include/Common/AudioRequest.h delete mode 100644 Generals/Code/GameEngine/Include/Common/AudioSettings.h delete mode 100644 Generals/Code/GameEngine/Include/Common/GameAudio.h delete mode 100644 Generals/Code/GameEngine/Include/Common/GameMusic.h delete mode 100644 Generals/Code/GameEngine/Include/Common/GameSounds.h delete mode 100644 Generals/Code/GameEngine/Include/Common/MiscAudio.h delete mode 100644 Generals/Code/GameEngine/Include/Common/simpleplayer.h delete mode 100644 Generals/Code/GameEngine/Include/Common/urllaunch.h delete mode 100644 Generals/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp delete mode 100644 Generals/Code/GameEngine/Source/Common/Audio/AudioRequest.cpp delete mode 100644 Generals/Code/GameEngine/Source/Common/Audio/GameAudio.cpp delete mode 100644 Generals/Code/GameEngine/Source/Common/Audio/GameMusic.cpp delete mode 100644 Generals/Code/GameEngine/Source/Common/Audio/GameSounds.cpp delete mode 100644 Generals/Code/GameEngine/Source/Common/Audio/simpleplayer.cpp delete mode 100644 Generals/Code/GameEngine/Source/Common/Audio/urllaunch.cpp delete mode 100644 Generals/Code/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp delete mode 100644 Generals/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp delete mode 100644 Generals/Code/GameEngine/Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp delete mode 100644 Generals/Code/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h delete mode 100644 Generals/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt index eed57fc7e28..8a7110946d6 100644 --- a/Core/GameEngine/CMakeLists.txt +++ b/Core/GameEngine/CMakeLists.txt @@ -4,13 +4,13 @@ set(GAMEENGINE_SRC Include/Common/ArchiveFile.h Include/Common/ArchiveFileSystem.h Include/Common/AsciiString.h -# Include/Common/AudioAffect.h -# Include/Common/AudioEventInfo.h -# Include/Common/AudioEventRTS.h -# Include/Common/AudioHandleSpecialValues.h -# Include/Common/AudioRandomValue.h -# Include/Common/AudioRequest.h -# Include/Common/AudioSettings.h + Include/Common/AudioAffect.h + Include/Common/AudioEventInfo.h + Include/Common/AudioEventRTS.h + Include/Common/AudioHandleSpecialValues.h + Include/Common/AudioRandomValue.h + Include/Common/AudioRequest.h + Include/Common/AudioSettings.h # Include/Common/BattleHonors.h # Include/Common/BezFwdIterator.h # Include/Common/BezierSegment.h @@ -33,21 +33,21 @@ set(GAMEENGINE_SRC # Include/Common/DisabledTypes.h # Include/Common/DiscreteCircle.h # Include/Common/DrawModule.h -# Include/Common/DynamicAudioEventInfo.h + Include/Common/DynamicAudioEventInfo.h # Include/Common/encrypt.h # Include/Common/Energy.h # Include/Common/Errors.h Include/Common/file.h Include/Common/FileSystem.h # Include/Common/FunctionLexicon.h -# Include/Common/GameAudio.h + Include/Common/GameAudio.h # Include/Common/GameCommon.h Include/Common/GameDefines.h # Include/Common/GameEngine.h # Include/Common/GameLOD.h # Include/Common/GameMemory.h -# Include/Common/GameMusic.h -# Include/Common/GameSounds.h + Include/Common/GameMusic.h + Include/Common/GameSounds.h # Include/Common/GameSpyMiscPreferences.h # Include/Common/GameState.h # Include/Common/GameStateMap.h @@ -69,7 +69,7 @@ set(GAMEENGINE_SRC # Include/Common/MapReaderWriterInfo.h # Include/Common/MessageStream.h # Include/Common/MiniLog.h -# Include/Common/MiscAudio.h + Include/Common/MiscAudio.h # Include/Common/MissionStats.h # Include/Common/ModelState.h # Include/Common/Module.h @@ -100,7 +100,7 @@ set(GAMEENGINE_SRC # Include/Common/Science.h # Include/Common/ScopedMutex.h # Include/Common/ScoreKeeper.h -# Include/Common/simpleplayer.h + #Include/Common/simpleplayer.h # unused # Include/Common/SkirmishBattleHonors.h # Include/Common/SkirmishPreferences.h # Include/Common/Snapshot.h @@ -127,7 +127,7 @@ set(GAMEENGINE_SRC Include/Common/UnicodeString.h # Include/Common/UnitTimings.h # Include/Common/Upgrade.h -# Include/Common/urllaunch.h + #Include/Common/urllaunch.h # unused # Include/Common/UserPreferences.h # Include/Common/version.h # Include/Common/WellKnownKeys.h @@ -552,12 +552,12 @@ set(GAMEENGINE_SRC # Include/GameNetwork/WOLBrowser/FEBDispatch.h # Include/GameNetwork/WOLBrowser/WebBrowser.h # Include/Precompiled/PreRTS.h -# Source/Common/Audio/AudioEventRTS.cpp -# Source/Common/Audio/AudioRequest.cpp -# Source/Common/Audio/DynamicAudioEventInfo.cpp -# Source/Common/Audio/GameAudio.cpp -# Source/Common/Audio/GameMusic.cpp -# Source/Common/Audio/GameSounds.cpp + Source/Common/Audio/AudioEventRTS.cpp + Source/Common/Audio/AudioRequest.cpp + Source/Common/Audio/DynamicAudioEventInfo.cpp + Source/Common/Audio/GameAudio.cpp + Source/Common/Audio/GameMusic.cpp + Source/Common/Audio/GameSounds.cpp #Source/Common/Audio/simpleplayer.cpp # unused #Source/Common/Audio/urllaunch.cpp # unused # Source/Common/Bezier/BezFwdIterator.cpp @@ -576,7 +576,7 @@ set(GAMEENGINE_SRC # Source/Common/INI/INI.cpp # Source/Common/INI/INIAiData.cpp # Source/Common/INI/INIAnimation.cpp -# Source/Common/INI/INIAudioEventInfo.cpp + Source/Common/INI/INIAudioEventInfo.cpp # Source/Common/INI/INICommandButton.cpp # Source/Common/INI/INICommandSet.cpp # Source/Common/INI/INIControlBarScheme.cpp @@ -587,7 +587,7 @@ set(GAMEENGINE_SRC # Source/Common/INI/INIMapCache.cpp # Source/Common/INI/INIMapData.cpp # Source/Common/INI/INIMappedImage.cpp -# Source/Common/INI/INIMiscAudio.cpp + Source/Common/INI/INIMiscAudio.cpp # Source/Common/INI/INIModel.cpp # Source/Common/INI/INIMultiplayer.cpp # Source/Common/INI/INIObject.cpp @@ -815,7 +815,7 @@ set(GAMEENGINE_SRC # Source/GameClient/Statistics.cpp # Source/GameClient/System/Anim2D.cpp # Source/GameClient/System/CampaignManager.cpp -# "Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp" + Source/GameClient/System/Debug/AudioDebugDisplay.cpp # Source/GameClient/System/DebugDisplay.cpp # Source/GameClient/System/Image.cpp # Source/GameClient/System/ParticleSys.cpp diff --git a/GeneralsMD/Code/GameEngine/Include/Common/AudioAffect.h b/Core/GameEngine/Include/Common/AudioAffect.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/AudioAffect.h rename to Core/GameEngine/Include/Common/AudioAffect.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/AudioEventInfo.h b/Core/GameEngine/Include/Common/AudioEventInfo.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/AudioEventInfo.h rename to Core/GameEngine/Include/Common/AudioEventInfo.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/AudioEventRTS.h b/Core/GameEngine/Include/Common/AudioEventRTS.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/AudioEventRTS.h rename to Core/GameEngine/Include/Common/AudioEventRTS.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/AudioHandleSpecialValues.h b/Core/GameEngine/Include/Common/AudioHandleSpecialValues.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/AudioHandleSpecialValues.h rename to Core/GameEngine/Include/Common/AudioHandleSpecialValues.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/AudioRandomValue.h b/Core/GameEngine/Include/Common/AudioRandomValue.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/AudioRandomValue.h rename to Core/GameEngine/Include/Common/AudioRandomValue.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/AudioRequest.h b/Core/GameEngine/Include/Common/AudioRequest.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/AudioRequest.h rename to Core/GameEngine/Include/Common/AudioRequest.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/AudioSettings.h b/Core/GameEngine/Include/Common/AudioSettings.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/AudioSettings.h rename to Core/GameEngine/Include/Common/AudioSettings.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/DynamicAudioEventInfo.h b/Core/GameEngine/Include/Common/DynamicAudioEventInfo.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/DynamicAudioEventInfo.h rename to Core/GameEngine/Include/Common/DynamicAudioEventInfo.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameAudio.h b/Core/GameEngine/Include/Common/GameAudio.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/GameAudio.h rename to Core/GameEngine/Include/Common/GameAudio.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameMusic.h b/Core/GameEngine/Include/Common/GameMusic.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/GameMusic.h rename to Core/GameEngine/Include/Common/GameMusic.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameSounds.h b/Core/GameEngine/Include/Common/GameSounds.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/GameSounds.h rename to Core/GameEngine/Include/Common/GameSounds.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/MiscAudio.h b/Core/GameEngine/Include/Common/MiscAudio.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/MiscAudio.h rename to Core/GameEngine/Include/Common/MiscAudio.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/simpleplayer.h b/Core/GameEngine/Include/Common/simpleplayer.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/simpleplayer.h rename to Core/GameEngine/Include/Common/simpleplayer.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/urllaunch.h b/Core/GameEngine/Include/Common/urllaunch.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/urllaunch.h rename to Core/GameEngine/Include/Common/urllaunch.h diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp b/Core/GameEngine/Source/Common/Audio/AudioEventRTS.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp rename to Core/GameEngine/Source/Common/Audio/AudioEventRTS.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Audio/AudioRequest.cpp b/Core/GameEngine/Source/Common/Audio/AudioRequest.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/Audio/AudioRequest.cpp rename to Core/GameEngine/Source/Common/Audio/AudioRequest.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Audio/DynamicAudioEventInfo.cpp b/Core/GameEngine/Source/Common/Audio/DynamicAudioEventInfo.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/Audio/DynamicAudioEventInfo.cpp rename to Core/GameEngine/Source/Common/Audio/DynamicAudioEventInfo.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Audio/GameAudio.cpp b/Core/GameEngine/Source/Common/Audio/GameAudio.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/Audio/GameAudio.cpp rename to Core/GameEngine/Source/Common/Audio/GameAudio.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Audio/GameMusic.cpp b/Core/GameEngine/Source/Common/Audio/GameMusic.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/Audio/GameMusic.cpp rename to Core/GameEngine/Source/Common/Audio/GameMusic.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Audio/GameSounds.cpp b/Core/GameEngine/Source/Common/Audio/GameSounds.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/Audio/GameSounds.cpp rename to Core/GameEngine/Source/Common/Audio/GameSounds.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Audio/simpleplayer.cpp b/Core/GameEngine/Source/Common/Audio/simpleplayer.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/Audio/simpleplayer.cpp rename to Core/GameEngine/Source/Common/Audio/simpleplayer.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Audio/urllaunch.cpp b/Core/GameEngine/Source/Common/Audio/urllaunch.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/Audio/urllaunch.cpp rename to Core/GameEngine/Source/Common/Audio/urllaunch.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp b/Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp rename to Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp b/Core/GameEngine/Source/Common/INI/INIMiscAudio.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp rename to Core/GameEngine/Source/Common/INI/INIMiscAudio.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp b/Core/GameEngine/Source/GameClient/System/Debug/AudioDebugDisplay.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp rename to Core/GameEngine/Source/GameClient/System/Debug/AudioDebugDisplay.cpp diff --git a/Core/GameEngineDevice/CMakeLists.txt b/Core/GameEngineDevice/CMakeLists.txt index ee4556c3329..9996b8a8eac 100644 --- a/Core/GameEngineDevice/CMakeLists.txt +++ b/Core/GameEngineDevice/CMakeLists.txt @@ -1,5 +1,5 @@ set(GAMEENGINEDEVICE_SRC -# Include/MilesAudioDevice/MilesAudioManager.h + Include/MilesAudioDevice/MilesAudioManager.h # Include/VideoDevice/Bink/BinkVideoPlayer.h # Include/W3DDevice/Common/W3DConvert.h # Include/W3DDevice/Common/W3DFunctionLexicon.h @@ -90,7 +90,7 @@ set(GAMEENGINEDEVICE_SRC # Include/Win32Device/GameClient/Win32DIKeyboard.h # Include/Win32Device/GameClient/Win32DIMouse.h # Include/Win32Device/GameClient/Win32Mouse.h -# Source/MilesAudioDevice/MilesAudioManager.cpp + Source/MilesAudioDevice/MilesAudioManager.cpp # Source/VideoDevice/Bink/BinkVideoPlayer.cpp # Source/W3DDevice/Common/System/W3DFunctionLexicon.cpp # Source/W3DDevice/Common/System/W3DRadar.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h b/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h rename to Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h diff --git a/GeneralsMD/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp rename to Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp diff --git a/Generals/Code/GameEngine/CMakeLists.txt b/Generals/Code/GameEngine/CMakeLists.txt index 7ce03891810..c0d605965bd 100644 --- a/Generals/Code/GameEngine/CMakeLists.txt +++ b/Generals/Code/GameEngine/CMakeLists.txt @@ -3,13 +3,13 @@ set(GAMEENGINE_SRC # Include/Common/ArchiveFile.h # Include/Common/ArchiveFileSystem.h # Include/Common/AsciiString.h - Include/Common/AudioAffect.h - Include/Common/AudioEventInfo.h - Include/Common/AudioEventRTS.h - Include/Common/AudioHandleSpecialValues.h - Include/Common/AudioRandomValue.h - Include/Common/AudioRequest.h - Include/Common/AudioSettings.h +# Include/Common/AudioAffect.h +# Include/Common/AudioEventInfo.h +# Include/Common/AudioEventRTS.h +# Include/Common/AudioHandleSpecialValues.h +# Include/Common/AudioRandomValue.h +# Include/Common/AudioRequest.h +# Include/Common/AudioSettings.h Include/Common/BattleHonors.h Include/Common/BezFwdIterator.h Include/Common/BezierSegment.h @@ -37,14 +37,14 @@ set(GAMEENGINE_SRC # Include/Common/file.h # Include/Common/FileSystem.h Include/Common/FunctionLexicon.h - Include/Common/GameAudio.h +# Include/Common/GameAudio.h Include/Common/GameCommon.h # Include/Common/GameDefines.h Include/Common/GameEngine.h Include/Common/GameLOD.h Include/Common/GameMemory.h - Include/Common/GameMusic.h - Include/Common/GameSounds.h +# Include/Common/GameMusic.h +# Include/Common/GameSounds.h Include/Common/GameSpyMiscPreferences.h Include/Common/GameState.h Include/Common/GameStateMap.h @@ -66,7 +66,7 @@ set(GAMEENGINE_SRC Include/Common/MapReaderWriterInfo.h Include/Common/MessageStream.h Include/Common/MiniLog.h - Include/Common/MiscAudio.h +# Include/Common/MiscAudio.h Include/Common/MissionStats.h Include/Common/ModelState.h Include/Common/Module.h @@ -512,11 +512,13 @@ set(GAMEENGINE_SRC Include/GameNetwork/WOLBrowser/FEBDispatch.h Include/GameNetwork/WOLBrowser/WebBrowser.h Include/Precompiled/PreRTS.h - Source/Common/Audio/AudioEventRTS.cpp - Source/Common/Audio/AudioRequest.cpp - Source/Common/Audio/GameAudio.cpp - Source/Common/Audio/GameMusic.cpp - Source/Common/Audio/GameSounds.cpp +# Source/Common/Audio/AudioEventRTS.cpp +# Source/Common/Audio/AudioRequest.cpp +# Source/Common/Audio/GameAudio.cpp +# Source/Common/Audio/GameMusic.cpp +# Source/Common/Audio/GameSounds.cpp + #Source/Common/Audio/simpleplayer.cpp # unused + #Source/Common/Audio/urllaunch.cpp # unused Source/Common/Bezier/BezFwdIterator.cpp Source/Common/Bezier/BezierSegment.cpp Source/Common/BitFlags.cpp @@ -533,7 +535,7 @@ set(GAMEENGINE_SRC Source/Common/INI/INI.cpp Source/Common/INI/INIAiData.cpp Source/Common/INI/INIAnimation.cpp - Source/Common/INI/INIAudioEventInfo.cpp +# Source/Common/INI/INIAudioEventInfo.cpp Source/Common/INI/INICommandButton.cpp Source/Common/INI/INICommandSet.cpp Source/Common/INI/INIControlBarScheme.cpp @@ -544,7 +546,7 @@ set(GAMEENGINE_SRC Source/Common/INI/INIMapCache.cpp Source/Common/INI/INIMapData.cpp Source/Common/INI/INIMappedImage.cpp - Source/Common/INI/INIMiscAudio.cpp +# Source/Common/INI/INIMiscAudio.cpp Source/Common/INI/INIModel.cpp Source/Common/INI/INIMultiplayer.cpp Source/Common/INI/INIObject.cpp @@ -766,7 +768,7 @@ set(GAMEENGINE_SRC Source/GameClient/Statistics.cpp Source/GameClient/System/Anim2D.cpp Source/GameClient/System/CampaignManager.cpp - "Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp" +# "Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp" Source/GameClient/System/DebugDisplay.cpp Source/GameClient/System/Image.cpp Source/GameClient/System/ParticleSys.cpp diff --git a/Generals/Code/GameEngine/Include/Common/AudioAffect.h b/Generals/Code/GameEngine/Include/Common/AudioAffect.h deleted file mode 100644 index 6613abaef42..00000000000 --- a/Generals/Code/GameEngine/Include/Common/AudioAffect.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// EA Pacific -// John McDonald, Jr -// Do not distribute -#pragma once - -#ifndef _AUDIOAFFECT_H_ -#define _AUDIOAFFECT_H_ - -#include - -// if it is set by the options panel, use the system setting parameter. Otherwise, this will be -// appended to whatever the current system volume is. -enum AudioAffect CPP_11(: Int) -{ - AudioAffect_Music = 0x01, - AudioAffect_Sound = 0x02, - AudioAffect_Sound3D = 0x04, - AudioAffect_Speech = 0x08, - AudioAffect_All = (AudioAffect_Music | AudioAffect_Sound | AudioAffect_Sound3D | AudioAffect_Speech), - - AudioAffect_SystemSetting = 0x10, -}; - -#endif // _AUDIOAFFECT_H_ diff --git a/Generals/Code/GameEngine/Include/Common/AudioEventInfo.h b/Generals/Code/GameEngine/Include/Common/AudioEventInfo.h deleted file mode 100644 index a9924df3179..00000000000 --- a/Generals/Code/GameEngine/Include/Common/AudioEventInfo.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: AudioEventInfo.h ///////////////////////////////////////////////////////////////////////// -// AudioEventInfo structure -// Author: John K. McDonald, March 2002 - -#pragma once -#ifndef _H_AUDIOEVENTINFO_ -#define _H_AUDIOEVENTINFO_ - -#include "Common/AsciiString.h" -#include "Common/GameMemory.h" -#include "Common/STLTypedefs.h" - -// DEFINES -#define NO_INTENSIVE_AUDIO_DEBUG - -// FORWARD DECLARATIONS /////////////////////////////////////////////////////////////////////////// -struct FieldParse; - -// USEFUL DECLARATIONS //////////////////////////////////////////////////////////////////////////// -enum AudioType CPP_11(: Int) -{ - AT_Music, - AT_Streaming, - AT_SoundEffect -}; - -extern const char *theAudioPriorityNames[]; -enum AudioPriority CPP_11(: Int) -{ - AP_LOWEST, - AP_LOW, - AP_NORMAL, - AP_HIGH, - AP_CRITICAL -}; - -extern const char *theSoundTypeNames[]; -enum SoundType CPP_11(: Int) -{ - ST_UI = 0x0001, - ST_WORLD = 0x0002, - ST_SHROUDED = 0x0004, - ST_GLOBAL = 0x0008, - ST_VOICE = 0x0010, - ST_PLAYER = 0x0020, - ST_ALLIES = 0x0040, - ST_ENEMIES = 0x0080, - ST_EVERYONE = 0x0100, -}; - -extern const char *theAudioControlNames[]; -enum AudioControl CPP_11(: Int) -{ - AC_LOOP = 0x0001, - AC_RANDOM = 0x0002, - AC_ALL = 0x0004, - AC_POSTDELAY = 0x0008, - AC_INTERRUPT = 0x0010, -}; - -class DynamicAudioEventInfo; - -struct AudioEventInfo : public MemoryPoolObject -{ - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AudioEventInfo, "AudioEventInfo" ) - -public: - AsciiString m_audioName; // This name matches the name of the AudioEventRTS - AsciiString m_filename; // For music tracks, this is the filename of the track - - Real m_volume; // Desired volume of this audio - Real m_volumeShift; // Desired volume shift of the audio - Real m_minVolume; // Clamped minimum value, useful when muting sound effects - Real m_pitchShiftMin; // minimum pitch shift value - Real m_pitchShiftMax; // maximum pitch shift value - Int m_delayMin; // minimum delay before we'll fire up another one of these - Int m_delayMax; // maximum delay before we'll fire up another one of these - Int m_limit; // Limit to the number of these sounds that can be fired up simultaneously - Int m_loopCount; // number of times to loop this sound - - AudioPriority m_priority; // Priority of this sound - UnsignedInt m_type; // Type of sound - UnsignedInt m_control; // control of sound - - std::vector m_soundsMorning; // Sounds to play in the wee hours of the morning - std::vector m_sounds; // Default sounds to play - std::vector m_soundsNight; // Sounds to play at night - std::vector m_soundsEvening; // Sounds to play in the evening - - std::vector m_attackSounds; - std::vector m_decaySounds; - - Real m_lowPassFreq; // When performing low pass filters, what is the maximum frequency heard, expressed as a percentage? - Real m_minDistance; // less than this distance and the sound behaves as though it is at minDistance - Real m_maxDistance; // greater than this distance and the sound behaves as though it is muted - - AudioType m_soundType; // This should be either Music, Streaming or SoundEffect - - - // DynamicAudioEventInfo interfacing functions - virtual Bool isLevelSpecific() const { return false; } ///< If true, this sound is only defined on the current level and can be deleted when that level ends - virtual DynamicAudioEventInfo * getDynamicAudioEventInfo() { return NULL; } ///< If this object is REALLY a DynamicAudioEventInfo, return a pointer to the derived class - virtual const DynamicAudioEventInfo * getDynamicAudioEventInfo() const { return NULL; } ///< If this object is REALLY a DynamicAudioEventInfo, return a pointer to the derived class - - /// Is this a permenant sound? That is, if I start this sound up, will it ever end - /// "on its own" or only if I explicitly kill it? - Bool isPermanentSound() const { return BitIsSet( m_control, AC_LOOP ) && (m_loopCount == 0 ); } - - static const FieldParse m_audioEventInfo[]; ///< the parse table for INI definition - const FieldParse *getFieldParse( void ) const { return m_audioEventInfo; } -}; - -#endif /* _H_AUDIOEVENTINFO_ */ diff --git a/Generals/Code/GameEngine/Include/Common/AudioEventRTS.h b/Generals/Code/GameEngine/Include/Common/AudioEventRTS.h deleted file mode 100644 index 4bf690e6040..00000000000 --- a/Generals/Code/GameEngine/Include/Common/AudioEventRTS.h +++ /dev/null @@ -1,217 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: AudioEventRTS.h /////////////////////////////////////////////////////////////////////////////// -// AudioEventRTS structure -// Author: John K. McDonald, March 2002 - -#pragma once -#ifndef _H_AUDIOEVENTRTS_ -#define _H_AUDIOEVENTRTS_ - -#include "Common/AsciiString.h" -#include "Common/GameAudio.h" -#include "Common/GameMemory.h" -#include "Common/GameType.h" - -// forward declarations /////////////////////////////////////////////////////////////////////////// -struct AudioEventInfo; - -enum OwnerType CPP_11(: Int) -{ - OT_Positional, - OT_Drawable, - OT_Object, - OT_Dead, - OT_INVALID -}; - -enum PortionToPlay CPP_11(: Int) -{ - PP_Attack, - PP_Sound, - PP_Decay, - PP_Done -}; - -enum AudioPriority CPP_11(: Int); - -// This is called AudioEventRTS because AudioEvent is a typedef in ww3d -// You might want this to be memory pooled (I personally do), but it can't -// because we allocate them on the stack frequently. -class AudioEventRTS -{ -public: - AudioEventRTS( ); - AudioEventRTS( const AsciiString& eventName ); - AudioEventRTS( const AsciiString& eventName, ObjectID ownerID ); - AudioEventRTS( const AsciiString& eventName, DrawableID drawableID ); // Pass 0 for unused if attaching to drawable - AudioEventRTS( const AsciiString& eventName, const Coord3D *positionOfAudio ); - - virtual ~AudioEventRTS( ); - - AudioEventRTS( const AudioEventRTS& right ); - AudioEventRTS& operator=( const AudioEventRTS& right ); - - void setEventName( AsciiString name ); - const AsciiString& getEventName( void ) const { return m_eventName; } - - // generateFilename is separate from generatePlayInfo because generatePlayInfo should only be called once - // per triggered event. generateFilename will be called once per loop, or once to get each filename if 'all' is - // specified. - void generateFilename( void ); - AsciiString getFilename( void ); - - // The attack and decay sounds are generated in generatePlayInfo, because they will never be played more - // than once during a given sound event. - void generatePlayInfo( void ); - Real getPitchShift( void ) const; - Real getVolumeShift( void ) const; - AsciiString getAttackFilename( void ) const; - AsciiString getDecayFilename( void ) const; - Real getDelay( void ) const; - - void decrementDelay( Real timeToDecrement ); - - PortionToPlay getNextPlayPortion( void ) const; - void advanceNextPlayPortion( void ); - void setNextPlayPortion( PortionToPlay ptp ); - - void decreaseLoopCount( void ); - Bool hasMoreLoops( void ) const; - - void setAudioEventInfo( const AudioEventInfo *eventInfo ) const; - const AudioEventInfo *getAudioEventInfo( void ) const; - - void setPlayingHandle( AudioHandle handle ); // for ID of this audio piece. - AudioHandle getPlayingHandle( void ); // for ID of this audio piece - - void setPosition( const Coord3D *pos ); - const Coord3D* getPosition( void ); - - void setObjectID( ObjectID objID ); - ObjectID getObjectID( void ); - - Bool isDead() const { return m_ownerType == OT_Dead; } - OwnerType getOwnerType() const { return m_ownerType; } - - void setDrawableID( DrawableID drawID ); - DrawableID getDrawableID( void ); - - void setTimeOfDay( TimeOfDay tod ); - TimeOfDay getTimeOfDay( void ) const; - - void setHandleToKill( AudioHandle handleToKill ); - AudioHandle getHandleToKill( void ) const; - - void setShouldFade( Bool shouldFade ); - Bool getShouldFade( void ) const; - - void setIsLogicalAudio( Bool isLogicalAudio ); - Bool getIsLogicalAudio( void ) const; - - Bool isPositionalAudio( void ) const; - Bool isCurrentlyPlaying( void ) const; - - AudioPriority getAudioPriority( void ) const; - void setAudioPriority( AudioPriority newPriority ); - - Real getVolume( void ) const; - void setVolume( Real vol ); - - Int getPlayerIndex( void ) const; - void setPlayerIndex( Int playerNdx ); - - Int getPlayingAudioIndex( void ) { return m_playingAudioIndex; }; - void setPlayingAudioIndex( Int pai ) { m_playingAudioIndex = pai; }; - - Bool getUninterruptable( ) const { return m_uninterruptable; } - void setUninterruptable( Bool uninterruptable ) { m_uninterruptable = uninterruptable; } - - - // This will retrieve the appropriate position based on type. - const Coord3D *getCurrentPosition( void ); - - // This will return the directory leading up to the appropriate type, including the trailing '\\' - // If localized is true, we'll append a language specifc directory to the end of the path. - AsciiString generateFilenamePrefix( AudioType audioTypeToPlay, Bool localized ); - AsciiString generateFilenameExtension( AudioType audioTypeToPlay ); -protected: - void adjustForLocalization( AsciiString &strToAdjust ); - -protected: - AsciiString m_filenameToLoad; - mutable const AudioEventInfo *m_eventInfo; // Mutable so that it can be modified even on const objects - AudioHandle m_playingHandle; - - AudioHandle m_killThisHandle; ///< Sometimes sounds will canabilize other sounds in order to take their handle away. - ///< This is one of those instances. - - AsciiString m_eventName; ///< This should correspond with an entry in Dialog.ini, Speech.ini, or Audio.ini - AsciiString m_attackName; ///< This is the filename that should be used during the attack. - AsciiString m_decayName; ///< This is the filename that should be used during the decay. - - AudioPriority m_priority; ///< This should be the priority as given by the event info, or the overrided priority. - Real m_volume; ///< This is the override for the volume. It will either be the normal - TimeOfDay m_timeOfDay; ///< This should be the current Time Of Day. - - Coord3D m_positionOfAudio; ///< Position of the sound if no further positional updates are necessary - union // These are now unioned. - { - ObjectID m_objectID; ///< ObjectID of the object that this sound is tied to. Position can be automatically updated from this. - DrawableID m_drawableID; ///< DrawableID of the drawable that owns this sound - }; - OwnerType m_ownerType; - - Bool m_shouldFade; ///< This should fade in or out (if it is starting or stopping) - Bool m_isLogicalAudio; ///< Should probably only be true for scripted sounds - Bool m_uninterruptable; - - // Playing attributes - Real m_pitchShift; ///< Pitch shift that should occur on this piece of audio - Real m_volumeShift; ///< Volume shift that should occur on this piece of audio - Real m_delay; ///< Amount to delay before playing this sound - Int m_loopCount; ///< The current loop count value. Only valid if this is a looping type event or the override has been set. - Int m_playingAudioIndex; ///< The sound index we are currently playing. In the case of non-random, we increment this to move to the next sound - Int m_allCount; ///< If this sound is an ALL type, then this is how many sounds we have played so far. - - Int m_playerIndex; ///< The index of the player who owns this sound. Used for sounds that should have an owner, but don't have an object, etc. - - PortionToPlay m_portionToPlayNext; ///< Which portion (attack, sound, decay) should be played next? -}; - -class DynamicAudioEventRTS : public MemoryPoolObject -{ - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(DynamicAudioEventRTS, "DynamicAudioEventRTS" ) -public: - - DynamicAudioEventRTS() { } - DynamicAudioEventRTS(const AudioEventRTS& a) : m_event(a) { } - - AudioEventRTS m_event; -}; -EMPTY_DTOR(DynamicAudioEventRTS) - -#endif /* _H_AUDIOEVENTRTS_ */ - diff --git a/Generals/Code/GameEngine/Include/Common/AudioHandleSpecialValues.h b/Generals/Code/GameEngine/Include/Common/AudioHandleSpecialValues.h deleted file mode 100644 index 3893609f4db..00000000000 --- a/Generals/Code/GameEngine/Include/Common/AudioHandleSpecialValues.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// EA Pacific -// John McDonald, Jr -// Do not distribute - -#pragma once - -#ifndef _AUDIOHANDLESPECIALVALUES_H_ -#define _AUDIOHANDLESPECIALVALUES_H_ - -enum AudioHandleSpecialValues CPP_11(: Int) -{ - AHSV_Error = 0x00, - AHSV_NoSound, - AHSV_Muted, - AHSV_NotForLocal, - AHSV_StopTheMusic, - AHSV_StopTheMusicFade, - AHSV_FirstHandle -}; - -#endif // _AUDIOHANDLESPECIALVALUES_H_ diff --git a/Generals/Code/GameEngine/Include/Common/AudioRandomValue.h b/Generals/Code/GameEngine/Include/Common/AudioRandomValue.h deleted file mode 100644 index 2fa4ec7cb74..00000000000 --- a/Generals/Code/GameEngine/Include/Common/AudioRandomValue.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// AudioRandomValue.h -// Random number generation system -// Author: Michael S. Booth, January 1998 -// Split out into separate Logic/Client/Audio headers by MDC Sept 2002 - -#pragma once - -#ifndef _AUDIO_RANDOM_VALUE_H_ -#define _AUDIO_RANDOM_VALUE_H_ - -#include "Lib/BaseType.h" - -// do NOT use these functions directly, rather use the macros below -extern Int GetGameAudioRandomValue( int lo, int hi, const char *file, int line ); -extern Real GetGameAudioRandomValueReal( Real lo, Real hi, const char *file, int line ); - -// use these macros to access the random value functions -#define GameAudioRandomValue( lo, hi ) GetGameAudioRandomValue( lo, hi, __FILE__, __LINE__ ) -#define GameAudioRandomValueReal( lo, hi ) GetGameAudioRandomValueReal( lo, hi, __FILE__, __LINE__ ) - -//-------------------------------------------------------------------------------------------------------------- - -#endif // _AUDIO_RANDOM_VALUE_H_ diff --git a/Generals/Code/GameEngine/Include/Common/AudioRequest.h b/Generals/Code/GameEngine/Include/Common/AudioRequest.h deleted file mode 100644 index 18c3085acb4..00000000000 --- a/Generals/Code/GameEngine/Include/Common/AudioRequest.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// EA Pacific -// John McDonald, Jr -// Do not distribute - -#pragma once - -#ifndef _AUDIOREQUEST_H_ -#define _AUDIOREQUEST_H_ - -#include "Common/GameAudio.h" -#include "Common/GameMemory.h" - -class AudioEventRTS; - -enum RequestType CPP_11(: Int) -{ - AR_Play, - AR_Pause, - AR_Stop -}; - -struct AudioRequest : public MemoryPoolObject -{ - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AudioRequest, "AudioRequest" ) - -public: - RequestType m_request; - union - { - AudioEventRTS *m_pendingEvent; - AudioHandle m_handleToInteractOn; - }; - Bool m_usePendingEvent; - Bool m_requiresCheckForSample; -}; - -#endif // _AUDIOREQUEST_H_ diff --git a/Generals/Code/GameEngine/Include/Common/AudioSettings.h b/Generals/Code/GameEngine/Include/Common/AudioSettings.h deleted file mode 100644 index 7d198855440..00000000000 --- a/Generals/Code/GameEngine/Include/Common/AudioSettings.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// EA Pacific -// John McDonald, Jr -// Do not distribute - -#pragma once - -#ifndef _AUDIOSETTINGS_H_ -#define _AUDIOSETTINGS_H_ - -#include "Common/AsciiString.h" - -enum { MAX_HW_PROVIDERS = 4 }; - -struct AudioSettings -{ - AsciiString m_audioRoot; - AsciiString m_soundsFolder; - AsciiString m_musicFolder; - AsciiString m_streamingFolder; - AsciiString m_soundsExtension; - Bool m_useDigital; - Bool m_useMidi; - Int m_outputRate; - Int m_outputBits; - Int m_outputChannels; - Int m_sampleCount2D; - Int m_sampleCount3D; - Int m_streamCount; - Int m_globalMinRange; - Int m_globalMaxRange; - Int m_drawableAmbientFrames; - Int m_fadeAudioFrames; - UnsignedInt m_maxCacheSize; - - Real m_minVolume; // At volumes less than this, the sample will be culled. - - AsciiString m_preferred3DProvider[MAX_HW_PROVIDERS + 1]; - - //Defaults actually don't ever get changed! - Real m_relative2DVolume; //2D volume compared to 3D - Real m_defaultSoundVolume; - Real m_default3DSoundVolume; - Real m_defaultSpeechVolume; - Real m_defaultMusicVolume; - UnsignedInt m_defaultSpeakerType2D; - UnsignedInt m_defaultSpeakerType3D; - - //If you want to change a value, store it somewhere else (like here) - Real m_preferredSoundVolume; - Real m_preferred3DSoundVolume; - Real m_preferredSpeechVolume; - Real m_preferredMusicVolume; - - //The desired altitude of the microphone to improve panning relative to terrain. - Real m_microphoneDesiredHeightAboveTerrain; - - //When tracing a line between the ground look-at-point and the camera, we want - //to ensure a maximum percentage, so the microphone never goes behind the camera. - Real m_microphoneMaxPercentageBetweenGroundAndCamera; - - //Handles changing sound volume whenever the camera is close to the microphone. - Real m_zoomMinDistance; //If we're closer than the minimum distance, then apply the full bonus no matter how close. - Real m_zoomMaxDistance; //The maximum distance from microphone we need to be before benefiting from any bonus. - - //NOTE: The higher this value is, the lower normal sounds will be! If you specify a sound volume value of 25%, then sounds will play - //between 75% and 100%, not 100% to 125%! - Real m_zoomSoundVolumePercentageAmount; //The amount of sound volume dedicated to zooming. -}; - -#endif // _AUDIOSETTINGS_H_ diff --git a/Generals/Code/GameEngine/Include/Common/GameAudio.h b/Generals/Code/GameEngine/Include/Common/GameAudio.h deleted file mode 100644 index baf3da6bad6..00000000000 --- a/Generals/Code/GameEngine/Include/Common/GameAudio.h +++ /dev/null @@ -1,428 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//---------------------------------------------------------------------------- -// -// Project: RTS 3 -// -// File name: Common/GameAudio.h -// -// Created: 5/01/01 -// -//---------------------------------------------------------------------------- - -#pragma once - -#ifndef __COMMON_GAMEAUDIO_H_ -#define __COMMON_GAMEAUDIO_H_ - -// Includes -#include "Lib/BaseType.h" -#include "Common/STLTypedefs.h" -#include "Common/SubsystemInterface.h" - - -// Forward Declarations - -class AsciiString; -class AudioEventRTS; -class DebugDisplayInterface; -class Drawable; -class MusicManager; -class Object; -class SoundManager; - - -enum AudioAffect CPP_11(: Int); -enum AudioType CPP_11(: Int); - -struct AudioEventInfo; -struct AudioRequest; -struct AudioSettings; -struct MiscAudio; - -typedef std::hash_map, rts::equal_to > AudioEventInfoHash; -typedef AudioEventInfoHash::iterator AudioEventInfoHashIt; -typedef UnsignedInt AudioHandle; - - -// Defines -enum -{ - PROVIDER_ERROR = 0xFFFFFFFF -}; - -// Class AudioManager -/** - The life of audio. - - When audio is requested to play, it is done so in the following manner: - 1) An AudioEventRTS is created on the stack. - 2) Its guts are copied from elsewhere (for instance, a ThingTemplate, or MiscAudio). - 3) It is added to TheAudio via TheAudio->addAudioEvent(...) - - The return value from addAudioEvent can be saved in case the sound needs to loop and/or be - terminated at some point. - - To reomve a playing sound, the call TheAudio->removeAudioEvent(...) is used. This will search - the list of currently playing audio for the specified handle, and kill the attached sound. It - will play a decay sound, if one is specified. - - The important functions of TheAudio, are therefore - GameAudio::addAudioEvent() - GameAudio::removeAudioEvent() - All other functions exist to support these two basic requirements. - - In addition to the fundamental requirements, the audio has a fairly complicated sound management - scheme. If all units were always allowed to sound off, the sound engine would be overwhelmed and - would sound awful. Therefore, when an audio event is requested, it goes through a series of - checks to determine if it is near enough to the camera, if it should be heard based on shroud, - local player affiliation, etc. (The entire list of checks is contained in shouldPlayLocally()). - - In addition, the world and unit audio are never allowed to exceed their footprint, as specified - in the audio settings INI file. In order to accomodate this, the audio uses an audio cache. The - audio cache will attempt to load a sample, assuming there is enough room. If there is not enough - room, then it goes through and finds any samples that are lower priority, and kills them until - enough room is present for the sample. If it cannot free enough room, nothing happens to the - cache. - - Although the audio is multithreaded, most of the operations are performed such that the worst - case scenario for thread miscommunication is that the main thread misses an event for one frame. - One specific case of this is the status of playing audio. Because audio is playing - asynchronously, it can complete at any time. When most audio completes, it sets a flag on the - event noting that it has completed. During the next update (from the main thread), anything with - that flag set is moved to the stopped list, and then is cleaned up. (Basically, the audio uses - a push model for its multithreadedness, which doesn't require thread safety such as mutexes or - semaphores). - - All in all, the best way to learn how the audio works is to track the lifetime of an event - through the system. This will give a better understanding than all the documentation I could - write. - - -jkmcd - -December 2002 -*/ - -class AudioManager : public SubsystemInterface -{ - public: - AudioManager(); - virtual ~AudioManager(); -#if defined(RTS_DEBUG) - virtual void audioDebugDisplay(DebugDisplayInterface *dd, void *userData, FILE *fp = NULL ) = 0; -#endif - - // From SubsystemInterface - virtual void init(); - virtual void postProcessLoad(); - virtual void reset(); - virtual void update(); - - // device dependent stop, pause and resume - virtual void stopAudio( AudioAffect which ) = 0; - virtual void pauseAudio( AudioAffect which ) = 0; - virtual void resumeAudio( AudioAffect which ) = 0; - virtual void pauseAmbient( Bool shouldPause ) = 0; - - // for focus issues - virtual void loseFocus( void ); - virtual void regainFocus( void ); - - // control for AudioEventsRTS - virtual AudioHandle addAudioEvent( const AudioEventRTS *eventToAdd ); ///< Add an audio event (event must be declared in an INI file) - virtual void removeAudioEvent( AudioHandle audioEvent ); ///< Remove an audio event, stop for instance. - virtual void killAudioEventImmediately( AudioHandle audioEvent ) = 0; - - virtual Bool isValidAudioEvent( const AudioEventRTS *eventToCheck ) const; ///< validate that this piece of audio exists - virtual Bool isValidAudioEvent( AudioEventRTS *eventToCheck ) const; ///< validate that this piece of audio exists - - // add tracks during INIification - void addTrackName( const AsciiString& trackName ); - AsciiString nextTrackName(const AsciiString& currentTrack ); - AsciiString prevTrackName(const AsciiString& currentTrack ); - - // changing music tracks - virtual void nextMusicTrack( void ) = 0; - virtual void prevMusicTrack( void ) = 0; - virtual Bool isMusicPlaying( void ) const = 0; - virtual Bool hasMusicTrackCompleted( const AsciiString& trackName, Int numberOfTimes ) const = 0; - virtual AsciiString getMusicTrackName( void ) const = 0; - - virtual void setAudioEventEnabled( AsciiString eventToAffect, Bool enable ); - virtual void setAudioEventVolumeOverride( AsciiString eventToAffect, Real newVolume ); - virtual void removeAudioEvent( AsciiString eventToRemove ); - virtual void removeDisabledEvents(); - - // Really meant for internal purposes only, but cannot be protected. - virtual void getInfoForAudioEvent( const AudioEventRTS *eventToFindAndFill ) const; // Note: m_eventInfo is Mutable, and so this function will overwrite it if found - - ///< Return whether the current audio is playing or not. - ///< NOTE NOTE NOTE !!DO NOT USE THIS IN FOR GAMELOGIC PURPOSES!! NOTE NOTE NOTE - virtual Bool isCurrentlyPlaying( AudioHandle handle ); - - // Device Dependent open and close functions - virtual void openDevice( void ) = 0; - virtual void closeDevice( void ) = 0; - virtual void *getDevice( void ) = 0; - - // Debice Dependent notification functions - virtual void notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags ) = 0; - - // Device Dependent enumerate providers functions. It is okay for there to be only 1 provider (Miles provides a maximum of 64. - virtual UnsignedInt getProviderCount( void ) const = 0; - virtual AsciiString getProviderName( UnsignedInt providerNum ) const = 0; - virtual UnsignedInt getProviderIndex( AsciiString providerName ) const = 0; - virtual void selectProvider( UnsignedInt providerNdx ) = 0; - virtual void unselectProvider( void ) = 0; - virtual UnsignedInt getSelectedProvider( void ) const = 0; - virtual void setSpeakerType( UnsignedInt speakerType ) = 0; - virtual UnsignedInt getSpeakerType( void ) = 0; - - virtual UnsignedInt translateSpeakerTypeToUnsignedInt( const AsciiString& speakerType ); - virtual AsciiString translateUnsignedIntToSpeakerType( UnsignedInt speakerType ); - - // Device Dependent calls to get the number of channels for each type of audio (2-D, 3-D, Streams) - virtual UnsignedInt getNum2DSamples( void ) const = 0; - virtual UnsignedInt getNum3DSamples( void ) const = 0; - virtual UnsignedInt getNumStreams( void ) const = 0; - - // Device Dependent calls to determine sound prioritization info - virtual Bool doesViolateLimit( AudioEventRTS *event ) const = 0; - virtual Bool isPlayingLowerPriority( AudioEventRTS *event ) const = 0; - virtual Bool isPlayingAlready( AudioEventRTS *event ) const = 0; - virtual Bool isObjectPlayingVoice( UnsignedInt objID ) const = 0; - - virtual void adjustVolumeOfPlayingAudio(AsciiString eventName, Real newVolume) = 0; - virtual void removePlayingAudio( AsciiString eventName ) = 0; - virtual void removeAllDisabledAudio() = 0; - - // Is the audio device on? We can skip a lot of audio processing if not. - virtual Bool isOn( AudioAffect whichToGet ) const; - virtual void setOn( Bool turnOn, AudioAffect whichToAffect ); - - // Set and get the device Volume - virtual void setVolume( Real volume, AudioAffect whichToAffect ); - virtual Real getVolume( AudioAffect whichToGet ); - - // To get a more 3-D feeling from the universe, we adjust the volume of the 3-D samples based - // on zoom. - virtual void set3DVolumeAdjustment( Real volumeAdjustment ); - - virtual Bool has3DSensitiveStreamsPlaying( void ) const = 0; - - virtual void *getHandleForBink( void ) = 0; - virtual void releaseHandleForBink( void ) = 0; - - // this function will play an audio event rts by loading it into memory. It should not be used - // by anything except for the load screens. - virtual void friend_forcePlayAudioEventRTS(const AudioEventRTS* eventToPlay) = 0; - - // Update Listener position information - virtual void setListenerPosition( const Coord3D *newListenerPos, const Coord3D *newListenerOrientation ); - virtual const Coord3D *getListenerPosition( void ) const; - - virtual AudioRequest *allocateAudioRequest( Bool useAudioEvent ); - virtual void releaseAudioRequest( AudioRequest *requestToRelease ); - virtual void appendAudioRequest( AudioRequest *m_request ); - virtual void processRequestList( void ); - - virtual AudioEventInfo *newAudioEventInfo( AsciiString newEventName ); - virtual void addAudioEventInfo( AudioEventInfo * newEventInfo ); - virtual AudioEventInfo *findAudioEventInfo( AsciiString eventName ) const; - - const AudioSettings *getAudioSettings( void ) const; - const MiscAudio *getMiscAudio( void ) const; - - // This function should only be called by AudioManager, MusicManager and SoundManager - virtual void releaseAudioEventRTS( AudioEventRTS *&eventToRelease ); - - // For INI - AudioSettings *friend_getAudioSettings( void ); - MiscAudio *friend_getMiscAudio( void ); - const FieldParse *getFieldParseTable( void ) const; - - const AudioEventRTS *getValidSilentAudioEvent() const { return m_silentAudioEvent; } - - virtual void setHardwareAccelerated(Bool accel) { m_hardwareAccel = accel; } - virtual Bool getHardwareAccelerated() { return m_hardwareAccel; } - - virtual void setSpeakerSurround(Bool surround) { m_surroundSpeakers = surround; } - virtual Bool getSpeakerSurround() { return m_surroundSpeakers; } - - virtual void refreshCachedVariables(); - - virtual void setPreferredProvider(AsciiString providerNdx) = 0; - virtual void setPreferredSpeaker(AsciiString speakerType) = 0; - - // For Scripting - virtual Real getAudioLengthMS( const AudioEventRTS *event ); - virtual Real getFileLengthMS( AsciiString strToLoad ) const = 0; - - // For the file cache to know when to remove files. - virtual void closeAnySamplesUsingFile( const void *fileToClose ) = 0; - - virtual Bool isMusicAlreadyLoaded(void) const; - virtual Bool isMusicPlayingFromCD(void) const { return m_musicPlayingFromCD; } - - Bool getDisallowSpeech( void ) const { return m_disallowSpeech; } - void setDisallowSpeech( Bool disallowSpeech ) { m_disallowSpeech = disallowSpeech; } - - // For Worldbuilder, to build lists from which to select - virtual void findAllAudioEventsOfType( AudioType audioType, std::vector& allEvents ); - virtual const AudioEventInfoHash & getAllAudioEvents() const { return m_allAudioEventInfo; } - - Real getZoomVolume() const { return m_zoomVolume; } - protected: - - // Is the currently selected provider actually HW accelerated? - virtual Bool isCurrentProviderHardwareAccelerated(); - - // Is the currently selected speaker type Surround sound? - virtual Bool isCurrentSpeakerTypeSurroundSound(); - - // Should this piece of audio play on the local machine? - virtual Bool shouldPlayLocally(const AudioEventRTS *audioEvent); - - // Set the Listening position for the device - virtual void setDeviceListenerPosition( void ) = 0; - - // For tracking purposes - virtual AudioHandle allocateNewHandle( void ); - - // Remove all AudioEventInfo's with the m_isLevelSpecific flag - virtual void removeLevelSpecificAudioEventInfos( void ); - - void removeAllAudioRequests( void ); - - protected: - AudioSettings *m_audioSettings; - MiscAudio *m_miscAudio; - MusicManager *m_music; - SoundManager *m_sound; - Coord3D m_listenerPosition; - Coord3D m_listenerOrientation; - std::list m_audioRequests; - std::vector m_musicTracks; - - AudioEventInfoHash m_allAudioEventInfo; - AudioHandle theAudioHandlePool; - std::list > m_adjustedVolumes; - - Real m_musicVolume; - Real m_soundVolume; - Real m_sound3DVolume; - Real m_speechVolume; - - Real m_scriptMusicVolume; - Real m_scriptSoundVolume; - Real m_scriptSound3DVolume; - Real m_scriptSpeechVolume; - - Real m_systemMusicVolume; - Real m_systemSoundVolume; - Real m_systemSound3DVolume; - Real m_systemSpeechVolume; - Real m_zoomVolume; - - - AudioEventRTS *m_silentAudioEvent; - - enum { NUM_VOLUME_TYPES = 4 }; - Real *m_savedValues; - - // Group of 8 - Bool m_speechOn : 1; - Bool m_soundOn : 1; - Bool m_sound3DOn : 1; - Bool m_musicOn : 1; - Bool m_volumeHasChanged : 1; - Bool m_hardwareAccel : 1; - Bool m_surroundSpeakers : 1; - Bool m_musicPlayingFromCD : 1; - - // Next 8 - Bool m_disallowSpeech : 1; -}; - -// TheSuperHackers @feature helmutbuhler 17/05/2025 -// AudioManager that does nothing. Used for Headless Mode. -class AudioManagerDummy : public AudioManager -{ -#if defined(RTS_DEBUG) - virtual void audioDebugDisplay(DebugDisplayInterface* dd, void* userData, FILE* fp) {} -#endif - virtual void stopAudio(AudioAffect which) {} - virtual void pauseAudio(AudioAffect which) {} - virtual void resumeAudio(AudioAffect which) {} - virtual void pauseAmbient(Bool shouldPause) {} - virtual void killAudioEventImmediately(AudioHandle audioEvent) {} - virtual void nextMusicTrack() {} - virtual void prevMusicTrack() {} - virtual Bool isMusicPlaying() const { return false; } - virtual Bool hasMusicTrackCompleted(const AsciiString& trackName, Int numberOfTimes) const { return false; } - virtual AsciiString getMusicTrackName() const { return ""; } - virtual void openDevice() {} - virtual void closeDevice() {} - virtual void* getDevice() { return NULL; } - virtual void notifyOfAudioCompletion(UnsignedInt audioCompleted, UnsignedInt flags) {} - virtual UnsignedInt getProviderCount(void) const { return 0; }; - virtual AsciiString getProviderName(UnsignedInt providerNum) const { return ""; } - virtual UnsignedInt getProviderIndex(AsciiString providerName) const { return 0; } - virtual void selectProvider(UnsignedInt providerNdx) {} - virtual void unselectProvider(void) {} - virtual UnsignedInt getSelectedProvider(void) const { return 0; } - virtual void setSpeakerType(UnsignedInt speakerType) {} - virtual UnsignedInt getSpeakerType(void) { return 0; } - virtual UnsignedInt getNum2DSamples(void) const { return 0; } - virtual UnsignedInt getNum3DSamples(void) const { return 0; } - virtual UnsignedInt getNumStreams(void) const { return 0; } - virtual Bool doesViolateLimit(AudioEventRTS* event) const { return false; } - virtual Bool isPlayingLowerPriority(AudioEventRTS* event) const { return false; } - virtual Bool isPlayingAlready(AudioEventRTS* event) const { return false; } - virtual Bool isObjectPlayingVoice(UnsignedInt objID) const { return false; } - virtual void adjustVolumeOfPlayingAudio(AsciiString eventName, Real newVolume) {} - virtual void removePlayingAudio(AsciiString eventName) {} - virtual void removeAllDisabledAudio() {} - virtual Bool has3DSensitiveStreamsPlaying(void) const { return false; } - virtual void* getHandleForBink(void) { return NULL; } - virtual void releaseHandleForBink(void) {} - virtual void friend_forcePlayAudioEventRTS(const AudioEventRTS* eventToPlay) {} - virtual void setPreferredProvider(AsciiString providerNdx) {} - virtual void setPreferredSpeaker(AsciiString speakerType) {} - virtual Real getFileLengthMS(AsciiString strToLoad) const { return -1; } - virtual void closeAnySamplesUsingFile(const void* fileToClose) {} - virtual void setDeviceListenerPosition(void) {} -}; - - -extern AudioManager *TheAudio; - -#endif // __COMMON_GAMEAUDIO_H_ diff --git a/Generals/Code/GameEngine/Include/Common/GameMusic.h b/Generals/Code/GameEngine/Include/Common/GameMusic.h deleted file mode 100644 index e1f781aa76a..00000000000 --- a/Generals/Code/GameEngine/Include/Common/GameMusic.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//---------------------------------------------------------------------------- -// -// Project: RTS 3 -// -// File name: Common/GameMusic.h -// -// Created: 5/01/01 -// -//---------------------------------------------------------------------------- - -#pragma once - -#ifndef __COMMON_GAMEMUSIC_H_ -#define __COMMON_GAMEMUSIC_H_ - - -//---------------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------------- - -#include "Common/GameAudio.h" -#include "Common/GameMemory.h" - - -//---------------------------------------------------------------------------- -// Forward References -//---------------------------------------------------------------------------- - -class AudioEventRTS; -struct FieldParse; - -//---------------------------------------------------------------------------- -// Type Defines -//---------------------------------------------------------------------------- - - -//=============================== -// MusicTrack -//=============================== - -//------------------------------------------------------------------------------------------------- -/** The MusicTrack struct holds all information about a music track. - * Place data in TrackInfo that is useful to the game code in determining - * what tracks to play. */ -//------------------------------------------------------------------------------------------------- - -class MusicTrack : public MemoryPoolObject -{ - - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( MusicTrack, "MusicTrack" ) - -public: - - MusicTrack(); - // virtual destructor prototype defined by memory pool object - - const FieldParse *getFieldParse( void ) const { return m_musicTrackFieldParseTable; } - - Int index; ///< Track index - AsciiString name; ///< Logical name of track - AsciiString filename; ///< Filename with extension of music track - Real volume; ///< Mixing level for this track - Bool ambient; ///< Game info about this track(public) - - MusicTrack *next; - MusicTrack *prev; - - static const FieldParse m_musicTrackFieldParseTable[]; ///< the parse table for INI definition - -}; - -class MusicManager -{ - public: - MusicManager(); - virtual ~MusicManager(); - - void playTrack( AudioEventRTS *eventToUse ); - void stopTrack( AudioHandle eventToRemove ); - - virtual void addAudioEvent(AudioEventRTS *eventToAdd); // pre-copied - virtual void removeAudioEvent( AudioHandle eventToRemove ); - - void setVolume( Real m_volume ); -}; - -#endif // __COMMON_GAMEMUSIC_H_ diff --git a/Generals/Code/GameEngine/Include/Common/GameSounds.h b/Generals/Code/GameEngine/Include/Common/GameSounds.h deleted file mode 100644 index 41bf4d3b61d..00000000000 --- a/Generals/Code/GameEngine/Include/Common/GameSounds.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//---------------------------------------------------------------------------- -// -// Project: RTS 3 -// -// File name: Common/GameSounds.h -// -// Created: 5/02/01 -// -//---------------------------------------------------------------------------- - -#pragma once -#ifndef __COMMON_GAMESOUNDS_H_ -#define __COMMON_GAMESOUNDS_H_ - -#include "Common/SubsystemInterface.h" -#include "Common/GameAudio.h" -#include "Common/GameType.h" - -// Forward declarations -class AudioEventRTS; - -class SoundManager : public SubsystemInterface -{ - public: - SoundManager(); - virtual ~SoundManager(); - - virtual void init( void ); ///< Initializes the sounds system - virtual void postProcessLoad(); - virtual void update( void ); ///< Services sounds tasks. Called by AudioInterface - virtual void reset( void ); ///< Reset the sounds system - - virtual void loseFocus( void ); ///< Called when application loses focus - virtual void regainFocus( void ); ///< Called when application regains focus - - virtual void setListenerPosition( const Coord3D *position ); ///< Set the listener position for map3DSound() calculations - virtual void setViewRadius( Real viewRadius );///< Sets the radius of the view from the center of the screen in world coordinate units - virtual void setCameraAudibleDistance( Real audibleDistance ); - virtual Real getCameraAudibleDistance( void ); - - virtual void addAudioEvent(AudioEventRTS *&eventToAdd); // pre-copied - - virtual void notifyOf2DSampleStart( void ); - virtual void notifyOf3DSampleStart( void ); - - virtual void notifyOf2DSampleCompletion( void ); - virtual void notifyOf3DSampleCompletion( void ); - - virtual Int getAvailableSamples( void ); - virtual Int getAvailable3DSamples( void ); - - // empty string means that this sound wasn't found or some error occurred. CHECK FOR EMPTY STRING. - virtual AsciiString getFilenameForPlayFromAudioEvent( const AudioEventRTS *eventToGetFrom ); - - // called by this class and MilesAudioManager to determine if a sound can still be played - virtual Bool canPlayNow( AudioEventRTS *event ); - - protected: - virtual Bool violatesVoice( AudioEventRTS *event ); - virtual Bool isInterrupting( AudioEventRTS *event ); - - - protected: - UnsignedInt m_num2DSamples; - UnsignedInt m_num3DSamples; - - UnsignedInt m_numPlaying2DSamples; - UnsignedInt m_numPlaying3DSamples; -}; - -#endif // __COMMON_GAMESOUNDS_H_ - diff --git a/Generals/Code/GameEngine/Include/Common/MiscAudio.h b/Generals/Code/GameEngine/Include/Common/MiscAudio.h deleted file mode 100644 index 63d2b783335..00000000000 --- a/Generals/Code/GameEngine/Include/Common/MiscAudio.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -///MiscAudio.h///////////////////////////////////////////////////////////////////////////////////// -// This file is for miscellaneous sound hooks that don't have another happy home. - -#pragma once - -#ifndef _MISCAUDIO_H_ -#define _MISCAUDIO_H_ - -#include "Common/AudioEventRTS.h" - -struct MiscAudio -{ - static const FieldParse m_fieldParseTable[]; - - AudioEventRTS m_radarUnitUnderAttackSound; ///< radar sounds to play when unit under attack - AudioEventRTS m_radarHarvesterUnderAttackSound; ///< radar sounds to play when harvester under attack - AudioEventRTS m_radarStructureUnderAttackSound; ///< radar sounds to play when structure under attack - AudioEventRTS m_radarUnderAttackSound; ///< radar sounds to play when ? under attack - AudioEventRTS m_radarInfiltrationSound; ///< radar sounds to play when something is infiltrated - AudioEventRTS m_radarOnlineSound; ///< radar sounds to play when radar goes online - AudioEventRTS m_radarOfflineSound; ///< radar sounds to play when radar goes offline - AudioEventRTS m_defectorTimerTickSound; ///< snd to play during transient invulnerability while defecting // lorenzen - AudioEventRTS m_defectorTimerDingSound; ///< snd to play when you become vulnerable again // lorenzen - AudioEventRTS m_lockonTickSound; ///< snd to play during stealth-fighter-lockon period - AudioEventRTS m_allCheerSound; ///< snd to play when user presses 'cheer' key - AudioEventRTS m_battleCrySound; ///< snd to play when user presses 'battlecry' key - AudioEventRTS m_guiClickSound; ///< snd to play when user presses button in GUI - AudioEventRTS m_noCanDoSound; ///< Global "No Can Do" sound - AudioEventRTS m_stealthDiscoveredSound; ///< I have just discovered an enemy stealth unit - AudioEventRTS m_stealthNeutralizedSound; ///< One of my stealthed units has just been discovered by the enemy - AudioEventRTS m_moneyDepositSound; ///< Money was deposited in my bank - AudioEventRTS m_moneyWithdrawSound; ///< Money was withdrawn from my bank - AudioEventRTS m_buildingDisabled; ///< Building has lost power, been hit with an EMP, or disable hacked. - AudioEventRTS m_buildingReenabled; ///< Building has recovered from being disabled. - AudioEventRTS m_vehicleDisabled; ///< Vehicle has been disabled via EMP or hacker attack. - AudioEventRTS m_vehicleReenabled; ///< Vehicle has recovered from being disabled. - AudioEventRTS m_splatterVehiclePilotsBrain; ///< Pilot has been sniped by Jarmen Kell. - AudioEventRTS m_terroristInCarMoveVoice; ///< Terrorist issues a move order while in a car. - AudioEventRTS m_terroristInCarAttackVoice; ///< Terrorist issues attack order while in a car. - AudioEventRTS m_terroristInCarSelectVoice; ///< Terrorist is selected while in a car. - AudioEventRTS m_crateHeal; ///< When heal crate is picked up. - AudioEventRTS m_crateShroud; ///< When shroud crate is picked up. - AudioEventRTS m_crateSalvage; ///< When salvage crate is picked up. - AudioEventRTS m_crateFreeUnit; ///< When free unit crate is picked up. - AudioEventRTS m_crateMoney; ///< When money crate is picked up. - AudioEventRTS m_unitPromoted; ///< Unit is promoted. - AudioEventRTS m_repairSparks; ///< Battle drone repairs unit. - AudioEventRTS m_sabotageShutDownBuilding; ///< When Saboteur hits a building - AudioEventRTS m_sabotageResetTimerBuilding; ///< When Saboteur hits a building - AudioEventRTS m_aircraftWheelScreech; ///< When a jet lands on a runway. -}; - - -#endif /* _MISCAUDIO_H_ */ - diff --git a/Generals/Code/GameEngine/Include/Common/simpleplayer.h b/Generals/Code/GameEngine/Include/Common/simpleplayer.h deleted file mode 100644 index cc48f527095..00000000000 --- a/Generals/Code/GameEngine/Include/Common/simpleplayer.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - - -#ifndef SIMPLEPLAYER_H -#define SIMPLEPLAYER_H - -#include "wmsdk.h" - -// -// we preserve a list of "ready-to-free" list of wave headers for the -// caller to unprepare and free -// -typedef struct WAVEHDR_LIST { - LPWAVEHDR pwh; - struct WAVEHDR_LIST *next; -} WAVEHDR_LIST; - -#define SIMPLE_PLAYER_OPEN_EVENT _T( "45ab58e0-382e-4d1c-ac50-88a5f9601851" ) -#define SIMPLE_PLAYER_CLOSE_EVENT _T( "276095fa-a8e0-48e6-ac61-8b0002345607" ) -#define WMAPLAY_EVENT _T( "9e828a72-64f3-48f0-9de8-13dafd0cbd3a" ) -/////////////////////////////////////////////////////////////////////////////// -class CSimplePlayer : public IWMReaderCallback -{ -public: - CSimplePlayer( HRESULT* phr ); - ~CSimplePlayer(); - - virtual HRESULT Play( LPCWSTR pszUrl, DWORD dwSecDuration, HANDLE hCompletionEvent, HRESULT *phrCompletion ); - -// -// IUnknown Implemenation -// -public: - virtual HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID riid, - void **ppvObject ); - - virtual ULONG STDMETHODCALLTYPE AddRef(); - virtual ULONG STDMETHODCALLTYPE Release(); - -// -// IWMReaderCallback Implemenation -// -public: - virtual HRESULT STDMETHODCALLTYPE OnSample( - /* [in] */ DWORD dwOutputNum, - /* [in] */ QWORD cnsSampleTime, - /* [in] */ QWORD cnsSampleDuration, - /* [in] */ DWORD dwFlags, - /* [in] */ INSSBuffer __RPC_FAR *pSample, - /* [in] */ void __RPC_FAR *pvContext); - - virtual HRESULT STDMETHODCALLTYPE OnStatus( - /* [in] */ WMT_STATUS Status, - /* [in] */ HRESULT hr, - /* [in] */ WMT_ATTR_DATATYPE dwType, - /* [in] */ BYTE __RPC_FAR *pValue, - /* [in] */ void __RPC_FAR *pvContext); - -// -// Helper Methods -// -protected: - - HRESULT Close(); - - void OnWaveOutMsg( UINT uMsg, DWORD dwParam1, DWORD dwParam2 ); - - static void CALLBACK WaveProc( - HWAVEOUT hwo, - UINT uMsg, - DWORD dwInstance, - DWORD dwParam1, - DWORD dwParam2 ); - - HRESULT AddWaveHeader( LPWAVEHDR pwh ); - void RemoveWaveHeaders( void ); - - CRITICAL_SECTION m_CriSec; - WAVEHDR_LIST *m_whdrHead; - - LONG m_cRef; - LONG m_cBuffersOutstanding; - BOOL m_fEof; - HANDLE m_hCompletionEvent; - - IWMReader *m_pReader; - IWMHeaderInfo *m_pHeader; - HWAVEOUT m_hwo; - - HRESULT *m_phrCompletion; - - HRESULT m_hrOpen; - HANDLE m_hOpenEvent; - HANDLE m_hCloseEvent; - - union - { - WAVEFORMATEX m_wfx; - BYTE m_WfxBuf[1024]; - }; - - LPWSTR m_pszUrl; - -}; - -#endif // SIMPLEPLAYER_H diff --git a/Generals/Code/GameEngine/Include/Common/urllaunch.h b/Generals/Code/GameEngine/Include/Common/urllaunch.h deleted file mode 100644 index 27ebc43d5d2..00000000000 --- a/Generals/Code/GameEngine/Include/Common/urllaunch.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - - -#ifndef URLLAUNCH_H -#define URLLAUNCH_H - -HRESULT MakeEscapedURL( LPWSTR pszInURL, LPWSTR *ppszOutURL ); - -HRESULT LaunchURL( LPCWSTR pszURL ); - -#endif // URLLAUNCH_H diff --git a/Generals/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp b/Generals/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp deleted file mode 100644 index 4b7eebd6b84..00000000000 --- a/Generals/Code/GameEngine/Source/Common/Audio/AudioEventRTS.cpp +++ /dev/null @@ -1,847 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: AudioEventRTS.cpp -/*---------------------------------------------------------------------------*/ -/* EA Pacific */ -/* Confidential Information */ -/* Copyright (C) 2001 - All Rights Reserved */ -/* DO NOT DISTRIBUTE */ -/*---------------------------------------------------------------------------*/ -/* Project: RTS3 */ -/* File name: AudioEventRTS.cpp */ -/* Created: John K. McDonald, Jr., 3/21/2002 */ -/* Desc: AudioEventRTS constructors and assignment operator, etc. */ -/* Revision History: */ -/* 3/21/2002 : Initial creation */ -/*---------------------------------------------------------------------------*/ -#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine - -#include "Common/AudioEventRTS.h" - -#include "Common/AudioEventInfo.h" -#include "Common/AudioRandomValue.h" -#include "Common/AudioSettings.h" -#include "Common/file.h" -#include "Common/FileSystem.h" -#include "Common/GameSounds.h" -#include "Common/GlobalData.h" -#include "Common/Player.h" -#include "Common/Registry.h" - -#include "GameLogic/GameLogic.h" // For getObjectByID -#include "GameLogic/LogicRandomValue.h" -#include "GameLogic/Object.h" - -#include "GameClient/Drawable.h" // For getPosition -#include "GameClient/GameClient.h" // For getDrawableByID - - -//------------------------------------------------------------------------------------------------- -AudioEventRTS::AudioEventRTS() - : m_eventName(AsciiString::TheEmptyString), - m_priority(AP_NORMAL), - m_volume(-1.0), - m_timeOfDay(TIME_OF_DAY_AFTERNOON), - m_ownerType(OT_INVALID), - m_shouldFade(false), - m_isLogicalAudio(false), - m_filenameToLoad(AsciiString::TheEmptyString), - m_eventInfo(NULL), - m_playingHandle(0), - m_killThisHandle(0), - m_pitchShift(1.0), - m_volumeShift(0.0), - m_loopCount(1), - m_playingAudioIndex(-1), - m_allCount(0), - m_playerIndex(-1), - m_delay(0.0f), - m_uninterruptable(FALSE) -{ - m_attackName.clear(); - m_decayName.clear(); - m_positionOfAudio.zero(); -} - -//------------------------------------------------------------------------------------------------- -AudioEventRTS::AudioEventRTS( const AsciiString& eventName ) - : m_eventName(eventName), - m_priority(AP_NORMAL), - m_volume(-1.0), - m_timeOfDay(TIME_OF_DAY_AFTERNOON), - m_ownerType(OT_INVALID), - m_shouldFade(false), - m_isLogicalAudio(false), - m_filenameToLoad(AsciiString::TheEmptyString), - m_eventInfo(NULL), - m_playingHandle(0), - m_killThisHandle(0), - m_pitchShift(1.0), - m_volumeShift(0.0), - m_loopCount(1), - m_playingAudioIndex(-1), - m_allCount(0), - m_playerIndex(-1), - m_delay(0.0f), - m_uninterruptable(FALSE) -{ - m_attackName.clear(); - m_decayName.clear(); - m_positionOfAudio.zero(); -} - -//------------------------------------------------------------------------------------------------- -AudioEventRTS::AudioEventRTS( const AsciiString& eventName, ObjectID ownerID ) - : m_eventName(eventName), - m_priority(AP_NORMAL), - m_volume(-1.0), - m_timeOfDay(TIME_OF_DAY_AFTERNOON), - m_objectID(ownerID), - m_ownerType(OT_INVALID), - m_shouldFade(false), - m_isLogicalAudio(false), - m_filenameToLoad(AsciiString::TheEmptyString), - m_eventInfo(NULL), - m_playingHandle(0), - m_killThisHandle(0), - m_pitchShift(1.0), - m_volumeShift(0.0), - m_loopCount(1), - m_playingAudioIndex(-1), - m_allCount(0), - m_playerIndex(-1), - m_delay(0.0f), - m_uninterruptable(FALSE) -{ - m_attackName.clear(); - m_decayName.clear(); - - if( m_objectID ) - { - m_ownerType = OT_Object; - } - else - { - m_objectID = INVALID_ID; - } -} - -//------------------------------------------------------------------------------------------------- -AudioEventRTS::AudioEventRTS( const AsciiString& eventName, DrawableID drawableID ) - : m_eventName(eventName), - m_priority(AP_NORMAL), - m_volume(-1.0), - m_timeOfDay(TIME_OF_DAY_AFTERNOON), - m_drawableID(drawableID), - m_ownerType(OT_INVALID), - m_shouldFade(false), - m_isLogicalAudio(false), - m_filenameToLoad(AsciiString::TheEmptyString), - m_eventInfo(NULL), - m_playingHandle(0), - m_killThisHandle(0), - m_pitchShift(1.0), - m_volumeShift(0.0), - m_loopCount(1), - m_playingAudioIndex(-1), - m_allCount(0), - m_playerIndex(-1), - m_delay(0.0f), - m_uninterruptable(FALSE) -{ - m_attackName.clear(); - m_decayName.clear(); - - if( m_drawableID ) - { - m_ownerType = OT_Drawable; - } - else - { - m_drawableID = INVALID_DRAWABLE_ID; - } -} - -//------------------------------------------------------------------------------------------------- -AudioEventRTS::AudioEventRTS( const AsciiString& eventName, const Coord3D *positionOfAudio ) - : m_eventName(eventName), - m_priority(AP_NORMAL), - m_volume(-1.0), - m_timeOfDay(TIME_OF_DAY_AFTERNOON), - m_ownerType(OT_Positional), - m_shouldFade(false), - m_isLogicalAudio(false), - m_filenameToLoad(AsciiString::TheEmptyString), - m_eventInfo(NULL), - m_playingHandle(0), - m_killThisHandle(0), - m_pitchShift(1.0), - m_volumeShift(0.0), - m_loopCount(1), - m_playingAudioIndex(-1), - m_allCount(0), - m_playerIndex(-1), - m_delay(0.0f), - m_uninterruptable(FALSE) -{ - m_positionOfAudio.set( positionOfAudio ); - m_attackName.clear(); - m_decayName.clear(); -} - -//------------------------------------------------------------------------------------------------- -AudioEventRTS::AudioEventRTS( const AudioEventRTS& right ) -{ - m_filenameToLoad = right.m_filenameToLoad; - m_eventInfo = right.m_eventInfo; - m_playingHandle = right.m_playingHandle; - m_killThisHandle = right.m_killThisHandle; - m_eventName = right.m_eventName; - m_priority = right.m_priority; - m_volume = right.m_volume; - m_timeOfDay = right.m_timeOfDay; - m_ownerType = right.m_ownerType; - m_shouldFade = right.m_shouldFade; - m_isLogicalAudio = right.m_isLogicalAudio; - m_pitchShift = right.m_pitchShift; - m_volumeShift = right.m_volumeShift; - m_loopCount = right.m_loopCount; - m_playingAudioIndex = right.m_playingAudioIndex; - m_allCount = right.m_allCount; - m_playerIndex = right.m_playerIndex; - m_delay = right.m_delay; - m_attackName = right.m_attackName; - m_decayName = right.m_decayName; - m_portionToPlayNext = right.m_portionToPlayNext; - m_uninterruptable = right.m_uninterruptable; - - if( m_ownerType == OT_Positional || m_ownerType == OT_Dead ) - { - m_positionOfAudio.set( &right.m_positionOfAudio ); - } - else if( m_ownerType == OT_Drawable ) - { - m_drawableID = right.m_drawableID; - } - else if( m_ownerType == OT_Object ) - { - m_objectID = right.m_objectID; - } - -} - -//------------------------------------------------------------------------------------------------- -AudioEventRTS& AudioEventRTS::operator=( const AudioEventRTS& right ) -{ - m_filenameToLoad = right.m_filenameToLoad; - m_eventInfo = right.m_eventInfo; - m_playingHandle = right.m_playingHandle; - m_killThisHandle = right.m_killThisHandle; - m_eventName = right.m_eventName; - m_priority = right.m_priority; - m_volume = right.m_volume; - m_timeOfDay = right.m_timeOfDay; - m_ownerType = right.m_ownerType; - m_shouldFade = right.m_shouldFade; - m_isLogicalAudio = right.m_isLogicalAudio; - m_pitchShift = right.m_pitchShift; - m_volumeShift = right.m_volumeShift; - m_loopCount = right.m_loopCount; - m_playingAudioIndex = right.m_playingAudioIndex; - m_allCount = right.m_allCount; - m_playerIndex = right.m_playerIndex; - m_delay = right.m_delay; - m_attackName = right.m_attackName; - m_decayName = right.m_decayName; - m_portionToPlayNext = right.m_portionToPlayNext; - m_uninterruptable = right.m_uninterruptable; - - if( m_ownerType == OT_Positional || m_ownerType == OT_Dead ) - { - m_positionOfAudio.set( &right.m_positionOfAudio ); - } - else if( m_ownerType == OT_Drawable ) - { - m_drawableID = right.m_drawableID; - } - else if( m_ownerType == OT_Object ) - { - m_objectID = right.m_objectID; - } - return *this; - -} - -//------------------------------------------------------------------------------------------------- -AudioEventRTS::~AudioEventRTS() -{ -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setEventName( AsciiString name ) -{ - if ((name != m_eventName) && m_eventInfo != NULL) { - // Clear out the audio event info, cause its not valid for the new event. - m_eventInfo = NULL; - } - - m_eventName = name; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::generateFilename( void ) -{ - // A Logic Random Value is used because we may ask "How long will it take to play this sound?" - // In that case, we need the same answer across all pcs. - - if (!m_eventInfo) { - return; - } - - m_filenameToLoad = generateFilenamePrefix(m_eventInfo->m_soundType, false); - - Int which = 0; - - if (m_eventInfo->m_soundType == AT_Music || m_eventInfo->m_soundType == AT_Streaming) { - m_filenameToLoad.concat(m_eventInfo->m_filename); - adjustForLocalization(m_filenameToLoad); - return; - } else { - if (m_eventInfo->m_sounds.size() == 0) { - m_filenameToLoad = AsciiString::TheEmptyString; - return; - } - - - - if (BitIsSet(m_eventInfo->m_control, AC_RANDOM)) - { - if (m_isLogicalAudio) - { - which = GameLogicRandomValue(0, m_eventInfo->m_sounds.size() - 1); - } - else - { - which = GameAudioRandomValue(0, m_eventInfo->m_sounds.size() - 1); - } - - if (which == m_playingAudioIndex && m_eventInfo->m_sounds.size() > 2) - which = ( which + 1 ) % m_eventInfo->m_sounds.size(); - - m_playingAudioIndex = which;//caching random choice to compare next call - - } - else - which = (++m_playingAudioIndex) % m_eventInfo->m_sounds.size(); - - - } - - m_filenameToLoad.concat(m_eventInfo->m_sounds[which]); - m_filenameToLoad.concat(generateFilenameExtension(m_eventInfo->m_soundType)); - adjustForLocalization(m_filenameToLoad); - - // Note: Also generate Delay when generating a filename, cause - // we want delay to apply between every loop of a sound. - m_delay = GameAudioRandomValueReal(m_eventInfo->m_delayMin, m_eventInfo->m_delayMax); -} - -//------------------------------------------------------------------------------------------------- -AsciiString AudioEventRTS::getFilename( void ) -{ - return m_filenameToLoad; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::generatePlayInfo( void ) -{ - m_pitchShift = GameAudioRandomValueReal(m_eventInfo->m_pitchShiftMin, m_eventInfo->m_pitchShiftMax); - m_volumeShift = GameAudioRandomValueReal(1.0f + m_eventInfo->m_volumeShift, 1.0f); // volume shifts are between 0 and 1 - m_loopCount = m_eventInfo->m_loopCount; - - m_portionToPlayNext = PP_Attack; - Int attackSize = m_eventInfo->m_attackSounds.size(); - if (attackSize > 0) { - m_attackName = generateFilenamePrefix(m_eventInfo->m_soundType, false); - // needs to be logic because it needs to be the same on all systems. - Int attackToPlay; - if (m_isLogicalAudio) { - attackToPlay = GameLogicRandomValue(0, attackSize - 1); - } else { - attackToPlay = GameAudioRandomValue(0, attackSize - 1); - } - - m_attackName.concat(m_eventInfo->m_attackSounds[attackToPlay]); - m_attackName.concat(generateFilenameExtension(m_eventInfo->m_soundType)); - adjustForLocalization(m_attackName); - } else { - m_portionToPlayNext = PP_Sound; - } - - Int decaySize = m_eventInfo->m_decaySounds.size(); - if (decaySize > 0) { - m_decayName = generateFilenamePrefix(m_eventInfo->m_soundType, false); - // needs to be logic because it needs to be the same on all systems. - Int decayToPlay; - if (m_isLogicalAudio) { - decayToPlay = GameLogicRandomValue(0, decaySize - 1); - } else { - decayToPlay = GameAudioRandomValue(0, decaySize - 1); - } - - m_decayName.concat(m_eventInfo->m_decaySounds[decayToPlay]); - m_decayName.concat(generateFilenameExtension(m_eventInfo->m_soundType)); - adjustForLocalization(m_decayName); - } - - m_isLogicalAudio = FALSE; -} - -//------------------------------------------------------------------------------------------------- -Real AudioEventRTS::getPitchShift( void ) const -{ - return m_pitchShift; -} - -//------------------------------------------------------------------------------------------------- -Real AudioEventRTS::getVolumeShift( void ) const -{ - return m_volumeShift; -} - -//------------------------------------------------------------------------------------------------- -AsciiString AudioEventRTS::getAttackFilename( void ) const -{ - return m_attackName; -} - -//------------------------------------------------------------------------------------------------- -AsciiString AudioEventRTS::getDecayFilename( void ) const -{ - return m_decayName; -} - -//------------------------------------------------------------------------------------------------- -Real AudioEventRTS::getDelay( void ) const -{ - return m_delay; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::decrementDelay( Real timeToDecrement ) -{ - m_delay -= timeToDecrement; -} - -//------------------------------------------------------------------------------------------------- -PortionToPlay AudioEventRTS::getNextPlayPortion( void ) const -{ - return m_portionToPlayNext; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::advanceNextPlayPortion( void ) -{ - switch (m_portionToPlayNext) - { - case PP_Attack: - m_portionToPlayNext = PP_Sound; - break; - case PP_Sound: - if (m_eventInfo && BitIsSet(m_eventInfo->m_control, AC_ALL)) - { - if (m_allCount == m_eventInfo->m_sounds.size()) { - m_portionToPlayNext = PP_Decay; - } - - // Advance the all count so that we move to the next sound. - ++m_allCount; - } - if (!m_decayName.isEmpty()) { - m_portionToPlayNext = PP_Decay; - } else { - m_portionToPlayNext = PP_Done; - } - break; - case PP_Decay: - m_portionToPlayNext = PP_Done; - break; - } -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setNextPlayPortion( PortionToPlay ptp ) -{ - m_portionToPlayNext = ptp; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::decreaseLoopCount( void ) -{ - if (m_loopCount == 1) { - m_loopCount = -1; - } else if (m_loopCount > 1) { - --m_loopCount; - } -} - -//------------------------------------------------------------------------------------------------- -Bool AudioEventRTS::hasMoreLoops( void ) const -{ - return (m_loopCount >= 0); -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setAudioEventInfo( const AudioEventInfo *eventInfo ) const -{ - m_eventInfo = eventInfo; -} - -//------------------------------------------------------------------------------------------------- -const AudioEventInfo *AudioEventRTS::getAudioEventInfo( void ) const -{ - if (m_eventInfo) { - if (m_eventInfo->m_audioName == m_eventName) { - return m_eventInfo; - } else { - m_eventInfo = NULL; - } - } - - return m_eventInfo; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setPlayingHandle( AudioHandle handle ) -{ - m_playingHandle = handle; -} - -//------------------------------------------------------------------------------------------------- -AudioHandle AudioEventRTS::getPlayingHandle( void ) -{ - return m_playingHandle; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setPosition( const Coord3D *pos ) -{ - if (!pos) { - return; - } - - if (!(m_ownerType == OT_Positional || m_ownerType == OT_INVALID)) { - return; - } - - m_positionOfAudio = *pos; - m_ownerType = OT_Positional; -} - -//------------------------------------------------------------------------------------------------- -const Coord3D* AudioEventRTS::getPosition( void ) -{ - if( m_ownerType != OT_INVALID ) - { - return &m_positionOfAudio; - } - - return NULL; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setObjectID( ObjectID objID ) -{ - if (!(m_ownerType == OT_Object || m_ownerType == OT_INVALID)) { - return; - } - - m_objectID = objID; - m_ownerType = OT_Object; -} - -//------------------------------------------------------------------------------------------------- -ObjectID AudioEventRTS::getObjectID( void ) -{ - if (m_ownerType == OT_Object) { - return m_objectID; - } - - return INVALID_ID; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setDrawableID( DrawableID drawID ) -{ - if (!(m_ownerType == OT_Drawable || m_ownerType == OT_INVALID)) { - return; - } - - m_drawableID = drawID; - m_ownerType = OT_Drawable; -} - -//------------------------------------------------------------------------------------------------- -DrawableID AudioEventRTS::getDrawableID( void ) -{ - if (m_ownerType == OT_Drawable) { - return m_drawableID; - } - - return INVALID_DRAWABLE_ID; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setTimeOfDay( TimeOfDay tod ) -{ - m_timeOfDay = tod; -} - -//------------------------------------------------------------------------------------------------- -TimeOfDay AudioEventRTS::getTimeOfDay( void ) const -{ - return m_timeOfDay; -} - - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setHandleToKill( AudioHandle handleToKill ) -{ - m_killThisHandle = handleToKill; -} - -//------------------------------------------------------------------------------------------------- -AudioHandle AudioEventRTS::getHandleToKill( void ) const -{ - return m_killThisHandle; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setShouldFade( Bool shouldFade ) -{ - m_shouldFade = shouldFade; -} - -//------------------------------------------------------------------------------------------------- -Bool AudioEventRTS::getShouldFade( void ) const -{ - return m_shouldFade; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setIsLogicalAudio( Bool isLogicalAudio ) -{ - m_isLogicalAudio = isLogicalAudio; -} - -//------------------------------------------------------------------------------------------------- -Bool AudioEventRTS::getIsLogicalAudio( void ) const -{ - return m_isLogicalAudio; -} - -//------------------------------------------------------------------------------------------------- -Bool AudioEventRTS::isPositionalAudio( void ) const -{ - if( m_eventInfo ) - { - if( !BitIsSet( m_eventInfo->m_type, ST_WORLD ) ) - { - return FALSE; - } - } - if( m_ownerType != OT_INVALID ) - { - if( m_drawableID != INVALID_DRAWABLE_ID || m_objectID != INVALID_ID || m_ownerType == OT_Positional ) - { - return TRUE; - } - } - return FALSE; -} - -//------------------------------------------------------------------------------------------------- -Bool AudioEventRTS::isCurrentlyPlaying( void ) const -{ - return TheAudio->isCurrentlyPlaying(m_playingHandle); -} - -//------------------------------------------------------------------------------------------------- -AudioPriority AudioEventRTS::getAudioPriority( void ) const -{ - return m_priority; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setAudioPriority( AudioPriority newPriority ) -{ - m_priority = newPriority; - -} - - -//------------------------------------------------------------------------------------------------- -Real AudioEventRTS::getVolume( void ) const -{ - if (m_volume == -1.0f) { - if (m_eventInfo) { - return m_eventInfo->m_volume; - } - return 0.5; - } - - return m_volume; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setVolume( Real vol ) -{ - m_volume = vol; -} - -//------------------------------------------------------------------------------------------------- -const Coord3D *AudioEventRTS::getCurrentPosition( void ) -{ - if (m_ownerType == OT_Positional) - { - return &m_positionOfAudio; - } - else if (m_ownerType == OT_Object) - { - Object *obj = TheGameLogic->findObjectByID(m_objectID); - if (obj) - { - m_positionOfAudio.set( obj->getPosition() ); - } - else - { - m_ownerType = OT_Dead; - } - return &m_positionOfAudio; - } - else if (m_ownerType == OT_Drawable) - { - Drawable *draw = TheGameClient->findDrawableByID(m_drawableID); - if( draw ) - { - m_positionOfAudio.set( draw->getPosition() ); - } - else - { - m_ownerType = OT_Dead; - } - return &m_positionOfAudio; - } - else if( m_ownerType == OT_Dead ) - { - return &m_positionOfAudio; - } - - return NULL; -} - -//------------------------------------------------------------------------------------------------- -AsciiString AudioEventRTS::generateFilenamePrefix( AudioType audioTypeToPlay, Bool localized ) -{ - AsciiString retStr; - retStr = TheAudio->getAudioSettings()->m_audioRoot; - retStr.concat("\\"); - if (audioTypeToPlay == AT_Music) { - retStr.concat(TheAudio->getAudioSettings()->m_musicFolder); - } else if (audioTypeToPlay == AT_Streaming) { - retStr.concat(TheAudio->getAudioSettings()->m_streamingFolder); - } else { - retStr.concat(TheAudio->getAudioSettings()->m_soundsFolder); - } - retStr.concat("\\"); - - if (localized) { - retStr.concat(GetRegistryLanguage()); - retStr.concat("\\"); - } - - return retStr; -} - -//------------------------------------------------------------------------------------------------- -AsciiString AudioEventRTS::generateFilenameExtension( AudioType audioTypeToPlay ) -{ - AsciiString retStr = AsciiString::TheEmptyString; - if (audioTypeToPlay != AT_Music) { - retStr = "."; - retStr.concat(TheAudio->getAudioSettings()->m_soundsExtension); - } - - return retStr; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::adjustForLocalization(AsciiString &strToAdjust) -{ - const char *str = strToAdjust.reverseFind('\\'); - if (!str) { - return; - } - - // try the localized version first so that we're guarenteed to get it - // even if the generic data directory holds a version of the file - AsciiString localizedFilePath = generateFilenamePrefix(m_eventInfo->m_soundType, TRUE); - AsciiString filename = str; - localizedFilePath.concat(filename); - - if (TheFileSystem->doesFileExist(localizedFilePath.str())) { - strToAdjust = localizedFilePath; - } - // else there was no localized version, so leave the path we received unchanged - - return; -} - -//------------------------------------------------------------------------------------------------- -Int AudioEventRTS::getPlayerIndex( void ) const -{ - if (m_ownerType == OT_Object) { - Object *obj = TheGameLogic->findObjectByID(m_objectID); - if (obj) { - return obj->getControllingPlayer()->getPlayerIndex(); - } - } else if (m_ownerType == OT_Drawable) { - Drawable *draw = TheGameClient->findDrawableByID(m_drawableID); - if (draw) { - Object *obj = draw->getObject(); - if (obj) { - return obj->getControllingPlayer()->getPlayerIndex(); - } - } - } - - return m_playerIndex; -} - -//------------------------------------------------------------------------------------------------- -void AudioEventRTS::setPlayerIndex( Int playerNdx ) -{ - m_playerIndex = playerNdx; -} diff --git a/Generals/Code/GameEngine/Source/Common/Audio/AudioRequest.cpp b/Generals/Code/GameEngine/Source/Common/Audio/AudioRequest.cpp deleted file mode 100644 index 2e9406961ef..00000000000 --- a/Generals/Code/GameEngine/Source/Common/Audio/AudioRequest.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - - -#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine - -#include "Common/AudioRequest.h" - - -AudioRequest::~AudioRequest() -{ - -} diff --git a/Generals/Code/GameEngine/Source/Common/Audio/GameAudio.cpp b/Generals/Code/GameEngine/Source/Common/Audio/GameAudio.cpp deleted file mode 100644 index 66717162e7f..00000000000 --- a/Generals/Code/GameEngine/Source/Common/Audio/GameAudio.cpp +++ /dev/null @@ -1,1166 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//---------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: GameAudio.cpp -// -// Created: 5/01/01 -// -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------------- - -#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine -#include "Common/GameAudio.h" - -#include "Common/AudioAffect.h" -#include "Common/AudioEventInfo.h" -#include "Common/AudioEventRTS.h" -#include "Common/AudioHandleSpecialValues.h" -#include "Common/AudioRequest.h" -#include "Common/AudioSettings.h" -#include "Common/FileSystem.h" -#include "Common/GameEngine.h" -#include "Common/GameMusic.h" -#include "Common/GameSounds.h" -#include "Common/MiscAudio.h" -#include "Common/OSDisplay.h" -#include "Common/Player.h" -#include "Common/PlayerList.h" -#include "Common/UserPreferences.h" - -#include "GameClient/ControlBar.h" -#include "GameClient/Drawable.h" -#include "GameClient/View.h" - -#include "GameLogic/GameLogic.h" -#include "GameLogic/TerrainLogic.h" - -#include "WWMath/matrix3d.h" - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -static const char* TheSpeakerTypes[] = -{ - "2 Speakers", - "Headphones", - "Surround Sound", - "4 Speaker", - "5.1 Surround", - "7.1 Surround", - NULL -}; - -static const Int TheSpeakerTypesCount = sizeof(TheSpeakerTypes) / sizeof(TheSpeakerTypes[0]); - -static void parseSpeakerType( INI *ini, void *instance, void *store, const void *userData ); - -// Field Parse table for Audio Settings /////////////////////////////////////////////////////////// -static const FieldParse audioSettingsFieldParseTable[] = -{ - { "AudioRoot", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_audioRoot) }, - { "SoundsFolder", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_soundsFolder) }, - { "MusicFolder", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_musicFolder) }, - { "StreamingFolder", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_streamingFolder) }, - { "SoundsExtension", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_soundsExtension) }, - - { "UseDigital", INI::parseBool, NULL, offsetof( AudioSettings, m_useDigital) }, - { "UseMidi", INI::parseBool, NULL, offsetof( AudioSettings, m_useMidi) }, - { "OutputRate", INI::parseInt, NULL, offsetof( AudioSettings, m_outputRate) }, - { "OutputBits", INI::parseInt, NULL, offsetof( AudioSettings, m_outputBits) }, - { "OutputChannels", INI::parseInt, NULL, offsetof( AudioSettings, m_outputChannels) }, - { "SampleCount2D", INI::parseInt, NULL, offsetof( AudioSettings, m_sampleCount2D) }, - { "SampleCount3D", INI::parseInt, NULL, offsetof( AudioSettings, m_sampleCount3D) }, - { "StreamCount", INI::parseInt, NULL, offsetof( AudioSettings, m_streamCount) }, - - { "Preferred3DHW1", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_preferred3DProvider[0]) }, - { "Preferred3DHW2", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_preferred3DProvider[1]) }, - { "Preferred3DHW3", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_preferred3DProvider[2]) }, - { "Preferred3DHW4", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_preferred3DProvider[3]) }, - - { "Preferred3DSW", INI::parseAsciiString, NULL, offsetof( AudioSettings, m_preferred3DProvider[4]) }, - - { "Default2DSpeakerType", parseSpeakerType, NULL, offsetof( AudioSettings, m_defaultSpeakerType2D) }, - { "Default3DSpeakerType", parseSpeakerType, NULL, offsetof( AudioSettings, m_defaultSpeakerType3D) }, - - { "MinSampleVolume", INI::parsePercentToReal, NULL, offsetof( AudioSettings, m_minVolume) }, - { "GlobalMinRange", INI::parseInt, NULL, offsetof( AudioSettings, m_globalMinRange) }, - { "GlobalMaxRange", INI::parseInt, NULL, offsetof( AudioSettings, m_globalMaxRange) }, - { "TimeBetweenDrawableSounds", INI::parseDurationUnsignedInt, NULL, offsetof( AudioSettings, m_drawableAmbientFrames) }, - { "TimeToFadeAudio", INI::parseDurationUnsignedInt, NULL, offsetof( AudioSettings, m_fadeAudioFrames) }, - { "AudioFootprintInBytes",INI::parseUnsignedInt, NULL, offsetof( AudioSettings, m_maxCacheSize) }, - { "Relative2DVolume", INI::parsePercentToReal, NULL, offsetof( AudioSettings, m_relative2DVolume ) }, - { "DefaultSoundVolume", INI::parsePercentToReal, NULL, offsetof( AudioSettings, m_defaultSoundVolume) }, - { "Default3DSoundVolume", INI::parsePercentToReal, NULL, offsetof( AudioSettings, m_default3DSoundVolume) }, - { "DefaultSpeechVolume", INI::parsePercentToReal, NULL, offsetof( AudioSettings, m_defaultSpeechVolume) }, - { "DefaultMusicVolume", INI::parsePercentToReal, NULL, offsetof( AudioSettings, m_defaultMusicVolume) }, - { "MicrophoneDesiredHeightAboveTerrain", INI::parseReal, NULL, offsetof( AudioSettings, m_microphoneDesiredHeightAboveTerrain ) }, - { "MicrophoneMaxPercentageBetweenGroundAndCamera", INI::parsePercentToReal, NULL, offsetof( AudioSettings, m_microphoneMaxPercentageBetweenGroundAndCamera ) }, - { "ZoomMinDistance", INI::parseReal, NULL, offsetof( AudioSettings, m_zoomMinDistance ) }, - { "ZoomMaxDistance", INI::parseReal, NULL, offsetof( AudioSettings, m_zoomMaxDistance ) }, - { "ZoomSoundVolumePercentageAmount", INI::parsePercentToReal, NULL, offsetof( AudioSettings, m_zoomSoundVolumePercentageAmount ) }, - - { NULL, NULL, NULL, NULL } -}; - -// Singleton TheAudio ///////////////////////////////////////////////////////////////////////////// -AudioManager *TheAudio = NULL; - - -// AudioManager Device Independent functions ////////////////////////////////////////////////////// -AudioManager::AudioManager() : - m_soundOn(TRUE), - m_sound3DOn(TRUE), - m_musicOn(TRUE), - m_speechOn(TRUE), - m_music(NULL), - m_sound(NULL), - m_surroundSpeakers(FALSE), - m_hardwareAccel(FALSE), - m_musicPlayingFromCD(FALSE) -{ - // Added by Sadullah Nader - m_adjustedVolumes.clear(); - m_audioRequests.clear(); - m_listenerPosition.zero(); - m_musicTracks.clear(); - m_musicVolume = 0.0f; - m_sound3DVolume = 0.0f; - m_soundVolume = 0.0f; - m_speechVolume = 0.0f; - m_systemMusicVolume = 0.0f; - m_systemSound3DVolume = 0.0f; - m_systemSoundVolume = 0.0f; - m_systemSpeechVolume = 0.0f; - m_volumeHasChanged = FALSE; - // - - m_listenerOrientation.set(0.0, 1.0, 0.0); - theAudioHandlePool = AHSV_FirstHandle; - m_audioSettings = NEW AudioSettings; - m_miscAudio = NEW MiscAudio; - m_silentAudioEvent = NEW AudioEventRTS; - m_savedValues = NULL; - m_disallowSpeech = FALSE; -} - -//------------------------------------------------------------------------------------------------- -AudioManager::~AudioManager() -{ - // cleanup all of the loaded AudioEventInfos - AudioEventInfoHashIt it; - for (it = m_allAudioEventInfo.begin(); it != m_allAudioEventInfo.end(); ++it) { - AudioEventInfo *eventInfo = (*it).second; - if (eventInfo) { - deleteInstance(eventInfo); - eventInfo = NULL; - } - } - - delete m_silentAudioEvent; - m_silentAudioEvent = NULL; - - delete m_music; - m_music = NULL; - - delete m_sound; - m_sound = NULL; - - delete m_miscAudio; - m_miscAudio = NULL; - - delete m_audioSettings; - m_audioSettings = NULL; - - if (m_savedValues) - delete [] m_savedValues; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::init() -{ - INI ini; - ini.load( AsciiString( "Data\\INI\\AudioSettings.ini" ), INI_LOAD_OVERWRITE, NULL); - - ini.load( AsciiString( "Data\\INI\\Default\\Music.ini" ), INI_LOAD_OVERWRITE, NULL ); - ini.load( AsciiString( "Data\\INI\\Music.ini" ), INI_LOAD_OVERWRITE, NULL ); - - ini.load( AsciiString( "Data\\INI\\Default\\SoundEffects.ini" ), INI_LOAD_OVERWRITE, NULL ); - ini.load( AsciiString( "Data\\INI\\SoundEffects.ini" ), INI_LOAD_OVERWRITE, NULL ); - - ini.load( AsciiString( "Data\\INI\\Default\\Speech.ini" ), INI_LOAD_OVERWRITE, NULL ); - ini.load( AsciiString( "Data\\INI\\Speech.ini" ), INI_LOAD_OVERWRITE, NULL ); - - ini.load( AsciiString( "Data\\INI\\Default\\Voice.ini" ), INI_LOAD_OVERWRITE, NULL ); - ini.load( AsciiString( "Data\\INI\\Voice.ini" ), INI_LOAD_OVERWRITE, NULL ); - - // do the miscellaneous sound files last so that we find the audioeventrts associated with the events. - ini.load( AsciiString( "Data\\INI\\MiscAudio.ini" ), INI_LOAD_OVERWRITE, NULL); - - // determine if one of the music tracks exists. Since their now BIGd, one implies all. - // If they don't exist, then attempt to load them from the CD. - if (!isMusicAlreadyLoaded()) - { - m_musicPlayingFromCD = TRUE; - while (TRUE) - { - // @todo Unload any files from CD first. - jkmcd - - TheFileSystem->loadMusicFilesFromCD(); - if (isMusicAlreadyLoaded()) - { - break; - } - // We loop infinitely on the splash screen if we don't allow breaking out of this loop. -//#if !defined( RTS_DEBUG ) - else - { - // Display the warning. - - if (OSDisplayWarningBox("GUI:InsertCDPrompt", "GUI:InsertCDMessage", OSDBT_OK | OSDBT_CANCEL, OSDOF_SYSTEMMODAL | OSDOF_EXCLAMATIONICON) == OSDBT_CANCEL) { - //TheGameEngine->setQuitting(TRUE); // Can't do this to WorldBuilder - break; - } - } -//#endif - } - } - - m_music = NEW MusicManager; - m_sound = NEW SoundManager; - - // Set our system volumes from the user's preferred settings, not the defaults. - m_systemMusicVolume = getAudioSettings() ? getAudioSettings()->m_preferredMusicVolume : 0.55f; - m_systemSoundVolume = getAudioSettings() ? getAudioSettings()->m_preferredSoundVolume : 0.75f; - m_systemSound3DVolume = getAudioSettings() ? getAudioSettings()->m_preferred3DSoundVolume: 0.75f; - m_systemSpeechVolume = getAudioSettings() ? getAudioSettings()->m_preferredSpeechVolume : 0.55f; - - m_scriptMusicVolume = 1.0f; - m_scriptSoundVolume = 1.0f; - m_scriptSound3DVolume = 1.0f; - m_scriptSpeechVolume = 1.0f; - - m_musicVolume = m_systemMusicVolume; - m_soundVolume = m_systemSoundVolume; - m_sound3DVolume = m_systemSound3DVolume; - m_speechVolume = m_systemSpeechVolume; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::postProcessLoad() -{ - -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::reset() -{ - // clear out any adjusted volumes we might have set. - m_adjustedVolumes.clear(); - - // adjust the scripted volumes, and reset the - m_scriptMusicVolume = 1.0f; - m_scriptSoundVolume = 1.0f; - m_scriptSound3DVolume = 1.0f; - m_scriptSpeechVolume = 1.0f; - - // restore the final values to the - m_musicVolume = m_systemMusicVolume; - m_soundVolume = m_systemSoundVolume; - m_sound3DVolume = m_systemSound3DVolume; - m_speechVolume = m_systemSpeechVolume; - - m_disallowSpeech = FALSE; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::update() -{ - Coord3D groundPos, microphonePos; - TheTacticalView->getPosition( &groundPos ); - Real angle = TheTacticalView->getAngle(); - Matrix3D rot = Matrix3D::Identity; - rot.Rotate_Z( angle ); - Vector3 forward( 0, 1, 0 ); - rot.mulVector3( forward ); - - Real desiredHeight = TheAudio->getAudioSettings()->m_microphoneDesiredHeightAboveTerrain; - Real maxPercentage = TheAudio->getAudioSettings()->m_microphoneMaxPercentageBetweenGroundAndCamera; - - Coord3D lookTo; - lookTo.set(forward.X, forward.Y, forward.Z); - - //Kris: At this point, the microphone is calculated to be at the ground position where the camera is looking at. - //Instead we want to move the microphone towards the camera. Hopefully, it'll be a desired altitude, but if it - //gets too close to the camera (or even past it), that would be undesirable. Therefore, we have a backup method - //of making sure we only go a certain percentage towards the camera or the desired height, whichever occurs first. - Coord3D cameraPos = TheTacticalView->get3DCameraPosition(); - Coord3D groundToCameraVector; - groundToCameraVector.set( &cameraPos ); - groundToCameraVector.sub( &groundPos ); - Real bestScaleFactor; - - if( cameraPos.z <= desiredHeight || groundToCameraVector.z <= 0.0f ) - { - //Use the percentage calculation! - bestScaleFactor = maxPercentage; - } - else - { - //Calculate the stopping position of the groundToCameraVector when we force z to be m_microphoneDesiredHeightAboveTerrain - Real zScale = desiredHeight / groundToCameraVector.z; - - //Use the smallest of the two scale calculations - bestScaleFactor = MIN( maxPercentage, zScale ); - } - - //Now apply the best scalar to the ground-to-camera vector. - groundToCameraVector.scale( bestScaleFactor ); - - //Set the microphone to be the ground position adjusted for terrain plus the vector we just calculated. - groundPos.z = TheTerrainLogic->getGroundHeight( groundPos.x, groundPos.y ); - microphonePos.set( &groundPos ); - microphonePos.add( &groundToCameraVector ); - - //Viola! A properly placed microphone. - setListenerPosition( µphonePos, &lookTo ); - - - //Now determine if we would like to boost the volume based on the camera being close to the microphone! - Real maxBoostScalar = TheAudio->getAudioSettings()->m_zoomSoundVolumePercentageAmount; - Real minDist = TheAudio->getAudioSettings()->m_zoomMinDistance; - Real maxDist = TheAudio->getAudioSettings()->m_zoomMaxDistance; - - //We can't boost a sound above 100%, instead reduce the normal sound level. - m_zoomVolume = 1.0f - maxBoostScalar; - - //Are we even using a boost? - if( maxBoostScalar > 0.0f ) - { - //How far away is the camera from the microphone? - Coord3D vector = cameraPos; - vector.sub( µphonePos ); - Real dist = vector.length(); - - if( dist < minDist ) - { - //Max volume! - m_zoomVolume = 1.0f; - } - else if( dist < maxDist ) - { - //Determine what the boost amount will be. - Real scalar = (dist - minDist) / (maxDist - minDist); - m_zoomVolume = 1.0f - scalar * maxBoostScalar; - } - } - - set3DVolumeAdjustment( m_zoomVolume ); - -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::getInfoForAudioEvent( const AudioEventRTS *eventToFindAndFill ) const -{ - if (!eventToFindAndFill) { - return; - } - - if (eventToFindAndFill->getAudioEventInfo()) { - // already done - return; - } - - eventToFindAndFill->setAudioEventInfo(findAudioEventInfo(eventToFindAndFill->getEventName())); -} - -//------------------------------------------------------------------------------------------------- -AudioHandle AudioManager::addAudioEvent(const AudioEventRTS *eventToAdd) -{ - if (eventToAdd->getEventName().isEmpty() || eventToAdd->getEventName() == AsciiString("NoSound")) { - return AHSV_NoSound; - } - -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("AUDIO (%d): Received addAudioEvent('%s')", TheGameLogic->getFrame(), eventToAdd->getEventName().str())); -#endif - if (!eventToAdd->getAudioEventInfo()) { - getInfoForAudioEvent(eventToAdd); - if (!eventToAdd->getAudioEventInfo()) { - DEBUG_CRASH(("No info for requested audio event '%s'", eventToAdd->getEventName().str())); - return AHSV_Error; - } - } - - switch (eventToAdd->getAudioEventInfo()->m_soundType) - { - case AT_Music: - if (!isOn(AudioAffect_Music)) - return AHSV_NoSound; - break; - case AT_SoundEffect: - if (!isOn(AudioAffect_Sound) || !isOn(AudioAffect_Sound3D)) - return AHSV_NoSound; - break; - case AT_Streaming: - if (!isOn(AudioAffect_Speech)) - return AHSV_NoSound; - break; - } - - // if we're currently playing uninterruptable speech, then disallow the addition of this sample - if (getDisallowSpeech() && eventToAdd->getAudioEventInfo()->m_soundType == AT_Streaming) { - return AHSV_NoSound; - } - - - AudioEventRTS *audioEvent = MSGNEW("AudioEventRTS") AudioEventRTS(*eventToAdd); // poolify - audioEvent->setPlayingHandle( allocateNewHandle() ); - audioEvent->generateFilename(); // which file are we actually going to play? - ((AudioEventRTS*)eventToAdd)->setPlayingAudioIndex( audioEvent->getPlayingAudioIndex() ); - audioEvent->generatePlayInfo(); // generate pitch shift and volume shift now as well - - std::list >::iterator it; - for (it = m_adjustedVolumes.begin(); it != m_adjustedVolumes.end(); ++it) { - if (it->first == audioEvent->getEventName()) { - audioEvent->setVolume(it->second); - break; - } - } - - if (!audioEvent->getUninterruptable()) { - if (!shouldPlayLocally(audioEvent)) { - releaseAudioEventRTS(audioEvent); - return AHSV_NotForLocal; - } - } - - // cull muted audio - if (audioEvent->getVolume() < TheAudio->getAudioSettings()->m_minVolume) { -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG((" - culled due to muting (%d).", audioEvent->getVolume())); -#endif - releaseAudioEventRTS(audioEvent); - return AHSV_Muted; - } - - AudioType type = eventToAdd->getAudioEventInfo()->m_soundType; - if (type == AT_Music) - { - m_music->addAudioEvent(audioEvent); - } - else - { - //Possible to nuke audioEvent inside. - m_sound->addAudioEvent(audioEvent); - } - - if( audioEvent ) - { - return audioEvent->getPlayingHandle(); - } - return AHSV_NoSound; -} - -//------------------------------------------------------------------------------------------------- -Bool AudioManager::isValidAudioEvent(const AudioEventRTS *eventToCheck) const -{ - if (eventToCheck->getEventName().isEmpty()) { - return false; - } - - getInfoForAudioEvent(eventToCheck); - - return (eventToCheck->getAudioEventInfo() != NULL); -} - -//------------------------------------------------------------------------------------------------- -Bool AudioManager::isValidAudioEvent( AudioEventRTS *eventToCheck ) const -{ - if( eventToCheck->getEventName().isEmpty() ) - { - return false; - } - - getInfoForAudioEvent( eventToCheck ); - - return( eventToCheck->getAudioEventInfo() ); -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::addTrackName( const AsciiString& trackName ) -{ - m_musicTracks.push_back(trackName); -} - -//------------------------------------------------------------------------------------------------- -AsciiString AudioManager::nextTrackName(const AsciiString& currentTrack ) -{ - std::vector::iterator it; - for (it = m_musicTracks.begin(); it != m_musicTracks.end(); ++it) { - if (*it == currentTrack) { - break; - } - } - - if (it != m_musicTracks.end()) { - ++it; - } - - if (it == m_musicTracks.end()) { - it = m_musicTracks.begin(); - if (it == m_musicTracks.end()) { - return AsciiString::TheEmptyString; - } - } - - return *it; -} - -//------------------------------------------------------------------------------------------------- -AsciiString AudioManager::prevTrackName(const AsciiString& currentTrack ) -{ - std::vector::reverse_iterator rit; - for (rit = m_musicTracks.rbegin(); rit != m_musicTracks.rend(); ++rit) { - if (*rit == currentTrack) { - break; - } - } - - if (rit != m_musicTracks.rend()) { - ++rit; - } - - if (rit == m_musicTracks.rend()) { - rit = m_musicTracks.rbegin(); - if (rit == m_musicTracks.rend()) { - return AsciiString::TheEmptyString; - } - } - - return *rit; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::removeAudioEvent(AudioHandle audioEvent) -{ - if (audioEvent == AHSV_StopTheMusic || audioEvent == AHSV_StopTheMusicFade) { - m_music->removeAudioEvent(audioEvent); - return; - } - - if (audioEvent < AHSV_FirstHandle) { - return; - } - - AudioRequest *req = allocateAudioRequest( false ); - req->m_handleToInteractOn = audioEvent; - req->m_request = AR_Stop; - appendAudioRequest( req ); -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::setAudioEventEnabled( AsciiString eventToAffect, Bool enable ) -{ - setAudioEventVolumeOverride(eventToAffect, (enable ? -1.0f : 0.0f) ); -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::setAudioEventVolumeOverride( AsciiString eventToAffect, Real newVolume ) -{ - if (eventToAffect == AsciiString::TheEmptyString) { - m_adjustedVolumes.clear(); - return; - } - - // Find any playing audio events and adjust their volume accordingly. - if (newVolume != -1.0f) { - adjustVolumeOfPlayingAudio(eventToAffect, newVolume); - } - - std::list >::iterator it; - for (it = m_adjustedVolumes.begin(); it != m_adjustedVolumes.end(); ++it) { - if (it->first == eventToAffect) { - if (newVolume == -1.0f) { - m_adjustedVolumes.erase(it); - return; - } else { - it->second = newVolume; - return; - } - } - } - - if (newVolume != -1.0f) { - std::pair newPair; - newPair.first = eventToAffect; - newPair.second = newVolume; - m_adjustedVolumes.push_front(newPair); - } -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::removeAudioEvent( AsciiString eventToRemove ) -{ - removePlayingAudio( eventToRemove ); -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::removeDisabledEvents() -{ - removeAllDisabledAudio(); -} - -//------------------------------------------------------------------------------------------------- -Bool AudioManager::isCurrentlyPlaying( AudioHandle audioEvent ) -{ - return true; -} - -//------------------------------------------------------------------------------------------------- -UnsignedInt AudioManager::translateSpeakerTypeToUnsignedInt( const AsciiString& speakerType ) -{ - for (UnsignedInt i = 0; TheSpeakerTypes[i]; ++i) { - if (TheSpeakerTypes[i] == speakerType) { - return i; - } - } - - return 0; -} - -//------------------------------------------------------------------------------------------------- -AsciiString AudioManager::translateUnsignedIntToSpeakerType( UnsignedInt speakerType ) -{ - if (speakerType >= TheSpeakerTypesCount) { - return TheSpeakerTypes[0]; - } - - return TheSpeakerTypes[speakerType]; -} - -//------------------------------------------------------------------------------------------------- -Bool AudioManager::isOn( AudioAffect whichToGet ) const -{ - if (whichToGet & AudioAffect_Music) { - return m_musicOn; - } else if (whichToGet & AudioAffect_Sound) { - return m_soundOn; - } else if (whichToGet & AudioAffect_Sound3D) { - return m_sound3DOn; - } - - // Speech - return m_speechOn; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::setOn( Bool turnOn, AudioAffect whichToAffect ) -{ - if (whichToAffect & AudioAffect_Music) { - m_musicOn = turnOn; - } - - if (whichToAffect & AudioAffect_Sound) { - m_soundOn = turnOn; - } - - if (whichToAffect & AudioAffect_Sound3D) { - m_sound3DOn = turnOn; - } - - if (whichToAffect & AudioAffect_Speech) { - m_speechOn = turnOn; - } -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::setVolume( Real volume, AudioAffect whichToAffect ) -{ - if (whichToAffect & AudioAffect_Music) { - if (whichToAffect & AudioAffect_SystemSetting) { - m_systemMusicVolume = volume; - } else { - m_scriptMusicVolume = volume; - } - - m_musicVolume = m_scriptMusicVolume * m_systemMusicVolume; - } - - if (whichToAffect & AudioAffect_Sound) { - if (whichToAffect & AudioAffect_SystemSetting) { - m_systemSoundVolume = volume; - } else { - m_scriptSoundVolume = volume; - } - - m_soundVolume = m_scriptSoundVolume * m_systemSoundVolume; - } - - if (whichToAffect & AudioAffect_Sound3D) { - if (whichToAffect & AudioAffect_SystemSetting) { - m_systemSound3DVolume = volume; - } else { - m_scriptSound3DVolume = volume; - } - m_sound3DVolume = m_scriptSound3DVolume * m_systemSound3DVolume; - } - - if (whichToAffect & AudioAffect_Speech) { - if (whichToAffect & AudioAffect_SystemSetting) { - m_systemSpeechVolume = volume; - } else { - m_scriptSpeechVolume = volume; - } - m_speechVolume = m_scriptSpeechVolume * m_systemSpeechVolume; - } - - m_volumeHasChanged = true; -} - -//------------------------------------------------------------------------------------------------- -Real AudioManager::getVolume( AudioAffect whichToGet ) -{ - if (whichToGet & AudioAffect_Music) { - return m_musicVolume; - } else if (whichToGet & AudioAffect_Sound) { - return m_soundVolume; - } else if (whichToGet & AudioAffect_Sound3D) { - return m_sound3DVolume; - } - - // Speech - return m_speechVolume; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::set3DVolumeAdjustment( Real volumeAdjustment ) -{ - m_sound3DVolume = volumeAdjustment * m_scriptSound3DVolume * m_systemSound3DVolume; - - // clamp - if (m_sound3DVolume < 0.0f) - m_sound3DVolume = 0.0f; - - if (m_sound3DVolume > 1.0f) - m_sound3DVolume = 1.0f; - - if ( ! has3DSensitiveStreamsPlaying() ) - m_volumeHasChanged = TRUE; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::setListenerPosition( const Coord3D *newListenerPos, const Coord3D *newListenerOrientation ) -{ - m_listenerPosition = *newListenerPos; - m_listenerOrientation = *newListenerOrientation; -} - -//------------------------------------------------------------------------------------------------- -const Coord3D *AudioManager::getListenerPosition( void ) const -{ - return &m_listenerPosition; -} - -//------------------------------------------------------------------------------------------------- -AudioRequest *AudioManager::allocateAudioRequest( Bool useAudioEvent ) -{ - AudioRequest *audioReq = newInstance(AudioRequest); - audioReq->m_usePendingEvent = useAudioEvent; - audioReq->m_requiresCheckForSample = false; - return audioReq; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::releaseAudioRequest( AudioRequest *requestToRelease ) -{ - if (requestToRelease) { - deleteInstance(requestToRelease); - } -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::appendAudioRequest( AudioRequest *m_request ) -{ - m_audioRequests.push_back(m_request); -} - -//------------------------------------------------------------------------------------------------- -// Remove all pending audio requests -void AudioManager::removeAllAudioRequests( void ) -{ - std::list::iterator it; - for ( it = m_audioRequests.begin(); it != m_audioRequests.end(); it++ ) { - releaseAudioRequest( *it ); - } - - m_audioRequests.clear(); -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::processRequestList( void ) -{ - -} - -//------------------------------------------------------------------------------------------------- -AudioEventInfo *AudioManager::newAudioEventInfo( AsciiString audioName ) -{ - AudioEventInfo *eventInfo = findAudioEventInfo(audioName); - if (eventInfo) { - DEBUG_CRASH(("Requested add of '%s' multiple times. Is this intentional? - jkmcd", audioName.str())); - return eventInfo; - } - - m_allAudioEventInfo[audioName] = newInstance(AudioEventInfo); - return m_allAudioEventInfo[audioName]; -} - -//------------------------------------------------------------------------------------------------- -// Add an AudioEventInfo structure allocated elsewhere to the audio event list -void AudioManager::addAudioEventInfo( AudioEventInfo * newEvent ) -{ - // Warning: Don't try to copy the structure. It may be a derived class - AudioEventInfo *eventInfo = findAudioEventInfo( newEvent->m_audioName ); - if (eventInfo) - { - DEBUG_CRASH(("Requested add of '%s' multiple times. Is this intentional? - jkmcd", newEvent->m_audioName.str())); - *eventInfo = *newEvent; - } - else - { - m_allAudioEventInfo[newEvent->m_audioName] = newEvent; - } -} - -//------------------------------------------------------------------------------------------------- -AudioEventInfo *AudioManager::findAudioEventInfo( AsciiString eventName ) const -{ - AudioEventInfoHash::const_iterator it; - it = m_allAudioEventInfo.find(eventName); - if (it == m_allAudioEventInfo.end()) { - return NULL; - } - - return (*it).second; -} - -//------------------------------------------------------------------------------------------------- -// Remove all AudioEventInfo's with the m_isLevelSpecific flag -void AudioManager::removeLevelSpecificAudioEventInfos(void) -{ - AudioEventInfoHash::iterator it = m_allAudioEventInfo.begin(); - - while ( it != m_allAudioEventInfo.end() ) - { - AudioEventInfoHash::iterator next = it; // Make sure erase doesn't cause problems - next++; - - if ( it->second->isLevelSpecific() ) - { - deleteInstance(it->second); - m_allAudioEventInfo.erase( it ); - } - - it = next; - } - -} - -//------------------------------------------------------------------------------------------------- -const AudioSettings *AudioManager::getAudioSettings( void ) const -{ - return m_audioSettings; -} - -//------------------------------------------------------------------------------------------------- -AudioSettings *AudioManager::friend_getAudioSettings( void ) -{ - return m_audioSettings; -} - -//------------------------------------------------------------------------------------------------- -const MiscAudio *AudioManager::getMiscAudio( void ) const -{ - return m_miscAudio; -} - -//------------------------------------------------------------------------------------------------- -MiscAudio *AudioManager::friend_getMiscAudio( void ) -{ - return m_miscAudio; -} - -//------------------------------------------------------------------------------------------------- -const FieldParse *AudioManager::getFieldParseTable( void ) const -{ - return audioSettingsFieldParseTable; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::refreshCachedVariables() -{ - m_hardwareAccel = isCurrentProviderHardwareAccelerated(); - m_surroundSpeakers = isCurrentSpeakerTypeSurroundSound(); -} - -//------------------------------------------------------------------------------------------------- -Real AudioManager::getAudioLengthMS( const AudioEventRTS *event ) -{ - if (!event->getAudioEventInfo()) { - getInfoForAudioEvent(event); - if (!event->getAudioEventInfo()) { - return 0.0f; - } - } - - AudioEventRTS tmpEvent = *event; - - tmpEvent.generateFilename(); - tmpEvent.generatePlayInfo(); - return getFileLengthMS(tmpEvent.getAttackFilename()) + - getFileLengthMS(tmpEvent.getFilename()) + - getFileLengthMS(tmpEvent.getDecayFilename()); -} - -//------------------------------------------------------------------------------------------------- -Bool AudioManager::isMusicAlreadyLoaded(void) const -{ - const AudioEventInfo *musicToLoad = NULL; - AudioEventInfoHash::const_iterator it; - for (it = m_allAudioEventInfo.begin(); it != m_allAudioEventInfo.end(); ++it) { - if (it->second) { - const AudioEventInfo *aet = it->second; - if (aet->m_soundType == AT_Music) { - musicToLoad = aet; - } - } - } - - if (!musicToLoad) { - return FALSE; - } - - AudioEventRTS aud; - aud.setAudioEventInfo(musicToLoad); - aud.generateFilename(); - - AsciiString astr = aud.getFilename(); - - return (TheFileSystem->doesFileExist(astr.str())); -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::findAllAudioEventsOfType( AudioType audioType, std::vector& allEvents ) -{ - AudioEventInfoHashIt it; - for (it = m_allAudioEventInfo.begin(); it != m_allAudioEventInfo.end(); ++it) { - AudioEventInfo *aud = (*it).second; - if (aud->m_soundType == audioType) { - allEvents.push_back(aud); - } - } -} - -//------------------------------------------------------------------------------------------------- -Bool AudioManager::isCurrentProviderHardwareAccelerated() -{ - for (Int i = 0; i < MAX_HW_PROVIDERS; ++i) { - if (getProviderName(getSelectedProvider()) == TheAudio->getAudioSettings()->m_preferred3DProvider[i]) { - return TRUE; - } - } - - return FALSE; -} - -//------------------------------------------------------------------------------------------------- -Bool AudioManager::isCurrentSpeakerTypeSurroundSound() -{ - return (getSpeakerType() == TheAudio->getAudioSettings()->m_defaultSpeakerType3D); -} - -//------------------------------------------------------------------------------------------------- -Bool AudioManager::shouldPlayLocally(const AudioEventRTS *audioEvent) -{ - Player *localPlayer = ThePlayerList->getLocalPlayer(); - if( !localPlayer->isPlayerActive() ) - { - //We are dead, thus are observing. Get the player we are observing. It's - //possible that we're not looking at any player, therefore it can be NULL. - localPlayer = TheControlBar->getObserverLookAtPlayer(); - } - - const AudioEventInfo *ei = audioEvent->getAudioEventInfo(); - - // Music should always play locally. - if (ei->m_soundType == AT_Music) { - return TRUE; - } - - if (!BitIsSet(ei->m_type, (ST_PLAYER | ST_ALLIES | ST_ENEMIES | ST_EVERYONE))) { - DEBUG_CRASH(("No player restrictions specified for '%s'. Using Everyone.", ei->m_audioName.str())); - return TRUE; - } - - if (BitIsSet(ei->m_type, ST_EVERYONE)) { - return TRUE; - } - - Player *owningPlayer = ThePlayerList->getNthPlayer(audioEvent->getPlayerIndex()); - - if (BitIsSet(ei->m_type, ST_PLAYER) && BitIsSet(ei->m_type, ST_UI) && owningPlayer == NULL) { - DEBUG_ASSERTCRASH(!TheGameLogic->isInGameLogicUpdate(), ("Playing %s sound -- player-based UI sound without specifying a player.")); - return TRUE; - } - - if (owningPlayer == NULL) { - DEBUG_CRASH(("Sound '%s' expects an owning player, but the audio event that created it didn't specify one.", ei->m_audioName.str())); - return FALSE; - } - - if( !localPlayer ) - { - return FALSE; - } - - const Team *localTeam = localPlayer->getDefaultTeam(); - if (localTeam == NULL) { - return FALSE; - } - - if (BitIsSet(ei->m_type, ST_PLAYER)) { - return owningPlayer == localPlayer; - } - - if (BitIsSet(ei->m_type, ST_ALLIES)) { - // We have to also check that the owning player isn't the local player, because PLAYER - // wasn't specified, or we wouldn't have gotten here. - return (owningPlayer != localPlayer) && owningPlayer->getRelationship(localTeam) == ALLIES; - } - - if (BitIsSet(ei->m_type, ST_ENEMIES)) { - return owningPlayer->getRelationship(localTeam) == ENEMIES; - } - - return FALSE; -} - -//------------------------------------------------------------------------------------------------- -AudioHandle AudioManager::allocateNewHandle( void ) -{ - // note, intenionally a post increment rather than a pre increment. - return theAudioHandlePool++; -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::releaseAudioEventRTS( AudioEventRTS *&eventToRelease ) -{ - if( eventToRelease ) - { - delete eventToRelease; - eventToRelease = NULL; - } -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::loseFocus( void ) -{ - DEBUG_ASSERTLOG(m_savedValues == NULL, ("AudioManager::loseFocus() - leak - jkmcd")); - // In this case, make all the audio go silent. - m_savedValues = NEW Real[NUM_VOLUME_TYPES]; - m_savedValues[0] = m_systemMusicVolume; - m_savedValues[1] = m_systemSoundVolume; - m_savedValues[2] = m_systemSound3DVolume; - m_savedValues[3] = m_systemSpeechVolume; - - // Now, set them all to 0. - setVolume(0.0f, (AudioAffect) (AudioAffect_All | AudioAffect_SystemSetting)); -} - -//------------------------------------------------------------------------------------------------- -void AudioManager::regainFocus( void ) -{ - if (!m_savedValues) { - return; - } - - // We got focus back. Restore the previous audio values. - setVolume(m_savedValues[0], (AudioAffect) (AudioAffect_Music | AudioAffect_SystemSetting)); - setVolume(m_savedValues[1], (AudioAffect) (AudioAffect_Sound | AudioAffect_SystemSetting)); - setVolume(m_savedValues[2], (AudioAffect) (AudioAffect_Sound3D | AudioAffect_SystemSetting)); - setVolume(m_savedValues[3], (AudioAffect) (AudioAffect_Speech | AudioAffect_SystemSetting)); - - // Now, blow away the old volumes. - delete [] m_savedValues; - m_savedValues = NULL; -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -void INI::parseAudioSettingsDefinition( INI *ini ) -{ - ini->initFromINI(TheAudio->friend_getAudioSettings(), TheAudio->getFieldParseTable()); - - // time to override the volume settings, default 3-D provider, and speaker setup with the - // ones stored from the prefs - OptionPreferences prefs; - - TheAudio->setPreferredProvider(prefs.getPreferred3DProvider()); - TheAudio->setPreferredSpeaker(prefs.getSpeakerType()); - - Real relative2DVolume = TheAudio->getAudioSettings()->m_relative2DVolume; - relative2DVolume = MIN( 1.0f, MAX( -1.0f, relative2DVolume ) ); - - TheAudio->friend_getAudioSettings()->m_preferredSoundVolume = prefs.getSoundVolume() / 100.0f; - TheAudio->friend_getAudioSettings()->m_preferred3DSoundVolume = prefs.get3DSoundVolume() / 100.0f; - TheAudio->friend_getAudioSettings()->m_preferredSpeechVolume = prefs.getSpeechVolume() / 100.0f; - TheAudio->friend_getAudioSettings()->m_preferredMusicVolume = prefs.getMusicVolume() / 100.0f; -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- - -//------------------------------------------------------------------------------------------------- -void parseSpeakerType( INI *ini, void *instance, void *store, const void* userData ) -{ - AsciiString str; - ini->parseAsciiString( ini, instance, &str, userData ); - - (*(UnsignedInt*)store) = TheAudio->translateSpeakerTypeToUnsignedInt(str); -} - diff --git a/Generals/Code/GameEngine/Source/Common/Audio/GameMusic.cpp b/Generals/Code/GameEngine/Source/Common/Audio/GameMusic.cpp deleted file mode 100644 index b7dce07e7ad..00000000000 --- a/Generals/Code/GameEngine/Source/Common/Audio/GameMusic.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright(C) 2001 - All Rights Reserved -// -//---------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: GameMusic.cpp -// -// Created: 5/01/01 -// -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------------- - -#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine - -#include "Common/GameMusic.h" - -#include "Common/AudioEventRTS.h" -#include "Common/AudioRequest.h" -#include "Common/GameAudio.h" -#include "Common/INI.h" - - -//---------------------------------------------------------------------------- -// Externals -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Defines -//---------------------------------------------------------------------------- -#define MUSIC_PATH "Data\\Audio\\Tracks" // directory path to the music files - - -//---------------------------------------------------------------------------- -// Private Types -//---------------------------------------------------------------------------- - -//------------------------------------------------------------------------------------------------- -/** The INI data fields for music tracks */ -//------------------------------------------------------------------------------------------------- -const FieldParse MusicTrack::m_musicTrackFieldParseTable[] = -{ - - { "Filename", INI::parseAsciiString, NULL, offsetof( MusicTrack, filename ) }, - { "Volume", INI::parsePercentToReal, NULL, offsetof( MusicTrack, volume ) }, - { "Ambient", INI::parseBool, NULL, offsetof( MusicTrack, ambient ) }, - { NULL, NULL, NULL, 0 }, -}; - - -//------------------------------------------------------------------------------------------------- -MusicManager::MusicManager() -{ - -} - -//------------------------------------------------------------------------------------------------- -MusicManager::~MusicManager() -{ - -} - -//------------------------------------------------------------------------------------------------- -void MusicManager::playTrack( AudioEventRTS *eventToUse ) -{ - AudioRequest *audioRequest = TheAudio->allocateAudioRequest( true ); - audioRequest->m_pendingEvent = eventToUse; - audioRequest->m_request = AR_Play; - TheAudio->appendAudioRequest( audioRequest ); -} - -//------------------------------------------------------------------------------------------------- -void MusicManager::stopTrack( AudioHandle eventToRemove ) -{ - AudioRequest *audioRequest = TheAudio->allocateAudioRequest( false ); - audioRequest->m_handleToInteractOn = eventToRemove; - audioRequest->m_request = AR_Stop; - TheAudio->appendAudioRequest( audioRequest ); -} - -//------------------------------------------------------------------------------------------------- -void MusicManager::addAudioEvent( AudioEventRTS *eventToAdd ) -{ - playTrack( eventToAdd ); -} - -//------------------------------------------------------------------------------------------------- -void MusicManager::removeAudioEvent( AudioHandle eventToRemove ) -{ - stopTrack( eventToRemove ); -} - diff --git a/Generals/Code/GameEngine/Source/Common/Audio/GameSounds.cpp b/Generals/Code/GameEngine/Source/Common/Audio/GameSounds.cpp deleted file mode 100644 index eeb5b202a95..00000000000 --- a/Generals/Code/GameEngine/Source/Common/Audio/GameSounds.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright(C) 2001 - All Rights Reserved -// -//---------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: GameSounds.cpp -// -// Created: 5/02/01 -// -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------------- -#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine - -#include "Lib/BaseType.h" -#include "Common/GameSounds.h" - -#include "Common/AudioEventInfo.h" -#include "Common/AudioEventRTS.h" -#include "Common/AudioRequest.h" -#include "Common/Player.h" -#include "Common/PlayerList.h" - -#include "GameLogic/PartitionManager.h" - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -//------------------------------------------------------------------------------------------------- -SoundManager::SoundManager() -{ - // nada to do -} - -//------------------------------------------------------------------------------------------------- -SoundManager::~SoundManager() -{ - // nada to do -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::init( void ) -{ - -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::postProcessLoad() -{ - // The AudioManager should actually be live now, so go ahead and get the info we need from it - // here -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::update( void ) -{ - -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::reset( void ) -{ - m_numPlaying2DSamples = 0; - m_numPlaying3DSamples = 0; -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::loseFocus( void ) -{ - -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::regainFocus( void ) -{ - -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::setListenerPosition( const Coord3D *position ) -{ - -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::setViewRadius( Real viewRadius ) -{ - -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::setCameraAudibleDistance( Real audibleDistance ) -{ - -} - -//------------------------------------------------------------------------------------------------- -Real SoundManager::getCameraAudibleDistance( void ) -{ - return 1.0f; -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::addAudioEvent(AudioEventRTS *&eventToAdd) -{ - if (m_num2DSamples == 0 && m_num3DSamples == 0) { - m_num2DSamples = TheAudio->getNum2DSamples(); - m_num3DSamples = TheAudio->getNum3DSamples(); - } - - if (canPlayNow(eventToAdd)) { -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG((" - appended to request list with handle '%d'.", (UnsignedInt) eventToAdd->getPlayingHandle())); -#endif - AudioRequest *audioRequest = TheAudio->allocateAudioRequest( true ); - audioRequest->m_pendingEvent = eventToAdd; - audioRequest->m_request = AR_Play; - TheAudio->appendAudioRequest(audioRequest); - } else { - TheAudio->releaseAudioEventRTS(eventToAdd); - } -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::notifyOf2DSampleStart( void ) -{ - ++m_numPlaying2DSamples; -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::notifyOf3DSampleStart( void ) -{ - ++m_numPlaying3DSamples; -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::notifyOf2DSampleCompletion( void ) -{ - if (m_numPlaying2DSamples > 0) { - --m_numPlaying2DSamples; - } -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::notifyOf3DSampleCompletion( void ) -{ - if (m_numPlaying3DSamples > 0) { - --m_numPlaying3DSamples; - } -} - -//------------------------------------------------------------------------------------------------- -Int SoundManager::getAvailableSamples( void ) -{ - return (m_num2DSamples - m_numPlaying2DSamples); -} - -//------------------------------------------------------------------------------------------------- -Int SoundManager::getAvailable3DSamples( void ) -{ - return (m_num3DSamples - m_numPlaying3DSamples); -} - -//------------------------------------------------------------------------------------------------- -AsciiString SoundManager::getFilenameForPlayFromAudioEvent( const AudioEventRTS *eventToGetFrom ) -{ - return AsciiString::TheEmptyString; -} - -//------------------------------------------------------------------------------------------------- -Bool SoundManager::canPlayNow( AudioEventRTS *event ) -{ - Bool retVal = false; - // 1) Are we muted because we're beyond our maximum distance? - // 2) Are we shrouded and this is a shroud sound? - // 3) Are we violating our voice count or are we playing above the limit? (If so, stop now) - // 4) is there an avaiable channel open? - // 5) if not, then determine if there is anything of lower priority that we can kill - // 6) if not, are we an interrupt-sound type? - // if so, are there any sounds of our type playing right now that we can interrupt? - // potentially here: Are there any sounds that are playing that are now beyond their distance? - // if so, kill them and start our sound - // if not, we're done. Can't play dude. - - if( event->isPositionalAudio() && !BitIsSet( event->getAudioEventInfo()->m_type, ST_GLOBAL) && event->getAudioEventInfo()->m_priority != AP_CRITICAL ) - { - Coord3D distance = *TheAudio->getListenerPosition(); - const Coord3D *pos = event->getCurrentPosition(); - if (pos) - { - distance.sub(pos); - if (distance.length() >= event->getAudioEventInfo()->m_maxDistance) - { -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("- culled due to distance (%.2f).", distance.length())); -#endif - return false; - } - - Int localPlayerNdx = ThePlayerList->getLocalPlayer()->getPlayerIndex(); - if( (event->getAudioEventInfo()->m_type & ST_SHROUDED) && - ThePartitionManager->getShroudStatusForPlayer(localPlayerNdx, pos) != CELLSHROUD_CLEAR ) - { -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("- culled due to shroud.")); -#endif - return false; - } - } - } - - if (violatesVoice(event)) - { - retVal = isInterrupting(event); - if (retVal) - { - return true; - } - else - { -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("- culled due to voice.")); -#endif - return false; - } - } - - if( TheAudio->doesViolateLimit( event ) ) - { -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("- culled due to limit." )); -#endif - return false; - } - else if( isInterrupting( event ) ) - { - return true; - } - - if (event->isPositionalAudio()) - { - if (m_numPlaying3DSamples < m_num3DSamples) - { - return true; - } -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("- %d samples playing, %d samples available", m_numPlaying3DSamples, m_num3DSamples)); -#endif - } - else - { - // its a UI sound (and thus, 2-D) - if (m_numPlaying2DSamples < m_num2DSamples) - { - return true; - } - } - - if (TheAudio->isPlayingLowerPriority(event)) - { - return true; - } - - if (isInterrupting(event)) - { - retVal = TheAudio->isPlayingAlready(event); - if (retVal) - { - return true; - } - else - { -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("- culled due to no channels available and non-interrupting." )); -#endif - return false; - } - } -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("culled due to unavailable channels")); -#endif - return false; -} - -//------------------------------------------------------------------------------------------------- -Bool SoundManager::violatesVoice( AudioEventRTS *event ) -{ - if (event->getAudioEventInfo()->m_type & ST_VOICE) { - return (event->getObjectID() && TheAudio->isObjectPlayingVoice(event->getObjectID())); - } - return false; -} - -//------------------------------------------------------------------------------------------------- -Bool SoundManager::isInterrupting( AudioEventRTS *event ) -{ - return event->getAudioEventInfo()->m_control & AC_INTERRUPT; -} \ No newline at end of file diff --git a/Generals/Code/GameEngine/Source/Common/Audio/simpleplayer.cpp b/Generals/Code/GameEngine/Source/Common/Audio/simpleplayer.cpp deleted file mode 100644 index d734b41fd55..00000000000 --- a/Generals/Code/GameEngine/Source/Common/Audio/simpleplayer.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - - -#include "Common/simpleplayer.h" -#include "Common/urllaunch.h" - - -/////////////////////////////////////////////////////////////////////////////// -CSimplePlayer::CSimplePlayer( HRESULT* phr ) -{ - m_cRef = 1; - m_cBuffersOutstanding = 0; - - m_pReader = NULL; - - m_pHeader = NULL; - m_hwo = NULL; - - m_fEof = FALSE; - m_pszUrl = NULL; - - *phr = S_OK; - - m_hOpenEvent = CreateEvent( NULL, FALSE, FALSE, SIMPLE_PLAYER_OPEN_EVENT ); - if ( NULL == m_hOpenEvent ) - { - *phr = E_OUTOFMEMORY; - } - m_hCloseEvent = CreateEvent( NULL, FALSE, FALSE, SIMPLE_PLAYER_CLOSE_EVENT ); - if ( NULL == m_hCloseEvent ) - { - *phr = E_OUTOFMEMORY; - } - - m_hrOpen = S_OK; - - m_hCompletionEvent = NULL; - - InitializeCriticalSection( &m_CriSec ); - m_whdrHead = NULL; -} - - -/////////////////////////////////////////////////////////////////////////////// -CSimplePlayer::~CSimplePlayer() -{ - DEBUG_ASSERTCRASH( 0 == m_cBuffersOutstanding,("CSimplePlayer destructor m_cBuffersOutstanding != 0") ); - - Close(); - - // - // final remove of everything in the wave header list - // - RemoveWaveHeaders(); - DeleteCriticalSection( &m_CriSec ); - - if( m_pHeader != NULL ) - { - m_pHeader->Release(); - m_pHeader = NULL; - } - - if( m_pReader != NULL ) - { - m_pReader->Release(); - m_pReader = NULL; - } - - if( m_hwo != NULL ) - { - waveOutClose( m_hwo ); - } - - delete [] m_pszUrl; - - if ( m_hOpenEvent ) - { - CloseHandle( m_hOpenEvent ); - } - if ( m_hCloseEvent ) - { - CloseHandle( m_hCloseEvent ); - } -} - - -/////////////////////////////////////////////////////////////////////////////// -HRESULT STDMETHODCALLTYPE CSimplePlayer::QueryInterface( - REFIID riid, - void **ppvObject ) -{ - return( E_NOINTERFACE ); -} - - -/////////////////////////////////////////////////////////////////////////////// -ULONG STDMETHODCALLTYPE CSimplePlayer::AddRef() -{ - return( InterlockedIncrement( &m_cRef ) ); -} - - -/////////////////////////////////////////////////////////////////////////////// -ULONG STDMETHODCALLTYPE CSimplePlayer::Release() -{ - ULONG uRet = InterlockedDecrement( &m_cRef ); - - if( 0 == uRet ) - { - delete this; - } - - return( uRet ); -} - - -/////////////////////////////////////////////////////////////////////////////// -HRESULT STDMETHODCALLTYPE CSimplePlayer::OnSample( - /* [in] */ DWORD dwOutputNum, - /* [in] */ QWORD cnsSampleTime, - /* [in] */ QWORD cnsSampleDuration, - /* [in] */ DWORD dwFlags, - /* [in] */ INSSBuffer __RPC_FAR *pSample, - /* [in] */ VOID *pvContext ) -{ - if( 0 != dwOutputNum ) - { - return( S_OK ); - } - - HRESULT hr = S_OK; - BYTE *pData; - DWORD cbData; - - // - // first UnprepareHeader and remove everthing in the ready list - // - RemoveWaveHeaders( ); - - hr = pSample->GetBufferAndLength( &pData, &cbData ); - if ( FAILED( hr ) ) - { - return( E_UNEXPECTED ); - } - - DEBUG_LOG(( " New Sample of length %d and PS time %d ms", - cbData, ( DWORD ) ( cnsSampleTime / 10000 ) )); - - LPWAVEHDR pwh = (LPWAVEHDR) new BYTE[ sizeof( WAVEHDR ) + cbData ]; - - if( NULL == pwh ) - { - DEBUG_LOG(( "OnSample OUT OF MEMORY! ")); - - *m_phrCompletion = E_OUTOFMEMORY; - SetEvent( m_hCompletionEvent ); - return( E_UNEXPECTED ); - } - - pwh->lpData = (LPSTR)&pwh[1]; - pwh->dwBufferLength = cbData; - pwh->dwBytesRecorded = cbData; - pwh->dwUser = 0; - pwh->dwLoops = 0; - pwh->dwFlags = 0; - - CopyMemory( pwh->lpData, pData, cbData ); - - MMRESULT mmr; - - mmr = waveOutPrepareHeader( m_hwo, pwh, sizeof(WAVEHDR) ); - mmr = MMSYSERR_NOERROR; - - if( mmr != MMSYSERR_NOERROR ) - { - DEBUG_LOG(( "failed to prepare wave buffer, error=%lu" , mmr )); - *m_phrCompletion = E_UNEXPECTED; - SetEvent( m_hCompletionEvent ); - return( E_UNEXPECTED ); - } - - mmr = waveOutWrite( m_hwo, pwh, sizeof(WAVEHDR) ); - mmr = MMSYSERR_NOERROR; - - if( mmr != MMSYSERR_NOERROR ) - { - delete pwh; - - DEBUG_LOG(( "failed to write wave sample, error=%lu" , mmr )); - *m_phrCompletion = E_UNEXPECTED; - SetEvent( m_hCompletionEvent ); - return( E_UNEXPECTED ); - } - - InterlockedIncrement( &m_cBuffersOutstanding ); - - return( S_OK ); -} - -/////////////////////////////////////////////////////////////////////////////// -HRESULT CSimplePlayer::Play( LPCWSTR pszUrl, DWORD dwSecDuration, HANDLE hCompletionEvent, HRESULT *phrCompletion ) -{ - HRESULT hr; - - // - // If the URL is not a UNC path, a full path, or an Internet-style URL then assume it is - // a relative local file name that needs to be expanded to a full path. - // - WCHAR wszFullUrl[ MAX_PATH ]; - - if( ( 0 == wcsstr( pszUrl, L"\\\\" ) ) - && ( 0 == wcsstr( pszUrl, L":\\" ) ) - && ( 0 == wcsstr( pszUrl, L"://" ) ) ) - { - // - // Expand to a full path name - // - LPWSTR pszCheck = _wfullpath( wszFullUrl, pszUrl, MAX_PATH ); - - if( NULL == pszCheck ) - { - DEBUG_LOG(( "internal error %lu" , GetLastError() )); - return E_UNEXPECTED ; - } - - pszUrl = wszFullUrl; - } - - // - // Save a copy of the URL - // - delete[] m_pszUrl; - - m_pszUrl = new WCHAR[ wcslen( pszUrl ) + 1 ]; - - if( NULL == m_pszUrl ) - { - DEBUG_LOG(( "insufficient Memory" )) ; - return( E_OUTOFMEMORY ); - } - - wcscpy( m_pszUrl, pszUrl ); - - // - // Attempt to open the URL - // - m_hCompletionEvent = hCompletionEvent; - - m_phrCompletion = phrCompletion; - -#ifdef SUPPORT_DRM - - hr = WMCreateReader( NULL, WMT_RIGHT_PLAYBACK, &m_pReader ); - -#else - - hr = WMCreateReader( NULL, 0, &m_pReader ); - -#endif - - if( FAILED( hr ) ) - { - DEBUG_LOG(( "failed to create audio reader (hr=0x%08x)" , hr )); - return( hr ); - } - - // - // Open the file - // - hr = m_pReader->Open( m_pszUrl, this, NULL ); - if ( SUCCEEDED( hr ) ) - { - WaitForSingleObject( m_hOpenEvent, INFINITE ); - hr = m_hrOpen; - } - if ( NS_E_NO_STREAM == hr ) - { - DEBUG_LOG(( "Waiting for transmission to begin..." )); - WaitForSingleObject( m_hOpenEvent, INFINITE ); - hr = m_hrOpen; - } - if ( FAILED( hr ) ) - { - DEBUG_LOG(( "failed to open (hr=0x%08x)", hr )); - return( hr ); - } - - - // - // It worked! Display various attributes - // - hr = m_pReader->QueryInterface( IID_IWMHeaderInfo, ( VOID ** )&m_pHeader ); - if ( FAILED( hr ) ) - { - DEBUG_LOG(( "failed to qi for header interface (hr=0x%08x)" , hr )); - return( hr ); - } - - WORD i, wAttrCnt; - - hr = m_pHeader->GetAttributeCount( 0, &wAttrCnt ); - if ( FAILED( hr ) ) - { - DEBUG_LOG(( "GetAttributeCount Failed (hr=0x%08x)" , hr )); - return( hr ); - } - - WCHAR *pwszName = NULL; - BYTE *pValue = NULL; - - for ( i = 0; i < wAttrCnt ; i++ ) - { - WORD wStream = 0; - WORD cchNamelen = 0; - WMT_ATTR_DATATYPE type; - WORD cbLength = 0; - - hr = m_pHeader->GetAttributeByIndex( i, &wStream, NULL, &cchNamelen, &type, NULL, &cbLength ); - if ( FAILED( hr ) ) - { - DEBUG_LOG(( "GetAttributeByIndex Failed (hr=0x%08x)" , hr )); - break; - } - - pwszName = new WCHAR[ cchNamelen ]; - pValue = new BYTE[ cbLength ]; - - if( NULL == pwszName || NULL == pValue ) - { - hr = E_OUTOFMEMORY; - break; - } - - hr = m_pHeader->GetAttributeByIndex( i, &wStream, pwszName, &cchNamelen, &type, pValue, &cbLength ); - if ( FAILED( hr ) ) - { - DEBUG_LOG(( "GetAttributeByIndex Failed (hr=0x%08x)" , hr )); - break; - } - - switch ( type ) - { - case WMT_TYPE_DWORD: - DEBUG_LOG(("%ws: %u" , pwszName, *((DWORD *) pValue) )); - break; - case WMT_TYPE_STRING: - DEBUG_LOG(("%ws: %ws" , pwszName, (WCHAR *) pValue )); - break; - case WMT_TYPE_BINARY: - DEBUG_LOG(("%ws: Type = Binary of Length %u" , pwszName, cbLength )); - break; - case WMT_TYPE_BOOL: - DEBUG_LOG(("%ws: %s" , pwszName, ( * ( ( BOOL * ) pValue) ? _T( "true" ) : _T( "false" ) ) )); - break; - case WMT_TYPE_WORD: - DEBUG_LOG(("%ws: %hu" , pwszName, *((WORD *) pValue) )); - break; - case WMT_TYPE_QWORD: - DEBUG_LOG(("%ws: %I64u" , pwszName, *((QWORD *) pValue) )); - break; - case WMT_TYPE_GUID: - DEBUG_LOG(("%ws: %I64x%I64x" , pwszName, *((QWORD *) pValue), *((QWORD *) pValue + 1) )); - break; - default: - DEBUG_LOG(("%ws: Type = %d, Length %u" , pwszName, type, cbLength )); - break; - } - - delete pwszName; - pwszName = NULL; - - delete pValue; - pValue = NULL; - } - - delete pwszName; - pwszName = NULL; - - delete pValue; - pValue = NULL; - - if ( FAILED( hr ) ) - { - return( hr ); - } - - // - // Make sure we're audio only - // - DWORD cOutputs; - - hr = m_pReader->GetOutputCount( &cOutputs ); - if ( FAILED( hr ) ) - { - DEBUG_LOG(( "failed GetOutputCount(), (hr=0x%08x)" , hr )); - return( hr ); - } - - if ( cOutputs != 1 ) - { - DEBUG_LOG(( "Not audio only (cOutputs = %d)." , cOutputs )); - // return( E_UNEXPECTED ); - } - - IWMOutputMediaProps *pProps; - hr = m_pReader->GetOutputProps( 0, &pProps ); - if ( FAILED( hr ) ) - { - DEBUG_LOG(( "failed GetOutputProps(), (hr=0x%08x)" , hr )); - return( hr ); - } - - DWORD cbBuffer = 0; - - hr = pProps->GetMediaType( NULL, &cbBuffer ); - if ( FAILED( hr ) ) - { - pProps->Release( ); - DEBUG_LOG(( "GetMediaType failed (hr=0x%08x)" , hr )); - return( hr ); - } - - WM_MEDIA_TYPE *pMediaType = ( WM_MEDIA_TYPE * ) new BYTE[cbBuffer] ; - - hr = pProps->GetMediaType( pMediaType, &cbBuffer ); - if ( FAILED( hr ) ) - { - pProps->Release( ); - DEBUG_LOG(( "GetMediaType failed (hr=0x%08x)" , hr )); - return( hr ); - } - - pProps->Release( ); - - if ( pMediaType->majortype != WMMEDIATYPE_Audio ) - { - delete[] (BYTE *) pMediaType ; - DEBUG_LOG(( "Not audio only (major type mismatch)." )); - return( E_UNEXPECTED ); - } - - // - // Set up for audio playback - // - WAVEFORMATEX *pwfx = ( WAVEFORMATEX * )pMediaType->pbFormat; - memcpy( &m_wfx, pwfx, sizeof( WAVEFORMATEX ) + pwfx->cbSize ); - - delete[] (BYTE *)pMediaType ; - pMediaType = NULL ; - - MMRESULT mmr; - - mmr = waveOutOpen( &m_hwo, - WAVE_MAPPER, - &m_wfx, - (DWORD)WaveProc, - (DWORD)this, - CALLBACK_FUNCTION ); - mmr = MMSYSERR_NOERROR; - - if( mmr != MMSYSERR_NOERROR ) - { - - DEBUG_LOG(( "failed to open wav output device, error=%lu" , mmr )); - return( E_UNEXPECTED ); - } - - // - // Start reading the data (and rendering the audio) - // - QWORD cnsDuration = ( QWORD ) dwSecDuration * 10000000; - hr = m_pReader->Start( 0, cnsDuration, 1.0, NULL ); - - if( FAILED( hr ) ) - { - DEBUG_LOG(( "failed Start(), (hr=0x%08x)" , hr )); - return( hr ); - } - - return( hr ); -} - - -/////////////////////////////////////////////////////////////////////////////// -HRESULT STDMETHODCALLTYPE CSimplePlayer::OnStatus( - /* [in] */ WMT_STATUS Status, - /* [in] */ HRESULT hr, - /* [in] */ WMT_ATTR_DATATYPE dwType, - /* [in] */ BYTE __RPC_FAR *pValue, - /* [in] */ void __RPC_FAR *pvContext) -{ - switch( Status ) - { - case WMT_OPENED: - DEBUG_LOG(( "OnStatus( WMT_OPENED )" )); - m_hrOpen = hr; - SetEvent( m_hOpenEvent ); - break; - - case WMT_SOURCE_SWITCH: - DEBUG_LOG(( "OnStatus( WMT_SOURCE_SWITCH )" )); - m_hrOpen = hr; - SetEvent( m_hOpenEvent ); - break; - - case WMT_ERROR: - DEBUG_LOG(( "OnStatus( WMT_ERROR )" )); - break; - - case WMT_STARTED: - DEBUG_LOG(( "OnStatus( WMT_STARTED )" )); - break; - - case WMT_STOPPED: - DEBUG_LOG(( "OnStatus( WMT_STOPPED )" )); - break; - - case WMT_BUFFERING_START: - DEBUG_LOG(( "OnStatus( WMT_BUFFERING START)" )); - break; - - case WMT_BUFFERING_STOP: - DEBUG_LOG(( "OnStatus( WMT_BUFFERING STOP)" )); - break; - - case WMT_EOF: - DEBUG_LOG(( "OnStatus( WMT_EOF )" )); - - // - // cleanup and exit - // - - m_fEof = TRUE; - - if( 0 == m_cBuffersOutstanding ) - { - SetEvent( m_hCompletionEvent ); - } - - break; - - case WMT_END_OF_SEGMENT: - DEBUG_LOG(( "OnStatus( WMT_END_OF_SEGMENT )" )); - - // - // cleanup and exit - // - - m_fEof = TRUE; - - if( 0 == m_cBuffersOutstanding ) - { - SetEvent( m_hCompletionEvent ); - } - - break; - - case WMT_LOCATING: - DEBUG_LOG(( "OnStatus( WMT_LOCATING )" )); - break; - - case WMT_CONNECTING: - DEBUG_LOG(( "OnStatus( WMT_CONNECTING )" )); - break; - - case WMT_NO_RIGHTS: - { - LPWSTR pwszEscapedURL = NULL; - - hr = MakeEscapedURL( m_pszUrl, &pwszEscapedURL ); - - if( SUCCEEDED( hr ) ) - { - WCHAR wszURL[ 0x1000 ]; - - swprintf( wszURL, L"%s&filename=%s&embedded=false", pValue, pwszEscapedURL ); - - hr = LaunchURL( wszURL ); - - if( FAILED( hr ) ) - { - DEBUG_LOG(( "Unable to launch web browser to retrieve playback license (hr=0x%08x)" , hr )); - } - - delete [] pwszEscapedURL; - pwszEscapedURL = NULL ; - } - } - break; - - case WMT_MISSING_CODEC: - { - DEBUG_LOG(( "Missing codec: (hr=0x%08x)" , hr )); - break; - } - - case WMT_CLOSED: - SetEvent( m_hCloseEvent ); - break; - }; - - return( S_OK ); -} - - -/////////////////////////////////////////////////////////////////////////////// -HRESULT CSimplePlayer::Close() -{ - HRESULT hr = S_OK; - - if( NULL != m_pReader ) - { - hr = m_pReader->Close(); - - if( SUCCEEDED( hr ) ) - { - WaitForSingleObject( m_hCloseEvent, INFINITE ); - } - } - - return( hr ); -} - - -/////////////////////////////////////////////////////////////////////////////// -void CSimplePlayer::OnWaveOutMsg( UINT uMsg, DWORD dwParam1, DWORD dwParam2 ) -{ - if( WOM_DONE == uMsg ) - { - // - // add the wave header to ready-to-free list for the caller - // to pick up and free in the next OnSample call - // - AddWaveHeader( ( LPWAVEHDR )dwParam1 ); - - InterlockedDecrement( &m_cBuffersOutstanding ); - - if( m_fEof && ( 0 == m_cBuffersOutstanding ) ) - { - SetEvent( m_hCompletionEvent ); - } - } -} - - -/////////////////////////////////////////////////////////////////////////////// -void CALLBACK CSimplePlayer::WaveProc( - HWAVEOUT hwo, - UINT uMsg, - DWORD dwInstance, - DWORD dwParam1, - DWORD dwParam2 ) -{ - CSimplePlayer *pThis = (CSimplePlayer*)dwInstance; - - pThis->OnWaveOutMsg( uMsg, dwParam1, dwParam2 ); -} - -////////////////////////////////////////////////////////////////////////////// -HRESULT CSimplePlayer::AddWaveHeader( LPWAVEHDR pwh ) -{ - WAVEHDR_LIST *tmp = new WAVEHDR_LIST; - if( NULL == tmp ) - { - return( E_OUTOFMEMORY ); - } - tmp->pwh = pwh; - - EnterCriticalSection( &m_CriSec ); - tmp->next = m_whdrHead; - m_whdrHead = tmp; - LeaveCriticalSection( &m_CriSec ); - return( S_OK ); -} - -////////////////////////////////////////////////////////////////////////////// -void CSimplePlayer::RemoveWaveHeaders( ) -{ - WAVEHDR_LIST *tmp; - - EnterCriticalSection( &m_CriSec ); - while( NULL != m_whdrHead ) - { - tmp = m_whdrHead->next; - DEBUG_ASSERTCRASH( m_whdrHead->pwh->dwFlags & WHDR_DONE, ("RemoveWaveHeaders!") ); - waveOutUnprepareHeader( m_hwo, m_whdrHead->pwh, sizeof( WAVEHDR ) ); - delete m_whdrHead->pwh; - delete m_whdrHead; - m_whdrHead = tmp; - } - LeaveCriticalSection( &m_CriSec ); -} diff --git a/Generals/Code/GameEngine/Source/Common/Audio/urllaunch.cpp b/Generals/Code/GameEngine/Source/Common/Audio/urllaunch.cpp deleted file mode 100644 index e3be6c9cc5f..00000000000 --- a/Generals/Code/GameEngine/Source/Common/Audio/urllaunch.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - - -#include "Common/urllaunch.h" - -#define FILE_PREFIX L"file://" - - -/////////////////////////////////////////////////////////////////////////////// -HRESULT MakeEscapedURL( LPWSTR pszInURL, LPWSTR *ppszOutURL ) -{ - if( ( NULL == pszInURL ) || ( NULL == ppszOutURL ) ) - { - return( E_INVALIDARG ); - } - - // - // Do we need to pre-pend file://? - // - BOOL fNeedFilePrefix = ( 0 == wcsstr( pszInURL, L"://" ) ); - - // - // Count how many characters need to be escaped - // - LPWSTR pszTemp = pszInURL; - DWORD cEscapees = 0; - - while( TRUE ) - { - LPWSTR pchToEscape = wcspbrk( pszTemp, L" #$%&\\+,;=@[]^{}" ); - - if( NULL == pchToEscape ) - { - break; - } - - cEscapees++; - - pszTemp = pchToEscape + 1; - } - - // - // Allocate sufficient outgoing buffer space - // - int cchNeeded = wcslen( pszInURL ) + ( 2 * cEscapees ) + 1; - - if( fNeedFilePrefix ) - { - cchNeeded += wcslen( FILE_PREFIX ); - } - - *ppszOutURL = new WCHAR[ cchNeeded ]; - - if( NULL == *ppszOutURL ) - { - return( E_OUTOFMEMORY ); - } - - // - // Fill in the outgoing escaped buffer - // - pszTemp = pszInURL; - - LPWSTR pchNext = *ppszOutURL; - - if( fNeedFilePrefix ) - { - wcscpy( *ppszOutURL, FILE_PREFIX ); - pchNext += wcslen( FILE_PREFIX ); - } - - while( TRUE ) - { - LPWSTR pchToEscape = wcspbrk( pszTemp, L" #$%&\\+,;=@[]^{}" ); - - if( NULL == pchToEscape ) - { - // - // Copy the rest of the input string and get out - // - wcscpy( pchNext, pszTemp ); - break; - } - - // - // Copy all characters since the previous escapee - // - int cchToCopy = pchToEscape - pszTemp; - - if( cchToCopy > 0 ) - { - wcsncpy( pchNext, pszTemp, cchToCopy ); - - pchNext += cchToCopy; - } - - // - // Expand this character into an escape code and move on - // - pchNext += swprintf( pchNext, L"%%%02x", *pchToEscape ); - - pszTemp = pchToEscape + 1; - } - - return( S_OK ); -} - - -/////////////////////////////////////////////////////////////////////////////// -HRESULT GetShellOpenCommand( LPTSTR ptszShellOpenCommand, DWORD cbShellOpenCommand ) -{ - LONG lResult; - - HKEY hKey = NULL; - HKEY hFileKey = NULL; - - BOOL fFoundExtensionCommand = FALSE; - - do - { - // - // Look for the file type associated with .html files - // - TCHAR szFileType[ MAX_PATH ]; - - lResult = RegOpenKeyEx( HKEY_CLASSES_ROOT, _T( ".html" ), 0, KEY_READ, &hKey ); - - if( ERROR_SUCCESS != lResult ) - { - break; - } - - DWORD dwLength = sizeof( szFileType ); - - lResult = RegQueryValueEx( hKey, NULL, 0, NULL, (BYTE *)szFileType, &dwLength ); - - if( ERROR_SUCCESS != lResult ) - { - break; - } - - // - // Find the command for the shell's open verb associated with this file type - // - TCHAR szKeyName[ MAX_PATH + 20 ]; - - wsprintf( szKeyName, _T( "%s\\shell\\open\\command" ), szFileType ); - - lResult = RegOpenKeyEx( HKEY_CLASSES_ROOT, szKeyName, 0, KEY_READ, &hFileKey ); - - if( ERROR_SUCCESS != lResult ) - { - break; - } - - dwLength = cbShellOpenCommand; - - lResult = RegQueryValueEx( hFileKey, NULL, 0, NULL, (BYTE *)ptszShellOpenCommand, &dwLength ); - - if( 0 == lResult ) - { - fFoundExtensionCommand = TRUE; - } - } - while( FALSE ); - - // - // If there was no application associated with .html files by extension, look for - // an application associated with the http protocol - // - if( !fFoundExtensionCommand ) - { - if( NULL != hKey ) - { - RegCloseKey( hKey ); - } - - do - { - // - // Find the command for the shell's open verb associated with the http protocol - // - lResult = RegOpenKeyEx( HKEY_CLASSES_ROOT, _T( "http\\shell\\open\\command" ), 0, KEY_READ, &hKey ); - - if( ERROR_SUCCESS != lResult ) - { - break; - } - - DWORD dwLength = cbShellOpenCommand; - - lResult = RegQueryValueEx( hKey, NULL, 0, NULL, (BYTE *)ptszShellOpenCommand, &dwLength ); - } - while( FALSE ); - } - - if( NULL != hKey ) - { - RegCloseKey( hKey ); - } - - if( NULL != hFileKey ) - { - RegCloseKey( hFileKey ); - } - - return( HRESULT_FROM_WIN32( lResult ) ); -} - - -/////////////////////////////////////////////////////////////////////////////// -HRESULT LaunchURL( LPCWSTR pszURL ) -{ - HRESULT hr; - - // - // Find the appropriate command to launch URLs with - // - TCHAR szShellOpenCommand[ MAX_PATH * 2 ]; - - hr = GetShellOpenCommand( szShellOpenCommand, sizeof( szShellOpenCommand ) ); - - if( FAILED( hr ) ) - { - return( hr ); - } - - // - // Build the appropriate command line, substituting our URL parameter - // - TCHAR szLaunchCommand[ 2000 ]; - - LPTSTR pszParam = _tcsstr( szShellOpenCommand, _T( "\"%1\"" ) ); - - if( NULL == pszParam ) - { - pszParam = _tcsstr( szShellOpenCommand, _T( "\"%*\"" ) ); - } - - if( NULL != pszParam ) - { - *pszParam = _T( '\0' ) ; - - wsprintf( szLaunchCommand, _T( "%s%ws%s" ), szShellOpenCommand, pszURL, pszParam + 4 ); - } - else - { - wsprintf( szLaunchCommand, _T( "%s %ws" ), szShellOpenCommand, pszURL ); - } - - // - // Find the application name, stripping quotes if necessary - // - TCHAR szExe[ MAX_PATH * 2 ]; - LPTSTR pchFirst = szShellOpenCommand; - LPTSTR pchNext = NULL; - - while( _T( ' ' ) == *pchFirst ) - { - pchFirst++; - } - - if( _T( '"' ) == *pchFirst ) - { - pchFirst++; - - pchNext = _tcschr( pchFirst, _T( '"' ) ); - } - else - { - pchNext = _tcschr( pchFirst + 1, _T( ' ' ) ); - } - - if( NULL == pchNext ) - { - pchNext = szShellOpenCommand + _tcslen( szShellOpenCommand ); - } - - _tcsncpy( szExe, pchFirst, pchNext - pchFirst ); - szExe[ pchNext - pchFirst ] = _T( '\0' ) ; - - // - // Because of the extremely long length of the URLs, neither - // WinExec, nor ShellExecute, were working correctly. For this reason - // we use CreateProcess. The CreateProcess documentation in MSDN says - // that the most robust way to call CreateProcess is to pass the full - // command line, where the first element is the application name, in the - // lpCommandLine parameter. In our case this is necesssary to get Netscape - // to function properly. - // - PROCESS_INFORMATION ProcInfo; - ZeroMemory( (LPVOID)&ProcInfo, sizeof( PROCESS_INFORMATION ) ); - - STARTUPINFO StartUp; - ZeroMemory( (LPVOID)&StartUp, sizeof( STARTUPINFO ) ); - - StartUp.cb = sizeof(STARTUPINFO); - - if( !CreateProcess( szExe, szLaunchCommand, NULL, NULL, - FALSE, 0, NULL, NULL, &StartUp, &ProcInfo) ) - { - hr = HRESULT_FROM_WIN32( GetLastError() ); - } - else - { - // - // CreateProcess succeeded and we do not need the handles to the thread - // or the process, so close them now. - // - if( NULL != ProcInfo.hThread ) - { - CloseHandle( ProcInfo.hThread ); - } - - if( NULL != ProcInfo.hProcess ) - { - CloseHandle( ProcInfo.hProcess ); - } - } - - return( hr ); -} diff --git a/Generals/Code/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp b/Generals/Code/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp deleted file mode 100644 index 8ca148daf28..00000000000 --- a/Generals/Code/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: INIAudioEventInfo.cpp //////////////////////////////////////////////////////////////////////// -// Author: Colin Day, July 2002 -// Desc: Parsing AudioEvent, MusicTrack and DialogEvent INI entries -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine - -#include "Common/INI.h" -#include "Common/GameAudio.h" -#include "Common/AudioEventInfo.h" - -AudioEventInfo::~AudioEventInfo() -{ - -} -// @todo: Get these functions unified. - -//------------------------------------------------------------------------------------------------- -void INI::parseMusicTrackDefinition( INI* ini ) -{ - AsciiString name; - AudioEventInfo *track; - - // read the name - const char* c = ini->getNextToken(); - name.set( c ); - - track = TheAudio->newAudioEventInfo( name ); - if (!track) { - return; - } - - AudioEventInfo *defaultInfo = TheAudio->findAudioEventInfo("DefaultMusicTrack"); - if (defaultInfo) { - (*track) = (*defaultInfo); - TheAudio->addTrackName( name ); - } - - track->m_audioName = name; - track->m_soundType = AT_Music; - - // parse the ini definition - ini->initFromINI( track, track->getFieldParse() ); -} // end parseMusicTrackDefinition - -//------------------------------------------------------------------------------------------------- -void INI::parseAudioEventDefinition( INI* ini ) -{ - AsciiString name; - AudioEventInfo *track; - - // read the name - const char* c = ini->getNextToken(); - name.set( c ); - - track = TheAudio->newAudioEventInfo( name ); - if (!track) { - return; - } - - AudioEventInfo *defaultInfo = TheAudio->findAudioEventInfo("DefaultSoundEffect"); - if (defaultInfo) { - (*track) = (*defaultInfo); - } - - track->m_audioName = name; - track->m_soundType = AT_SoundEffect; - - // parse the ini definition - ini->initFromINI( track, track->getFieldParse() ); -} // end parseAudioEventDefinition - -//------------------------------------------------------------------------------------------------- -void INI::parseDialogDefinition( INI* ini ) -{ - AsciiString name; - AudioEventInfo *track; - - // read the name - const char* c = ini->getNextToken(); - name.set( c ); - - track = TheAudio->newAudioEventInfo( name ); - if (!track) { - return; - } - - AudioEventInfo *defaultInfo = TheAudio->findAudioEventInfo("DefaultDialog"); - if (defaultInfo) { - (*track) = (*defaultInfo); - } - - track->m_audioName = name; - track->m_soundType = AT_Streaming; - - // parse the ini definition - ini->initFromINI( track, track->getFieldParse() ); -} // end parseAudioEventDefinition - - -//------------------------------------------------------------------------------------------------- -static void parseDelay( INI* ini, void *instance, void *store, const void* /*userData*/ ); -static void parsePitchShift( INI* ini, void *instance, void *store, const void* /*userData*/ ); - -//------------------------------------------------------------------------------------------------- -const FieldParse AudioEventInfo::m_audioEventInfo[] = -{ - { "Filename", INI::parseAsciiString, NULL, offsetof( AudioEventInfo, m_filename) }, - { "Volume", INI::parsePercentToReal, NULL, offsetof( AudioEventInfo, m_volume ) }, - { "VolumeShift", INI::parsePercentToReal, NULL, offsetof( AudioEventInfo, m_volumeShift ) }, - { "MinVolume", INI::parsePercentToReal, NULL, offsetof( AudioEventInfo, m_minVolume ) }, - { "PitchShift", parsePitchShift, NULL, 0 }, - { "Delay", parseDelay, NULL, 0 }, - { "Limit", INI::parseInt, NULL, offsetof( AudioEventInfo, m_limit ) }, - { "LoopCount", INI::parseInt, NULL, offsetof( AudioEventInfo, m_loopCount ) }, - { "Priority", INI::parseIndexList, theAudioPriorityNames, offsetof( AudioEventInfo, m_priority ) }, - { "Type", INI::parseBitString32, theSoundTypeNames, offsetof( AudioEventInfo, m_type ) }, - { "Control", INI::parseBitString32, theAudioControlNames, offsetof( AudioEventInfo, m_control ) }, - { "Sounds", INI::parseSoundsList, NULL, offsetof( AudioEventInfo, m_sounds ) }, - { "SoundsNight", INI::parseSoundsList, NULL, offsetof( AudioEventInfo, m_soundsNight ) }, - { "SoundsEvening", INI::parseSoundsList, NULL, offsetof( AudioEventInfo, m_soundsEvening ) }, - { "SoundsMorning", INI::parseSoundsList, NULL, offsetof( AudioEventInfo, m_soundsMorning ) }, - { "Attack", INI::parseSoundsList, NULL, offsetof( AudioEventInfo, m_attackSounds ) }, - { "Decay", INI::parseSoundsList, NULL, offsetof( AudioEventInfo, m_decaySounds ) }, - { "MinRange", INI::parseReal, NULL, offsetof( AudioEventInfo, m_minDistance) }, - { "MaxRange", INI::parseReal, NULL, offsetof( AudioEventInfo, m_maxDistance) }, - { "LowPassCutoff", INI::parsePercentToReal, NULL, offsetof( AudioEventInfo, m_lowPassFreq) }, -}; - -//------------------------------------------------------------------------------------------------- -static void parseDelay( INI* ini, void *instance, void *store, const void* /*userData*/ ) -{ - AudioEventInfo *attribs = (AudioEventInfo*) store; - - Int min = ini->scanInt(ini->getNextToken()); - Int max = ini->scanInt(ini->getNextToken()); - - DEBUG_ASSERTCRASH( min >= 0 && max >= min, ("Bad delay values for audio event %s", attribs->m_audioName.str())); - attribs->m_delayMax = max; - attribs->m_delayMin = min; -} - -//------------------------------------------------------------------------------------------------- -static void parsePitchShift( INI* ini, void *instance, void *store, const void* /*userData*/ ) -{ - AudioEventInfo *attribs = (AudioEventInfo*) store; - - Real min = ini->scanReal(ini->getNextToken()); - Real max = ini->scanReal(ini->getNextToken()); - - DEBUG_ASSERTCRASH( min > -100 && max >= min, ("Bad pitch shift values for audio event %s", attribs->m_audioName.str())); - attribs->m_pitchShiftMin = 1.0f + min/100; - attribs->m_pitchShiftMax = 1.0f + max/100; -} - -// STATIC DEFINIITIONS //////////////////////////////////////////////////////////////////////////// - -const char *theAudioPriorityNames[] = -{ - "LOWEST", - "LOW", - "NORMAL", - "HIGH", - "CRITICAL", - NULL -}; - -const char *theSoundTypeNames[] = -{ - "UI", - "WORLD", - "SHROUDED", - "GLOBAL", - "VOICE", - "PLAYER", - "ALLIES", - "ENEMIES", - "EVERYONE", - NULL -}; - -const char *theAudioControlNames[] = -{ - "LOOP", - "RANDOM", - "ALL", - "POSTDELAY", - "INTERRUPT", - NULL -}; - diff --git a/Generals/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp b/Generals/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp deleted file mode 100644 index d189db39bdb..00000000000 --- a/Generals/Code/GameEngine/Source/Common/INI/INIMiscAudio.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - - -#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine - -#include "Common/MiscAudio.h" -#include "Common/INI.h" - -const FieldParse MiscAudio::m_fieldParseTable[] = -{ - { "RadarNotifyUnitUnderAttackSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_radarUnitUnderAttackSound ) }, - { "RadarNotifyHarvesterUnderAttackSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_radarHarvesterUnderAttackSound ) }, - { "RadarNotifyStructureUnderAttackSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_radarStructureUnderAttackSound ) }, - { "RadarNotifyUnderAttackSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_radarUnderAttackSound ) }, - { "RadarNotifyInfiltrationSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_radarInfiltrationSound ) }, - { "RadarNotifyOnlineSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_radarOnlineSound ) }, - { "RadarNotifyOfflineSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_radarOfflineSound ) }, - { "DefectorTimerTickSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_defectorTimerTickSound ) }, - { "DefectorTimerDingSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_defectorTimerDingSound ) }, - { "LockonTickSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_lockonTickSound ) }, - { "AllCheerSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_allCheerSound ) }, - { "BattleCrySound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_battleCrySound ) }, - { "GUIClickSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_guiClickSound ) }, - { "NoCanDoSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_noCanDoSound ) }, - { "StealthDiscoveredSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_stealthDiscoveredSound ) }, - { "StealthNeutralizedSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_stealthNeutralizedSound ) }, - { "MoneyDepositSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_moneyDepositSound ) }, - { "MoneyWithdrawSound", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_moneyWithdrawSound ) }, - { "BuildingDisabled", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_buildingDisabled ) }, - { "BuildingReenabled", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_buildingReenabled ) }, - { "VehicleDisabled", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_vehicleDisabled ) }, - { "VehicleReenabled", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_vehicleReenabled ) }, - { "SplatterVehiclePilotsBrain", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_splatterVehiclePilotsBrain ) }, - { "TerroristInCarMoveVoice", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_terroristInCarMoveVoice ) }, - { "TerroristInCarAttackVoice", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_terroristInCarAttackVoice ) }, - { "TerroristInCarSelectVoice", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_terroristInCarSelectVoice ) }, - { "CrateHeal", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_crateHeal ) }, - { "CrateShroud", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_crateShroud ) }, - { "CrateSalvage", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_crateSalvage ) }, - { "CrateFreeUnit", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_crateFreeUnit ) }, - { "CrateMoney", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_crateMoney ) }, - { "UnitPromoted", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_unitPromoted ) }, - { "RepairSparks", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_repairSparks ) }, - { "SabotageShutDownBuilding", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_sabotageShutDownBuilding ) }, - { "SabotageResetTimeBuilding", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_sabotageResetTimerBuilding ) }, - { "AircraftWheelScreech", INI::parseAudioEventRTS, NULL, offsetof( MiscAudio, m_aircraftWheelScreech ) }, - - { 0, 0, 0, 0 } -}; - - -//------------------------------------------------------------------------------------------------- -void INI::parseMiscAudio( INI *ini ) -{ - ini->initFromINI(TheAudio->friend_getMiscAudio(), MiscAudio::m_fieldParseTable); -} \ No newline at end of file diff --git a/Generals/Code/GameEngine/Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp b/Generals/Code/GameEngine/Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp deleted file mode 100644 index 40db7ee5ad2..00000000000 --- a/Generals/Code/GameEngine/Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//---------------------------------------------------------------------------- -// -// Project: Generals -// -// Module: Debug -// -// File name: AudiDebugDisplay.cpp -// -// Created: 11/13/01 TR -// -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------------- - -#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine - -#include "GameClient/DebugDisplay.h" -#include "Common/GameAudio.h" - -//---------------------------------------------------------------------------- -// Externals -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Defines -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Private Types -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Private Data -//---------------------------------------------------------------------------- - -static DebugDisplayInterface *debugDisplay; - -//---------------------------------------------------------------------------- -// Public Data -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Private Prototypes -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -// Private Functions -//---------------------------------------------------------------------------- - - -static void printFunc( char *text ) -{ - debugDisplay->printf( text ); -} - -//---------------------------------------------------------------------------- -// Public Functions -//---------------------------------------------------------------------------- - - -//============================================================================ -// AudioDebugDisplay -//============================================================================ - -#if defined(RTS_DEBUG) -void AudioDebugDisplay ( DebugDisplayInterface *dd, void *, FILE *fp = NULL ) -{ - TheAudio->audioDebugDisplay( dd, NULL, fp ); -} -#endif - diff --git a/Generals/Code/GameEngineDevice/CMakeLists.txt b/Generals/Code/GameEngineDevice/CMakeLists.txt index 788db71e84c..bf2aef874bd 100644 --- a/Generals/Code/GameEngineDevice/CMakeLists.txt +++ b/Generals/Code/GameEngineDevice/CMakeLists.txt @@ -1,5 +1,5 @@ set(GAMEENGINEDEVICE_SRC - Include/MilesAudioDevice/MilesAudioManager.h +# Include/MilesAudioDevice/MilesAudioManager.h Include/VideoDevice/Bink/BinkVideoPlayer.h Include/W3DDevice/Common/W3DConvert.h Include/W3DDevice/Common/W3DFunctionLexicon.h @@ -78,7 +78,7 @@ set(GAMEENGINEDEVICE_SRC # Include/Win32Device/Common/Win32LocalFileSystem.h Include/Win32Device/GameClient/Win32DIKeyboard.h Include/Win32Device/GameClient/Win32Mouse.h - Source/MilesAudioDevice/MilesAudioManager.cpp +# Source/MilesAudioDevice/MilesAudioManager.cpp Source/VideoDevice/Bink/BinkVideoPlayer.cpp Source/W3DDevice/Common/System/W3DFunctionLexicon.cpp Source/W3DDevice/Common/System/W3DRadar.cpp diff --git a/Generals/Code/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h b/Generals/Code/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h deleted file mode 100644 index d113cc5f3c3..00000000000 --- a/Generals/Code/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h +++ /dev/null @@ -1,332 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -// FILE: MilesAudioManager.h ////////////////////////////////////////////////////////////////////////// -// MilesAudioManager implementation -// Author: John K. McDonald, July 2002 - -#include "Common/AsciiString.h" -#include "Common/GameAudio.h" -#include "mss/mss.h" - -class AudioEventRTS; - -enum { MAXPROVIDERS = 64 }; - -enum PlayingAudioType CPP_11(: Int) -{ - PAT_Sample, - PAT_3DSample, - PAT_Stream, - PAT_INVALID -}; - -enum PlayingStatus CPP_11(: Int) -{ - PS_Playing, - PS_Stopped, - PS_Paused -}; - -enum PlayingWhich CPP_11(: Int) -{ - PW_Attack, - PW_Sound, - PW_Decay, - PW_INVALID -}; - -struct PlayingAudio -{ - union - { - HSAMPLE m_sample; - H3DSAMPLE m_3DSample; - HSTREAM m_stream; - }; - - PlayingAudioType m_type; - volatile PlayingStatus m_status; // This member is adjusted by another running thread. - AudioEventRTS *m_audioEventRTS; - void *m_file; // The file that was opened to play this - Bool m_requestStop; - Bool m_cleanupAudioEventRTS; - Int m_framesFaded; - - PlayingAudio() : - m_type(PAT_INVALID), - m_audioEventRTS(NULL), - m_requestStop(false), - m_cleanupAudioEventRTS(true), - m_sample(NULL), - m_framesFaded(0) - { } -}; - -struct ProviderInfo -{ - AsciiString name; - HPROVIDER id; - Bool m_isValid; -}; - -struct OpenAudioFile -{ - AILSOUNDINFO m_soundInfo; - void *m_file; - UnsignedInt m_openCount; - UnsignedInt m_fileSize; - - Bool m_compressed; // if the file was compressed, then we need to free it with a miles function. - - // Note: OpenAudioFile does not own this m_eventInfo, and should not delete it. - const AudioEventInfo *m_eventInfo; // Not mutable, unlike the one on AudioEventRTS. -}; - -typedef std::hash_map< AsciiString, OpenAudioFile, rts::hash, rts::equal_to > OpenFilesHash; -typedef OpenFilesHash::iterator OpenFilesHashIt; - -class AudioFileCache -{ - public: - AudioFileCache(); - - // Protected by mutex - virtual ~AudioFileCache(); - void *openFile( AudioEventRTS *eventToOpenFrom ); - void closeFile( void *fileToClose ); - void setMaxSize( UnsignedInt size ); - // End Protected by mutex - - // Note: These functions should be used for informational purposes only. For speed reasons, - // they are not protected by the mutex, so they are not guarenteed to be valid if called from - // outside the audio cache. They should be used as a rough estimate only. - UnsignedInt getCurrentlyUsedSize() const { return m_currentlyUsedSize; } - UnsignedInt getMaxSize() const { return m_maxSize; } - - protected: - void releaseOpenAudioFile( OpenAudioFile *fileToRelease ); - - // This function will return TRUE if it was able to free enough space, and FALSE otherwise. - Bool freeEnoughSpaceForSample(const OpenAudioFile& sampleThatNeedsSpace); - - OpenFilesHash m_openFiles; - UnsignedInt m_currentlyUsedSize; - UnsignedInt m_maxSize; - HANDLE m_mutex; - const char *m_mutexName; -}; - -class MilesAudioManager : public AudioManager -{ - - public: -#if defined(RTS_DEBUG) - virtual void audioDebugDisplay(DebugDisplayInterface *dd, void *, FILE *fp = NULL ); - virtual AudioHandle addAudioEvent( const AudioEventRTS *eventToAdd ); ///< Add an audio event (event must be declared in an INI file) -#endif - - // from AudioDevice - virtual void init(); - virtual void postProcessLoad(); - virtual void reset(); - virtual void update(); - - MilesAudioManager(); - virtual ~MilesAudioManager(); - - - virtual void nextMusicTrack( void ); - virtual void prevMusicTrack( void ); - virtual Bool isMusicPlaying( void ) const; - virtual Bool hasMusicTrackCompleted( const AsciiString& trackName, Int numberOfTimes ) const; - virtual AsciiString getMusicTrackName( void ) const; - - virtual void openDevice( void ); - virtual void closeDevice( void ); - virtual void *getDevice( void ) { return m_digitalHandle; } - - virtual void stopAudio( AudioAffect which ); - virtual void pauseAudio( AudioAffect which ); - virtual void resumeAudio( AudioAffect which ); - virtual void pauseAmbient( Bool shouldPause ); - - virtual void killAudioEventImmediately( AudioHandle audioEvent ); - - ///< Return whether the current audio is playing or not. - ///< NOTE NOTE NOTE !!DO NOT USE THIS IN FOR GAMELOGIC PURPOSES!! NOTE NOTE NOTE - virtual Bool isCurrentlyPlaying( AudioHandle handle ); - - virtual void notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags ); - virtual PlayingAudio *findPlayingAudioFrom( UnsignedInt audioCompleted, UnsignedInt flags ); - - virtual UnsignedInt getProviderCount( void ) const; - virtual AsciiString getProviderName( UnsignedInt providerNum ) const; - virtual UnsignedInt getProviderIndex( AsciiString providerName ) const; - virtual void selectProvider( UnsignedInt providerNdx ); - virtual void unselectProvider( void ); - virtual UnsignedInt getSelectedProvider( void ) const; - virtual void setSpeakerType( UnsignedInt speakerType ); - virtual UnsignedInt getSpeakerType( void ); - - virtual void *getHandleForBink( void ); - virtual void releaseHandleForBink( void ); - - virtual void friend_forcePlayAudioEventRTS(const AudioEventRTS* eventToPlay); - - virtual UnsignedInt getNum2DSamples( void ) const; - virtual UnsignedInt getNum3DSamples( void ) const; - virtual UnsignedInt getNumStreams( void ) const; - - virtual Bool doesViolateLimit( AudioEventRTS *event ) const; - virtual Bool isPlayingLowerPriority( AudioEventRTS *event ) const; - virtual Bool isPlayingAlready( AudioEventRTS *event ) const; - virtual Bool isObjectPlayingVoice( UnsignedInt objID ) const; - Bool killLowestPrioritySoundImmediately( AudioEventRTS *event ); - AudioEventRTS* findLowestPrioritySound( AudioEventRTS *event ); - - virtual void adjustVolumeOfPlayingAudio(AsciiString eventName, Real newVolume); - - virtual void removePlayingAudio( AsciiString eventName ); - virtual void removeAllDisabledAudio(); - - virtual void processRequestList( void ); - virtual void processPlayingList( void ); - virtual void processFadingList( void ); - virtual void processStoppedList( void ); - - Bool shouldProcessRequestThisFrame( AudioRequest *req ) const; - void adjustRequest( AudioRequest *req ); - Bool checkForSample( AudioRequest *req ); - - virtual void setHardwareAccelerated(Bool accel); - virtual void setSpeakerSurround(Bool surround); - - virtual void setPreferredProvider(AsciiString provider) { m_pref3DProvider = provider; } - virtual void setPreferredSpeaker(AsciiString speakerType) { m_prefSpeaker = speakerType; } - - virtual Real getFileLengthMS( AsciiString strToLoad ) const; - - virtual void closeAnySamplesUsingFile( const void *fileToClose ); - - - virtual Bool has3DSensitiveStreamsPlaying( void ) const; - - - protected: - // 3-D functions - virtual void setDeviceListenerPosition( void ); - const Coord3D *getCurrentPositionFromEvent( AudioEventRTS *event ); - Bool isOnScreen( const Coord3D *pos ) const; - Real getEffectiveVolume(AudioEventRTS *event) const; - - // Looping functions - Bool startNextLoop( PlayingAudio *looping ); - - void playStream( AudioEventRTS *event, HSTREAM stream ); - // Returns the file handle for attachment to the PlayingAudio structure - void *playSample( AudioEventRTS *event, HSAMPLE sample ); - void *playSample3D( AudioEventRTS *event, H3DSAMPLE sample3D ); - - protected: - void buildProviderList( void ); - void createListener( void ); - void initDelayFilter( void ); - Bool isValidProvider( void ); - void initSamplePools( void ); - void processRequest( AudioRequest *req ); - - void playAudioEvent( AudioEventRTS *event ); - void stopAudioEvent( AudioHandle handle ); - void pauseAudioEvent( AudioHandle handle ); - - void *loadFileForRead( AudioEventRTS *eventToLoadFrom ); - void closeFile( void *fileRead ); - - PlayingAudio *allocatePlayingAudio( void ); - void releaseMilesHandles( PlayingAudio *release ); - void releasePlayingAudio( PlayingAudio *release ); - - void stopAllAudioImmediately( void ); - void freeAllMilesHandles( void ); - - HSAMPLE getFirst2DSample( AudioEventRTS *event ); - H3DSAMPLE getFirst3DSample( AudioEventRTS *event ); - - void adjustPlayingVolume( PlayingAudio *audio ); - - void stopAllSpeech( void ); - - protected: - void initFilters( HSAMPLE sample, const AudioEventRTS *eventInfo ); - void initFilters3D( H3DSAMPLE sample, const AudioEventRTS *eventInfo, const Coord3D *pos ); - - protected: - ProviderInfo m_provider3D[MAXPROVIDERS]; - UnsignedInt m_providerCount; - UnsignedInt m_selectedProvider; - UnsignedInt m_lastProvider; - UnsignedInt m_selectedSpeakerType; - - AsciiString m_pref3DProvider; - AsciiString m_prefSpeaker; - - HDIGDRIVER m_digitalHandle; - H3DPOBJECT m_listener; - HPROVIDER m_delayFilter; - - // This is a list of all handles that are forcibly played. They always play as UI sounds. - std::list m_audioForcePlayed; - - // Available handles for play. Note that there aren't handles open in advance for - // streaming things, only 2-D and 3-D sounds. - std::list m_availableSamples; - std::list m_available3DSamples; - - // Currently Playing stuff. Useful if we have to preempt it. - // This should rarely if ever happen, as we mirror this in Sounds, and attempt to - // keep preemption from taking place here. - std::list m_playingSounds; - std::list m_playing3DSounds; - std::list m_playingStreams; - - // Currently fading stuff. At this point, we just want to let it finish fading, when it is - // done it should be added to the completed list, then "freed" and the counts should be updated - // on the next update - std::list m_fadingAudio; - - // Stuff that is done playing (either because it has finished or because it was killed) - // This stuff should be cleaned up during the next update cycle. This includes updating counts - // in the sound engine - std::list m_stoppedAudio; - - AudioFileCache *m_audioCache; - PlayingAudio *m_binkHandle; - UnsignedInt m_num2DSamples; - UnsignedInt m_num3DSamples; - UnsignedInt m_numStreams; - -#if defined(RTS_DEBUG) - typedef std::set SetAsciiString; - typedef SetAsciiString::iterator SetAsciiStringIt; - SetAsciiString m_allEventsLoaded; - void dumpAllAssetsUsed(); -#endif - -}; - diff --git a/Generals/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Generals/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp deleted file mode 100644 index ecc78f02b43..00000000000 --- a/Generals/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp +++ /dev/null @@ -1,3386 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: MilesAudioManager.cpp -/*---------------------------------------------------------------------------*/ -/* EA Pacific */ -/* Confidential Information */ -/* Copyright (C) 2001 - All Rights Reserved */ -/* DO NOT DISTRIBUTE */ -/*---------------------------------------------------------------------------*/ -/* Project: RTS3 */ -/* File name: MilesAudioManager.cpp */ -/* Created: John K. McDonald, Jr., 3/21/2002 */ -/* Desc: This is the implementation for the MilesAudioManager, which */ -/* interfaces with the Miles Sound System. */ -/* Revision History: */ -/* 7/18/2002 : Initial creation */ -/*---------------------------------------------------------------------------*/ - -#include -#include "Lib/BaseType.h" -#include "MilesAudioDevice/MilesAudioManager.h" - -#include "Common/AudioAffect.h" -#include "Common/AudioHandleSpecialValues.h" -#include "Common/AudioRequest.h" -#include "Common/AudioSettings.h" -#include "Common/AsciiString.h" -#include "Common/AudioEventInfo.h" -#include "Common/FileSystem.h" -#include "Common/GameCommon.h" -#include "Common/GameSounds.h" -#include "Common/CRCDebug.h" -#include "Common/GlobalData.h" -#include "Common/ScopedMutex.h" - -#include "GameClient/DebugDisplay.h" -#include "GameClient/Drawable.h" -#include "GameClient/GameClient.h" -#include "GameClient/VideoPlayer.h" -#include "GameClient/View.h" - -#include "GameLogic/GameLogic.h" -#include "GameLogic/TerrainLogic.h" - -#include "Common/file.h" - - -enum { INFINITE_LOOP_COUNT = 1000000 }; - -// Callback functions useful for Miles //////////////////////////////////////////////////////////// -static void AILCALLBACK setSampleCompleted( HSAMPLE sampleCompleted ); -static void AILCALLBACK set3DSampleCompleted( H3DSAMPLE sample3DCompleted ); -static void AILCALLBACK setStreamCompleted( HSTREAM streamCompleted ); - -static U32 AILCALLBACK streamingFileOpen(char const *fileName, U32 *file_handle); -static void AILCALLBACK streamingFileClose(U32 fileHandle); -static S32 AILCALLBACK streamingFileSeek(U32 fileHandle, S32 offset, U32 type); -static U32 AILCALLBACK streamingFileRead(U32 fileHandle, void *buffer, U32 bytes); - -//------------------------------------------------------------------------------------------------- -MilesAudioManager::MilesAudioManager() : - m_providerCount(0), - m_selectedProvider(PROVIDER_ERROR), - m_selectedSpeakerType(0), - m_lastProvider(PROVIDER_ERROR), - m_digitalHandle(NULL), - m_num2DSamples(0), - m_num3DSamples(0), - m_numStreams(0), - m_delayFilter(NULL), - m_binkHandle(NULL), - m_pref3DProvider(AsciiString::TheEmptyString), - m_prefSpeaker(AsciiString::TheEmptyString) -{ - m_audioCache = NEW AudioFileCache; -} - -//------------------------------------------------------------------------------------------------- -MilesAudioManager::~MilesAudioManager() -{ - DEBUG_ASSERTCRASH(m_binkHandle == NULL, ("Leaked a Bink handle. Chuybregts")); - releaseHandleForBink(); - closeDevice(); - delete m_audioCache; - - DEBUG_ASSERTCRASH(this == TheAudio, ("Umm...")); - TheAudio = NULL; -} - -//------------------------------------------------------------------------------------------------- -#if defined(RTS_DEBUG) -AudioHandle MilesAudioManager::addAudioEvent( const AudioEventRTS *eventToAdd ) -{ - if (TheGlobalData->m_preloadReport) { - if (!eventToAdd->getEventName().isEmpty()) { - m_allEventsLoaded.insert(eventToAdd->getEventName()); - } - } - - return AudioManager::addAudioEvent(eventToAdd); -} -#endif - -#if defined(RTS_DEBUG) -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FILE *fp ) -{ - std::list::iterator it; - - static char buffer[128] = { 0 }; - if (buffer[0] == 0) { - AIL_MSS_version(buffer, 128); - } - - Coord3D lookPos; - TheTacticalView->getPosition( &lookPos ); - lookPos.z = TheTerrainLogic->getGroundHeight( lookPos.x, lookPos.y ); - const Coord3D *mikePos = TheAudio->getListenerPosition(); - Coord3D distanceVector = TheTacticalView->get3DCameraPosition(); - distanceVector.sub( mikePos ); - - Int now = TheGameLogic->getFrame(); - static Int lastCheck = now; - const Int frames = 60; - static Int latency = 0; - static Int worstLatency = 0; - if( lastCheck + frames <= now ) - { - latency = AIL_get_timer_highest_delay(); - if( latency > worstLatency ) - { - worstLatency = latency; - } - lastCheck = now; - } - - if( dd ) - { - dd->printf("Miles Sound System version: %s ", buffer); - dd->printf("Memory Usage : %d/%d\n", m_audioCache->getCurrentlyUsedSize(), m_audioCache->getMaxSize()); - dd->printf("Sound: %s ", (isOn(AudioAffect_Sound) ? "Yes" : "No")); - dd->printf("3DSound: %s ", (isOn(AudioAffect_Sound3D) ? "Yes" : "No")); - dd->printf("Speech: %s ", (isOn(AudioAffect_Speech) ? "Yes" : "No")); - dd->printf("Music: %s\n", (isOn(AudioAffect_Music) ? "Yes" : "No")); - dd->printf("Channels Available: "); - dd->printf("%d Sounds ", m_sound->getAvailableSamples()); - - dd->printf("%d(%d) 3D Sounds\n", m_sound->getAvailable3DSamples(), m_available3DSamples.size() ); - dd->printf("Volume: "); - dd->printf("Sound: %d ", REAL_TO_INT(m_soundVolume * 100.0f)); - dd->printf("3DSound: %d ", REAL_TO_INT(m_sound3DVolume * 100.0f)); - dd->printf("Speech: %d ", REAL_TO_INT(m_speechVolume * 100.0f)); - dd->printf("Music: %d\n", REAL_TO_INT(m_musicVolume * 100.0f)); - dd->printf("Current 3D Provider: %s ", - - TheAudio->getProviderName(m_selectedProvider).str()); - dd->printf("Current Speaker Type: %s\n", TheAudio->translateUnsignedIntToSpeakerType(TheAudio->getSpeakerType()).str()); - - dd->printf( "Looking at: (%d,%d,%d) -- Microphone at: (%d,%d,%d)\n", - (Int)lookPos.x, (Int)lookPos.y, (Int)lookPos.z, (Int)mikePos->x, (Int)mikePos->y, (Int)mikePos->z ); - dd->printf( "Camera distance from microphone: %d -- Zoom Volume: %d%%\n", - (Int)distanceVector.length(), (Int)(TheAudio->getZoomVolume()*100.0f) ); - dd->printf( "Worst latency: %d -- Current latency: %d\n", worstLatency, latency ); - - dd->printf("-----------------------------------------------------------\n"); - dd->printf("Playing Audio\n"); - } - if( fp ) - { - fprintf( fp, "Miles Sound System version: %s ", buffer ); - fprintf( fp, "Memory Usage : %d/%d\n", m_audioCache->getCurrentlyUsedSize(), m_audioCache->getMaxSize() ); - fprintf( fp, "Sound: %s ", (isOn(AudioAffect_Sound) ? "Yes" : "No") ); - fprintf( fp, "3DSound: %s ", (isOn(AudioAffect_Sound3D) ? "Yes" : "No") ); - fprintf( fp, "Speech: %s ", (isOn(AudioAffect_Speech) ? "Yes" : "No") ); - fprintf( fp, "Music: %s\n", (isOn(AudioAffect_Music) ? "Yes" : "No") ); - fprintf( fp, "Channels Available: " ); - fprintf( fp, "%d Sounds ", m_sound->getAvailableSamples() ); - fprintf( fp, "%d 3D Sounds\n", m_sound->getAvailable3DSamples() ); - fprintf( fp, "Volume: "); - fprintf( fp, "Sound: %d ", REAL_TO_INT(m_soundVolume * 100.0f) ); - fprintf( fp, "3DSound: %d ", REAL_TO_INT(m_sound3DVolume * 100.0f) ); - fprintf( fp, "Speech: %d ", REAL_TO_INT(m_speechVolume * 100.0f) ); - fprintf( fp, "Music: %d\n", REAL_TO_INT(m_musicVolume * 100.0f) ); - fprintf( fp, "Current 3D Provider: %s ", TheAudio->getProviderName(m_selectedProvider).str()); - fprintf( fp, "Current Speaker Type: %s\n", TheAudio->translateUnsignedIntToSpeakerType(TheAudio->getSpeakerType()).str()); - - fprintf( fp, "Looking at: (%d,%d,%d) -- Microphone at: (%d,%d,%d)\n", - (Int)lookPos.x, (Int)lookPos.y, (Int)lookPos.z, (Int)mikePos->x, (Int)mikePos->y, (Int)mikePos->z ); - fprintf( fp, "Camera distance from microphone: %d -- Zoom Volume: %d%%\n", - (Int)distanceVector.length(), (Int)(TheAudio->getZoomVolume()*100.0f) ); - - fprintf( fp, "-----------------------------------------------------------\n" ); - fprintf( fp, "Playing Audio\n" ); - } - - PlayingAudio *playing = NULL; - Int channel; - Int channelCount; - Real volume = 0.0f; - AsciiString filenameNoSlashes; - - const Int maxChannels = 64; - PlayingAudio *playingArray[maxChannels] = { NULL }; - - // 2-D Sounds - if( dd ) - { - dd->printf("-----------------------------------------------------Sounds\n"); - channelCount = TheAudio->getNum2DSamples(); - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { - playing = *it; - if (!playing) { - continue; - } - - playingArray[AIL_sample_user_data(playing->m_sample, 0)] = playing; - } - - for (Int i = 1; i <= maxChannels && i <= channelCount; ++i) { - playing = playingArray[i]; - if (!playing) { - dd->printf("%d: Silence\n", i); - continue; - } - - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); - filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1; - - // Calculate Sample volume - volume = 100.0f; - volume *= getEffectiveVolume(playing->m_audioEventRTS); - - dd->printf("%2d: %-20s - (%s) Volume: %d (2D)\n", i, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume)); - playingArray[i] = NULL; - } - } - if( fp ) - { - fprintf( fp, "-----------------------------------------------------Sounds\n" ); - channelCount = TheAudio->getNum2DSamples(); - channel = 1; - for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) - { - playing = *it; - if( !playing ) - { - continue; - } - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); - filenameNoSlashes = filenameNoSlashes.reverseFind( '\\' ) + 1; - - // Calculate Sample volume - volume = 100.0f; - volume *= getEffectiveVolume( playing->m_audioEventRTS ); - - fprintf( fp, "%2d: %-20s - (%s) Volume: %d (2D)\n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) ); - } - for( int i = channel; i <= channelCount; ++i ) - { - fprintf( fp, "%d: Silence\n", i ); - } - } - - const Coord3D *microphonePos = TheAudio->getListenerPosition(); - - // Now 3D Sounds - if( dd ) - { - dd->printf("--------------------------------------------------3D Sounds\n"); - channelCount = TheAudio->getNum3DSamples(); - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { - playing = *it; - if (!playing) { - continue; - } - - playingArray[AIL_3D_user_data(playing->m_3DSample, 0)] = playing; - } - - for (Int i = 1; i <= maxChannels && i <= channelCount; ++i) - { - playing = playingArray[i]; - if (!playing) - { - dd->printf("%d: Silence\n", i); - continue; - } - - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); - filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1; - - // Calculate Sample volume - volume = 100.0f; - volume *= getEffectiveVolume(playing->m_audioEventRTS); - Real dist = -1.0f; - const Coord3D *pos = playing->m_audioEventRTS->getPosition(); - char distStr[32]; - if( pos ) - { - Coord3D vector = *microphonePos; - vector.sub( pos ); - dist = vector.length(); - sprintf( distStr, "%d", REAL_TO_INT( dist ) ); - } - else - { - sprintf( distStr, "???" ); - } - char str[32]; - switch( playing->m_audioEventRTS->getOwnerType() ) - { - case OT_Positional: - sprintf( str, "(3D)" ); - break; - case OT_Object: - sprintf( str, "(3DObj)" ); - break; - case OT_Drawable: - sprintf( str, "(3DDraw)" ); - break; - case OT_Dead: - sprintf( str, "(3DDead)" ); - break; - - } - - dd->printf("%2d: %-20s - (%s) Volume: %d, Dist: %s, %s\n", - i, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume), distStr, str ); - playingArray[i] = NULL; - } - } - if( fp ) - { - fprintf( fp, "--------------------------------------------------3D Sounds\n" ); - channelCount = TheAudio->getNum3DSamples(); - channel = 1; - for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) - { - playing = *it; - if( !playing ) - { - continue; - } - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); - filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1; - - // Calculate Sample volume - volume = 100.0f; - volume *= getEffectiveVolume( playing->m_audioEventRTS ); - fprintf( fp, "%2d: %-24s - (%s) Volume: %d \n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) ); - } - - for( int i = channel; i <= channelCount; ++i ) - { - fprintf( fp, "%2d: Silence\n", i ); - } - } - - // Now Streams - if( dd ) - { - dd->printf("----------------------------------------------------Streams\n"); - channelCount = TheAudio->getNumStreams(); - channel = 1; - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (!playing) { - continue; - } - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); - filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1; - - - // Calculate Sample volume - volume = 100.0f; - volume *= getEffectiveVolume(playing->m_audioEventRTS); - - dd->printf("%2d: %-24s - (%s) Volume: %d (Stream)\n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume)); - } - - for ( int i = channel; i <= channelCount; ++i) { - dd->printf("%2d: Silence\n", i); - } - dd->printf("===========================================================\n"); - } - if( fp ) - { - fprintf( fp, "----------------------------------------------------Streams\n" ); - channelCount = TheAudio->getNumStreams(); - channel = 1; - for( it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it ) - { - playing = *it; - if( !playing ) - { - continue; - } - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); - filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1; - - // Calculate Sample volume - volume = 100.0f; - volume *= getEffectiveVolume(playing->m_audioEventRTS); - - fprintf( fp, "%2d: %-24s - (%s) Volume: %d (Stream)\n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) ); - } - - for( int i = channel; i <= channelCount; ++i ) - { - fprintf( fp, "%2d: Silence\n", i ); - } - fprintf( fp, "===========================================================\n" ); - } -} -#endif - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::init() -{ - AudioManager::init(); -#ifdef INTENSE_DEBUG - DEBUG_LOG(("Sound has temporarily been disabled in debug builds only. jkmcd")); - // for now, RTS_DEBUG builds only should have no sound. ask jkmcd or srj about this. - return; -#endif - - // We should now know how many samples we want to load - openDevice(); - m_audioCache->setMaxSize(getAudioSettings()->m_maxCacheSize); - - // Now, set the file callbacks to load the streams from Biggie files - AIL_set_file_callbacks(streamingFileOpen, streamingFileClose, streamingFileSeek, streamingFileRead); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::postProcessLoad() -{ - AudioManager::postProcessLoad(); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::reset() -{ -#if defined(RTS_DEBUG) - dumpAllAssetsUsed(); - m_allEventsLoaded.clear(); -#endif - - AudioManager::reset(); - stopAllAudioImmediately(); - removeAllAudioRequests(); - // This must come after stopAllAudioImmediately() and removeAllAudioRequests(), to ensure that - // sounds pointing to the temporary AudioEventInfo handles are deleted before their info is deleted - removeLevelSpecificAudioEventInfos(); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::update() -{ - AudioManager::update(); - setDeviceListenerPosition(); - processRequestList(); - processPlayingList(); - processFadingList(); - processStoppedList(); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::stopAudio( AudioAffect which ) -{ - // 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) - // 3) Set the status to stopped, so that when we next process the playing list, we will - // correctly clean up the sample. - - - std::list::iterator it; - - PlayingAudio *playing = NULL; - if (BitIsSet(which, AudioAffect_Sound)) { - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { - playing = *it; - if (playing) { - AIL_register_EOS_callback(playing->m_sample, NULL); - AIL_stop_sample(playing->m_sample); - playing->m_status = PS_Stopped; - } - } - } - - if (BitIsSet(which, AudioAffect_Sound3D)) { - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { - playing = *it; - if (playing) { - AIL_register_3D_EOS_callback(playing->m_3DSample, NULL); - AIL_stop_3D_sample(playing->m_3DSample); - playing->m_status = PS_Stopped; - } - } - } - - if (BitIsSet(which, AudioAffect_Speech | AudioAffect_Music)) { - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing) { - if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - if (!BitIsSet(which, AudioAffect_Music)) { - continue; - } - } else { - if (!BitIsSet(which, AudioAffect_Speech)) { - continue; - } - } - AIL_register_stream_callback(playing->m_stream, NULL); - AIL_pause_stream(playing->m_stream, 1); - playing->m_status = PS_Stopped; - } - } - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::pauseAudio( AudioAffect which ) -{ - std::list::iterator it; - - PlayingAudio *playing = NULL; - if (BitIsSet(which, AudioAffect_Sound)) { - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { - playing = *it; - if (playing) { - AIL_stop_sample(playing->m_sample); - } - } - } - - if (BitIsSet(which, AudioAffect_Sound3D)) { - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { - playing = *it; - if (playing) { - AIL_stop_3D_sample(playing->m_3DSample); - } - } - } - - if (BitIsSet(which, AudioAffect_Speech | AudioAffect_Music)) { - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing) { - if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - if (!BitIsSet(which, AudioAffect_Music)) { - continue; - } - } else { - if (!BitIsSet(which, AudioAffect_Speech)) { - continue; - } - } - - AIL_pause_stream(playing->m_stream, 1); - } - } - } - - //Get rid of PLAY audio requests when pausing audio. - std::list::iterator ait; - for (ait = m_audioRequests.begin(); ait != m_audioRequests.end(); /* empty */) - { - AudioRequest *req = (*ait); - if( req && req->m_request == AR_Play ) - { - deleteInstance(req); - ait = m_audioRequests.erase(ait); - } - else - { - ait++; - } - } -} - - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::resumeAudio( AudioAffect which ) -{ - std::list::iterator it; - - PlayingAudio *playing = NULL; - if (BitIsSet(which, AudioAffect_Sound)) { - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { - playing = *it; - if (playing) { - AIL_resume_sample(playing->m_sample); - } - } - } - - if (BitIsSet(which, AudioAffect_Sound3D)) { - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { - playing = *it; - if (playing) { - AIL_resume_3D_sample(playing->m_3DSample); - } - } - } - - if (BitIsSet(which, AudioAffect_Speech | AudioAffect_Music)) { - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing) { - if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - if (!BitIsSet(which, AudioAffect_Music)) { - continue; - } - } else { - if (!BitIsSet(which, AudioAffect_Speech)) { - continue; - } - } - AIL_pause_stream(playing->m_stream, 0); - } - } - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::pauseAmbient( Bool shouldPause ) -{ - -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::playAudioEvent( AudioEventRTS *event ) -{ -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("MILES (%d) - Processing play request: %d (%s)", TheGameLogic->getFrame(), event->getPlayingHandle(), event->getEventName().str())); -#endif - const AudioEventInfo *info = event->getAudioEventInfo(); - if (!info) { - return; - } - - std::list::iterator it; - PlayingAudio *playing = NULL; - - AudioHandle handleToKill = event->getHandleToKill(); - - AsciiString fileToPlay = event->getFilename(); - PlayingAudio *audio = allocatePlayingAudio(); - switch(info->m_soundType) - { - case AT_Music: - case AT_Streaming: - { - #ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("- Stream")); - #endif - - if ((info->m_soundType == AT_Streaming) && event->getUninterruptable()) { - stopAllSpeech(); - } - - Real curVolume = 1.0; - if (info->m_soundType == AT_Music) { - curVolume = m_musicVolume; - } else { - curVolume = m_speechVolume; - } - curVolume *= event->getVolume(); - - Bool foundSoundToReplace = false; - if (handleToKill) { - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = (*it); - if (!playing) { - continue; - } - - if (playing->m_audioEventRTS && playing->m_audioEventRTS->getPlayingHandle() == handleToKill) - { - //Release this streaming channel immediately because we are going to play another sound in it's place. - releasePlayingAudio(playing); - m_playingStreams.erase(it); - foundSoundToReplace = true; - break; - } - } - } - - HSTREAM stream; - if (!handleToKill || foundSoundToReplace) { - stream = AIL_open_stream(m_digitalHandle, fileToPlay.str(), 0); - } else { - stream = NULL; - } - - // Put this on here, so that the audio event RTS will be cleaned up regardless. - audio->m_audioEventRTS = event; - audio->m_stream = stream; - audio->m_type = PAT_Stream; - - if (stream) { - if ((info->m_soundType == AT_Streaming) && event->getUninterruptable()) { - setDisallowSpeech(TRUE); - } - AIL_set_stream_volume_pan(stream, curVolume, 0.5f); - playStream(event, stream); - m_playingStreams.push_back(audio); - audio = NULL; - } - break; - } - - case AT_SoundEffect: - { - #ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("- Sound")); - #endif - - - if (event->isPositionalAudio()) { - // Sounds that are non-global are positional 3-D sounds. Deal with them accordingly - #ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG((" Positional")); - #endif - Bool foundSoundToReplace = false; - if (handleToKill) - { - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { - playing = (*it); - if (!playing) { - continue; - } - - if( playing->m_audioEventRTS && playing->m_audioEventRTS->getPlayingHandle() == handleToKill ) - { - //Release this 3D sound channel immediately because we are going to play another sound in it's place. - releasePlayingAudio(playing); - m_playing3DSounds.erase(it); - foundSoundToReplace = true; - break; - } - } - } - - H3DSAMPLE sample3D; - if( !handleToKill || foundSoundToReplace ) - { - sample3D = getFirst3DSample( event ); - if( !sample3D ) - { - //If we don't have an available sample, kill the lowest priority assuming we have one that is lower - //than the sound we are trying to add. One possibility for strangeness is when an interrupt sound - //that wants to kill a handle to replace it, it's possible that another request already killed it, - //in which case we need to attempt to find another sound to kill. - if( killLowestPrioritySoundImmediately( event ) ) - { - sample3D = getFirst3DSample( event ); - } - } - } - else - { - sample3D = NULL; - } - // Push it onto the list of playing things - audio->m_audioEventRTS = event; - audio->m_3DSample = sample3D; - audio->m_file = NULL; - audio->m_type = PAT_3DSample; - m_playing3DSounds.push_back(audio); - - if (sample3D) { - audio->m_file = playSample3D(event, sample3D); - m_sound->notifyOf3DSampleStart(); - } - - if( !audio->m_file ) - { - m_playing3DSounds.pop_back(); - #ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG((" Killed (no handles available)")); - #endif - } - else - { - audio = NULL; - #ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG((" Playing.")); - #endif - } - } - else - { - // UI sounds are always 2-D. All other sounds should be Positional - // Unit acknowledgement, etc, falls into the UI category of sound. - Bool foundSoundToReplace = false; - if (handleToKill) { - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { - playing = (*it); - if (!playing) { - continue; - } - - if (playing->m_audioEventRTS && playing->m_audioEventRTS->getPlayingHandle() == handleToKill) - { - //Release this 2D sound channel immediately because we are going to play another sound in it's place. - releasePlayingAudio(playing); - m_playingSounds.erase(it); - foundSoundToReplace = true; - break; - } - } - } - - HSAMPLE sample; - if( !handleToKill || foundSoundToReplace ) - { - sample = getFirst2DSample(event); - if( !sample ) - { - //If we don't have an available sample, kill the lowest priority assuming we have one that is lower - //than the sound we are trying to add. One possibility for strangeness is when an interrupt sound - //that wants to kill a handle to replace it, it's possible that another request already killed it, - //in which case we need to attempt to find another sound to kill. - if( killLowestPrioritySoundImmediately( event ) ) - { - sample = getFirst2DSample( event ); - } - } - } - else - { - sample = NULL; - } - - // Push it onto the list of playing things - audio->m_audioEventRTS = event; - audio->m_sample = sample; - audio->m_file = NULL; - audio->m_type = PAT_Sample; - m_playingSounds.push_back(audio); - - if (sample) { - audio->m_file = playSample(event, sample); - m_sound->notifyOf2DSampleStart(); - } - - if (!audio->m_file) { - #ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG((" Killed (no handles available)")); - #endif - m_playingSounds.pop_back(); - } else { - audio = NULL; - } - - #ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG((" Playing.")); - #endif - } - break; - } - } - - // If we were able to successfully play audio, then we set it to NULL above. (And it will be freed - // later. However, if audio is non-NULL at this point, then it must be freed. - if (audio) { - releasePlayingAudio(audio); - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::stopAudioEvent( AudioHandle handle ) -{ -#ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("MILES (%d) - Processing stop request: %d", TheGameLogic->getFrame(), handle)); -#endif - - std::list::iterator it; - if ( handle == AHSV_StopTheMusic || handle == AHSV_StopTheMusicFade ) { - // for music, just find the currently playing music stream and kill it. - for ( it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it ) { - PlayingAudio *audio = (*it); - if (!audio) { - continue; - } - - if( audio->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music ) - { - if( handle == AHSV_StopTheMusicFade ) - { - m_fadingAudio.push_back(audio); - } - else - { - //m_stoppedAudio.push_back(audio); - releasePlayingAudio( audio ); - } - m_playingStreams.erase(it); - break; - } - } - } - - for ( it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it ) { - PlayingAudio *audio = (*it); - if (!audio) { - continue; - } - - if (audio->m_audioEventRTS->getPlayingHandle() == handle) { - // found it - audio->m_requestStop = true; - notifyOfAudioCompletion((UnsignedInt)(audio->m_stream), PAT_Stream); - break; - } - } - - for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) { - PlayingAudio *audio = (*it); - if (!audio) { - continue; - } - - if (audio->m_audioEventRTS->getPlayingHandle() == handle) { - audio->m_requestStop = true; - break; - } - } - - for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) { - PlayingAudio *audio = (*it); - if (!audio) { - continue; - } - - if (audio->m_audioEventRTS->getPlayingHandle() == handle) { - #ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG((" (%s)", audio->m_audioEventRTS->getEventName())); - #endif - audio->m_requestStop = true; - break; - } - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::killAudioEventImmediately( AudioHandle audioEvent ) -{ - //First look for it in the request list. - std::list::iterator ait; - for( ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ait++ ) - { - AudioRequest *req = (*ait); - if( req && req->m_request == AR_Play && req->m_handleToInteractOn == audioEvent ) - { - deleteInstance(req); - ait = m_audioRequests.erase(ait); - return; - } - } - - //Look for matching 3D sound to kill - std::list::iterator it; - for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); it++ ) - { - PlayingAudio *audio = (*it); - if( !audio ) - { - continue; - } - - if( audio->m_audioEventRTS->getPlayingHandle() == audioEvent ) - { - releasePlayingAudio( audio ); - m_playing3DSounds.erase( it ); - return; - } - } - - //Look for matching 2D sound to kill - for( it = m_playingSounds.begin(); it != m_playingSounds.end(); it++ ) - { - PlayingAudio *audio = (*it); - if( !audio ) - { - continue; - } - - if( audio->m_audioEventRTS->getPlayingHandle() == audioEvent ) - { - releasePlayingAudio( audio ); - m_playingSounds.erase( it ); - return; - } - } - - //Look for matching steaming sound to kill - for( it = m_playingStreams.begin(); it != m_playingStreams.end(); it++ ) - { - PlayingAudio *audio = (*it); - if( !audio ) - { - continue; - } - - if( audio->m_audioEventRTS->getPlayingHandle() == audioEvent ) - { - releasePlayingAudio( audio ); - m_playingStreams.erase( it ); - return; - } - } - -} - - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::pauseAudioEvent( AudioHandle handle ) -{ - // pause audio -} - -//------------------------------------------------------------------------------------------------- -void *MilesAudioManager::loadFileForRead( AudioEventRTS *eventToLoadFrom ) -{ - return m_audioCache->openFile(eventToLoadFrom); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::closeFile( void *fileRead ) -{ - m_audioCache->closeFile(fileRead); -} - - -//------------------------------------------------------------------------------------------------- -PlayingAudio *MilesAudioManager::allocatePlayingAudio( void ) -{ - PlayingAudio *aud = NEW PlayingAudio; // poolify - aud->m_status = PS_Playing; - return aud; -} - - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::releaseMilesHandles( PlayingAudio *release ) -{ - switch (release->m_type) - { - case PAT_Sample: - { - if (release->m_sample) { - AIL_register_EOS_callback(release->m_sample, NULL); - AIL_stop_sample(release->m_sample); - m_availableSamples.push_back(release->m_sample); - } - break; - } - case PAT_3DSample: - { - if (release->m_3DSample) { - AIL_register_3D_EOS_callback(release->m_3DSample, NULL); - AIL_stop_3D_sample(release->m_3DSample); - m_available3DSamples.push_back(release->m_3DSample); - } - break; - } - case PAT_Stream: - { - if (release->m_stream) { - AIL_register_stream_callback(release->m_stream, NULL); - AIL_close_stream(release->m_stream); - } - break; - } - } - release->m_type = PAT_INVALID; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::releasePlayingAudio( PlayingAudio *release ) -{ - if (release->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_SoundEffect) { - if (release->m_type == PAT_Sample) { - if (release->m_sample) { - m_sound->notifyOf2DSampleCompletion(); - } - } else { - if (release->m_3DSample) { - m_sound->notifyOf3DSampleCompletion(); - } - } - } - releaseMilesHandles(release); // forces stop of this audio - closeFile( release->m_file ); - if (release->m_cleanupAudioEventRTS) { - releaseAudioEventRTS(release->m_audioEventRTS); - } - delete release; - release = NULL; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::stopAllAudioImmediately( void ) -{ - std::list::iterator it; - PlayingAudio *playing; - - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ) { - playing = *it; - if (!playing) { - continue; - } - - releasePlayingAudio(playing); - it = m_playingSounds.erase(it); - } - - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ) { - playing = *it; - if (!playing) { - continue; - } - - releasePlayingAudio(playing); - it = m_playing3DSounds.erase(it); - } - - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ) { - playing = (*it); - if (!playing) { - continue; - } - - releasePlayingAudio(playing); - it = m_playingStreams.erase(it); - } - - for (it = m_fadingAudio.begin(); it != m_fadingAudio.end(); ) { - playing = (*it); - if (!playing) { - continue; - } - - releasePlayingAudio(playing); - it = m_fadingAudio.erase(it); - } - - std::list::iterator hit; - for (hit = m_audioForcePlayed.begin(); hit != m_audioForcePlayed.end(); ++hit) { - if (*hit) { - AIL_quick_unload(*hit); - } - } - - m_audioForcePlayed.clear(); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::freeAllMilesHandles( void ) -{ - // 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(); - - // Walks through the available 2-D and 3-D handles and releases them - std::list::iterator it; - for ( it = m_availableSamples.begin(); it != m_availableSamples.end(); /* empty */ ) { - HSAMPLE sample = *it; - AIL_release_sample_handle(sample); - it = m_availableSamples.erase(it); - } - m_num2DSamples = 0; - - std::list::iterator it3D; - for ( it3D = m_available3DSamples.begin(); it3D != m_available3DSamples.end(); /* empty */ ) { - H3DSAMPLE sample3D = *it3D; - AIL_release_3D_sample_handle(sample3D); - it3D = m_available3DSamples.erase(it3D); - } - m_num3DSamples = 0; - m_numStreams = 0; -} - -//------------------------------------------------------------------------------------------------- -HSAMPLE MilesAudioManager::getFirst2DSample( AudioEventRTS *event ) -{ - if (m_availableSamples.begin() != m_availableSamples.end()) { - HSAMPLE retSample = *m_availableSamples.begin(); - m_availableSamples.erase(m_availableSamples.begin()); - return (retSample); - } - - // Find the first sample of lower priority than my augmented priority that is interruptable and take its handle - - return NULL; -} - -//------------------------------------------------------------------------------------------------- -H3DSAMPLE MilesAudioManager::getFirst3DSample( AudioEventRTS *event ) -{ - if (m_available3DSamples.begin() != m_available3DSamples.end()) { - H3DSAMPLE retSample = *m_available3DSamples.begin(); - m_available3DSamples.erase(m_available3DSamples.begin()); - return (retSample); - } - - // Find the first sample of lower priority than my augmented priority that is interruptable and take its handle - return NULL; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::adjustPlayingVolume( PlayingAudio *audio ) -{ - Real desiredVolume = audio->m_audioEventRTS->getVolume() * audio->m_audioEventRTS->getVolumeShift(); - Real pan; - if (audio->m_type == PAT_Sample) { - AIL_sample_volume_pan(audio->m_sample, NULL, &pan); - AIL_set_sample_volume_pan(audio->m_sample, m_soundVolume * desiredVolume, pan); - - } else if (audio->m_type == PAT_3DSample) { - AIL_set_3D_sample_volume(audio->m_3DSample, m_sound3DVolume * desiredVolume); - - } else if (audio->m_type == PAT_Stream) { - AIL_stream_volume_pan(audio->m_stream, NULL, &pan); - if (audio->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music ) { - AIL_set_stream_volume_pan(audio->m_stream, m_musicVolume * desiredVolume, pan); - - } else { - AIL_set_stream_volume_pan(audio->m_stream, m_speechVolume * desiredVolume, pan); - - } - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::stopAllSpeech( void ) -{ - std::list::iterator it; - PlayingAudio *playing; - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ) { - playing = (*it); - if (!playing) { - continue; - } - - if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Streaming) { - releasePlayingAudio(playing); - it = m_playingStreams.erase(it); - } else { - ++it; - } - } - -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::initFilters( HSAMPLE sample, const AudioEventRTS *event ) -{ - // set the sample volume - Real volume = event->getVolume() * event->getVolumeShift() * m_soundVolume; - AIL_set_sample_volume_pan(sample, volume, 0.5f); - - // pitch shift - Real pitchShift = event->getPitchShift(); - if (pitchShift == 0.0f) { - DEBUG_CRASH(("Invalid Pitch shift in sound: '%s'", event->getEventName().str()) ); - } else { - AIL_set_sample_playback_rate(sample, REAL_TO_INT(AIL_sample_playback_rate(sample) * pitchShift)); - } - - // set up delay filter, if applicable - if (event->getDelay() > 0.0f) { - Real value; - value = event->getDelay(); - AIL_set_sample_processor(sample, DP_FILTER, m_delayFilter); - AIL_set_filter_sample_preference(sample, "Mono Delay Time", &value); - - value = 0.0; - AIL_set_filter_sample_preference(sample, "Mono Delay", &value); - AIL_set_filter_sample_preference(sample, "Mono Delay Mix", &value); - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::initFilters3D( H3DSAMPLE sample, const AudioEventRTS *event, const Coord3D *pos ) -{ - // set the sample volume - Real volume = event->getVolume() * event->getVolumeShift() * m_sound3DVolume; - AIL_set_3D_sample_volume(sample, volume); - - // pitch shift - Real pitchShift = event->getPitchShift(); - if (pitchShift == 0.0f) { - DEBUG_CRASH(("Invalid Pitch shift in sound: '%s'", event->getEventName().str()) ); - } else { - AIL_set_3D_sample_playback_rate(sample, REAL_TO_INT(AIL_3D_sample_playback_rate(sample) * pitchShift)); - } - - // Low pass filter - if (event->getAudioEventInfo()->m_lowPassFreq > 0 && !isOnScreen(pos) ) { - AIL_set_3D_sample_occlusion(sample, 1.0f - event->getAudioEventInfo()->m_lowPassFreq); - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::nextMusicTrack( void ) -{ - AsciiString trackName; - std::list::iterator it; - PlayingAudio *playing; - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - trackName = playing->m_audioEventRTS->getEventName(); - } - } - - // Stop currently playing music - TheAudio->removeAudioEvent(AHSV_StopTheMusic); - - trackName = nextTrackName(trackName); - AudioEventRTS newTrack(trackName); - TheAudio->addAudioEvent(&newTrack); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::prevMusicTrack( void ) -{ - AsciiString trackName; - std::list::iterator it; - PlayingAudio *playing; - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - trackName = playing->m_audioEventRTS->getEventName(); - } - } - - // Stop currently playing music - TheAudio->removeAudioEvent(AHSV_StopTheMusic); - - trackName = prevTrackName(trackName); - AudioEventRTS newTrack(trackName); - TheAudio->addAudioEvent(&newTrack); -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::isMusicPlaying( void ) const -{ - std::list::const_iterator it; - PlayingAudio *playing; - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - return TRUE; - } - } - - return FALSE; -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::hasMusicTrackCompleted( const AsciiString& trackName, Int numberOfTimes ) const -{ - std::list::const_iterator it; - PlayingAudio *playing; - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - if (playing->m_audioEventRTS->getEventName() == trackName) { - if (INFINITE_LOOP_COUNT - AIL_stream_loop_count(playing->m_stream) >= numberOfTimes) { - return TRUE; - } - } - } - } - - return FALSE; -} - -//------------------------------------------------------------------------------------------------- -AsciiString MilesAudioManager::getMusicTrackName( void ) const -{ - // First check the requests. If there's one there, then report that as the currently playing track. - std::list::const_iterator ait; - for (ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ++ait) { - if ((*ait)->m_request != AR_Play) { - continue; - } - - if (!(*ait)->m_usePendingEvent) { - continue; - } - - if ((*ait)->m_pendingEvent->getAudioEventInfo()->m_soundType == AT_Music) { - return (*ait)->m_pendingEvent->getEventName(); - } - } - - std::list::const_iterator it; - PlayingAudio *playing; - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - return playing->m_audioEventRTS->getEventName(); - } - } - - return AsciiString::TheEmptyString; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::openDevice( void ) -{ - if (!TheGlobalData->m_audioOn) { - return; - } - - AIL_set_redist_directory("MSS\\"); - AIL_startup(); - Int retval = 0; - - // AIL_quick_startup should be replaced later with a call to actually pick which device to use, etc - const AudioSettings *audioSettings = getAudioSettings(); - m_selectedSpeakerType = TheAudio->translateSpeakerTypeToUnsignedInt(m_prefSpeaker); - - retval = AIL_quick_startup(audioSettings->m_useDigital, audioSettings->m_useMidi, audioSettings->m_outputRate, audioSettings->m_outputBits, audioSettings->m_outputChannels); - - // Quick handles tells us where to store the various devices. For now, we're only interested in the digital handle. - AIL_quick_handles(&m_digitalHandle, NULL, NULL); - - if (retval) { - buildProviderList(); - } else { - // if we couldn't initialize any devices, turn sound off (fail silently) - setOn( false, AudioAffect_All ); - } - - selectProvider(TheAudio->getProviderIndex(m_pref3DProvider)); - - // Now that we're all done, update the cached variables so that everything is in sync. - TheAudio->refreshCachedVariables(); - - if (!isValidProvider()) { - return; - } - - initDelayFilter(); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::closeDevice( void ) -{ - freeAllMilesHandles(); - unselectProvider(); - AIL_shutdown(); -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::isCurrentlyPlaying( AudioHandle handle ) -{ - std::list::iterator it; - PlayingAudio *playing; - - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getPlayingHandle() == handle) { - return true; - } - } - - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getPlayingHandle() == handle) { - return true; - } - } - - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getPlayingHandle() == handle) { - return true; - } - } - - // if something is requested, it is also considered playing - std::list::iterator ait; - AudioRequest *req = NULL; - for (ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ++ait) { - req = *ait; - if (req && req->m_usePendingEvent && req->m_pendingEvent->getPlayingHandle() == handle) { - return true; - } - } - - return false; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags ) -{ - PlayingAudio *playing = findPlayingAudioFrom(audioCompleted, flags); - if (!playing) { - DEBUG_CRASH(("Audio has completed playing, but we can't seem to find it. - jkmcd")); - return; - } - - if (getDisallowSpeech() && playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Streaming) { - setDisallowSpeech(FALSE); - } - - if (playing->m_audioEventRTS->getAudioEventInfo()->m_control & AC_LOOP) { - if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Attack) { - playing->m_audioEventRTS->setNextPlayPortion(PP_Sound); - } - if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Sound) { - // First, decrease the loop count. - playing->m_audioEventRTS->decreaseLoopCount(); - - // Now, try to start the next loop - if (startNextLoop(playing)) { - return; - } - } - } - - playing->m_audioEventRTS->advanceNextPlayPortion(); - if (playing->m_audioEventRTS->getNextPlayPortion() != PP_Done) { - if (playing->m_type == PAT_Sample) { - closeFile(playing->m_file); // close it so as not to leak it. - playing->m_file = playSample(playing->m_audioEventRTS, playing->m_sample); - - // If we don't have a file now, then we should drop to the stopped status so that - // We correctly close this handle. - if (playing->m_file) { - return; - } - } else if (playing->m_type == PAT_3DSample) { - closeFile(playing->m_file); // close it so as not to leak it. - playing->m_file = playSample3D(playing->m_audioEventRTS, playing->m_3DSample); - - // If we don't have a file now, then we should drop to the stopped status so that - // We correctly close this handle. - if (playing->m_file) { - return; - } - } - } - - if (playing->m_type == PAT_Stream) { - if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - playStream(playing->m_audioEventRTS, playing->m_stream); - - return; - } - } - - playing->m_status = PS_Stopped; // it will be cleaned up on the next frame update -} - -//------------------------------------------------------------------------------------------------- -PlayingAudio *MilesAudioManager::findPlayingAudioFrom( UnsignedInt audioCompleted, UnsignedInt flags ) -{ - std::list::iterator it; - PlayingAudio *playing; - - if (flags == PAT_Sample) { - HSAMPLE sample = (HSAMPLE) audioCompleted; - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { - playing = *it; - if (playing && playing->m_sample == sample) { - return playing; - } - } - } - - if (flags == PAT_3DSample) { - H3DSAMPLE sample3D = (H3DSAMPLE) audioCompleted; - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { - playing = *it; - if (playing && playing->m_3DSample == sample3D) { - return playing; - } - } - } - - if (flags == PAT_Stream) { - HSTREAM stream = (HSTREAM) audioCompleted; - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing && playing->m_stream == stream) { - return playing; - } - } - } - - return NULL; -} - - -//------------------------------------------------------------------------------------------------- -UnsignedInt MilesAudioManager::getProviderCount( void ) const -{ - return m_providerCount; -} - -//------------------------------------------------------------------------------------------------- -AsciiString MilesAudioManager::getProviderName( UnsignedInt providerNum ) const -{ - if (isOn(AudioAffect_Sound3D) && providerNum < m_providerCount) { - return m_provider3D[providerNum].name; - } - - return AsciiString::TheEmptyString; -} - -//------------------------------------------------------------------------------------------------- -UnsignedInt MilesAudioManager::getProviderIndex( AsciiString providerName ) const -{ - for (UnsignedInt i = 0; i < m_providerCount; ++i) { - if (providerName == m_provider3D[i].name) { - return i; - } - } - - return PROVIDER_ERROR; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::selectProvider( UnsignedInt providerNdx ) -{ - if (!isOn(AudioAffect_Sound3D)) - { - return; - } - - if (providerNdx == m_selectedProvider) - { - return; - } - - if (isValidProvider()) - { - freeAllMilesHandles(); - unselectProvider(); - } - - LPDIRECTSOUND lpDirectSoundInfo; - AIL_get_DirectSound_info( NULL, (void**)&lpDirectSoundInfo, NULL ); - Bool useDolby = FALSE; - if( lpDirectSoundInfo ) - { - DWORD speakerConfig; - lpDirectSoundInfo->GetSpeakerConfig( &speakerConfig ); - switch( DSSPEAKER_CONFIG( speakerConfig ) ) - { - case DSSPEAKER_DIRECTOUT: - m_selectedSpeakerType = AIL_3D_2_SPEAKER; - break; - case DSSPEAKER_MONO: - m_selectedSpeakerType = AIL_3D_2_SPEAKER; - break; - case DSSPEAKER_STEREO: - m_selectedSpeakerType = AIL_3D_2_SPEAKER; - break; - case DSSPEAKER_HEADPHONE: - m_selectedSpeakerType = AIL_3D_HEADPHONE; - useDolby = TRUE; - break; - case DSSPEAKER_QUAD: - m_selectedSpeakerType = AIL_3D_4_SPEAKER; - useDolby = TRUE; - break; - case DSSPEAKER_SURROUND: - m_selectedSpeakerType = AIL_3D_SURROUND; - useDolby = TRUE; - break; - case DSSPEAKER_5POINT1: - m_selectedSpeakerType = AIL_3D_51_SPEAKER; - useDolby = TRUE; - break; - case DSSPEAKER_7POINT1: - m_selectedSpeakerType = AIL_3D_71_SPEAKER; - useDolby = TRUE; - break; - } - } - - Bool success = FALSE; - if( useDolby ) - { - providerNdx = getProviderIndex( "Dolby Surround" ); - } - else - { - providerNdx = getProviderIndex( "Miles Fast 2D Positional Audio" ); - } - success = AIL_open_3D_provider( m_provider3D[providerNdx].id ) == 0; - - //if (providerNdx < m_providerCount) - //{ - // failed = AIL_open_3D_provider(m_provider3D[providerNdx].id); - //} - - - - if( !success ) - { - m_selectedProvider = PROVIDER_ERROR; - // try to select a failsafe - providerNdx = getProviderIndex( "Miles Fast 2D Positional Audio" ); - success = AIL_open_3D_provider( m_provider3D[providerNdx].id ) == 0; - } - - if ( success ) - { - m_selectedProvider = providerNdx; - - initSamplePools(); - - createListener(); - setSpeakerType(m_selectedSpeakerType); - if (TheVideoPlayer) - { - TheVideoPlayer->notifyVideoPlayerOfNewProvider(TRUE); - } - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::unselectProvider( void ) -{ - if (!(isOn(AudioAffect_Sound3D) && isValidProvider())) { - return; - } - - if (TheVideoPlayer) { - TheVideoPlayer->notifyVideoPlayerOfNewProvider(FALSE); - } - AIL_close_3D_listener(m_listener); - m_listener = NULL; - - AIL_close_3D_provider(m_provider3D[m_selectedProvider].id); - m_lastProvider = m_selectedProvider; - - m_selectedProvider = PROVIDER_ERROR; -} - -//------------------------------------------------------------------------------------------------- -UnsignedInt MilesAudioManager::getSelectedProvider( void ) const -{ - return m_selectedProvider; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::setSpeakerType( UnsignedInt speakerType ) -{ - if (!isValidProvider()) { - return; - } - - AIL_set_3D_speaker_type( m_provider3D[m_selectedProvider].id, speakerType ); - m_selectedSpeakerType = speakerType; -} - -//------------------------------------------------------------------------------------------------- -UnsignedInt MilesAudioManager::getSpeakerType( void ) -{ - if (!isValidProvider()) { - return 0; - } - - return m_selectedSpeakerType; -} - -//------------------------------------------------------------------------------------------------- -UnsignedInt MilesAudioManager::getNum2DSamples( void ) const -{ - return m_num2DSamples; -} - -//------------------------------------------------------------------------------------------------- -UnsignedInt MilesAudioManager::getNum3DSamples( void ) const -{ - return m_num3DSamples; -} - -//------------------------------------------------------------------------------------------------- -UnsignedInt MilesAudioManager::getNumStreams( void ) const -{ - return m_numStreams; -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::doesViolateLimit( AudioEventRTS *event ) const -{ - Int limit = event->getAudioEventInfo()->m_limit; - if (limit == 0) { - return false; - } - - Int totalCount = 0; - Int totalRequestCount = 0; - - std::list::const_iterator it; - if (!event->isPositionalAudio()) { - // 2-D - for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) { - if ((*it)->m_audioEventRTS->getEventName() == event->getEventName()) { - if (totalCount == 0) { - // This is the oldest audio of this type playing. - event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle()); - } - ++totalCount; - } - } - } else { - // 3-D - for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) { - if ((*it)->m_audioEventRTS->getEventName() == event->getEventName()) { - if (totalCount == 0) { - // This is the oldest audio of this type playing. - event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle()); - } - ++totalCount; - } - } - } - - // Also check the request list in case we've requested to play this sound. - std::list::const_iterator arIt; - for (arIt = m_audioRequests.begin(); arIt != m_audioRequests.end(); ++arIt) { - AudioRequest *req = (*arIt); - if (req == NULL) { - continue; - } - if( req->m_usePendingEvent ) - { - if( req->m_pendingEvent->getEventName() == event->getEventName() ) - { - totalRequestCount++; - totalCount++; - } - } - } - - //If our event is an interrupting type, then normally we would always add it. The exception is when we have requested - //multiple sounds in the same frame and those requests violate the limit. Because we don't have any "old" sounds to - //remove in the case of an interrupt, we need to catch it early and prevent the sound from being added if we already - //reached the limit - if( event->getAudioEventInfo()->m_control & AC_INTERRUPT ) - { - if( totalRequestCount < limit ) - { - Int totalPlayingCount = totalCount - totalRequestCount; - if( totalRequestCount + totalPlayingCount < limit ) - { - //We aren't exceeding the actual limit, then clear the kill handle. - event->setHandleToKill(0); - return false; - } - - //We are exceeding the limit - the kill handle will kill the - //oldest playing sound to enforce the actual limit. - return false; - } - } - - if( totalCount < limit ) - { - event->setHandleToKill(0); - return false; - } - - return true; -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::isPlayingAlready( AudioEventRTS *event ) const -{ - std::list::const_iterator it; - if (!event->isPositionalAudio()) { - // 2-D - for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) { - if ((*it)->m_audioEventRTS->getEventName() == event->getEventName()) { - return true; - } - } - } else { - // 3-D - for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) { - if ((*it)->m_audioEventRTS->getEventName() == event->getEventName()) { - return true; - } - } - } - - return false; -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::isObjectPlayingVoice( UnsignedInt objID ) const -{ - if (objID == 0) { - return false; - } - - std::list::const_iterator it; - // 2-D - for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) { - if ((*it)->m_audioEventRTS->getObjectID() == objID && (*it)->m_audioEventRTS->getAudioEventInfo()->m_type & ST_VOICE) { - return true; - } - } - - // 3-D - for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) { - if ((*it)->m_audioEventRTS->getObjectID() == objID && (*it)->m_audioEventRTS->getAudioEventInfo()->m_type & ST_VOICE) { - return true; - } - } - - return false; -} - -//------------------------------------------------------------------------------------------------- -AudioEventRTS* MilesAudioManager::findLowestPrioritySound( AudioEventRTS *event ) -{ - AudioPriority priority = event->getAudioEventInfo()->m_priority; - if( priority == AP_LOWEST ) - { - //If the event we pass in is the lowest priority, don't bother checking because - //there is nothing lower priority than lowest. - return NULL; - } - AudioEventRTS *lowestPriorityEvent = NULL; - AudioPriority lowestPriority; - - std::list::const_iterator it; - if( event->isPositionalAudio() ) - { - //3D - for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) - { - AudioEventRTS *itEvent = (*it)->m_audioEventRTS; - AudioPriority itPriority = itEvent->getAudioEventInfo()->m_priority; - if( itPriority < priority ) - { - if( !lowestPriorityEvent || lowestPriority > itPriority ) - { - lowestPriorityEvent = itEvent; - lowestPriority = itPriority; - if( lowestPriority == AP_LOWEST ) - { - return lowestPriorityEvent; - } - } - } - } - } - else - { - //2D - for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) - { - AudioEventRTS *itEvent = (*it)->m_audioEventRTS; - AudioPriority itPriority = itEvent->getAudioEventInfo()->m_priority; - if( itPriority < priority ) - { - if( !lowestPriorityEvent || lowestPriority > itPriority ) - { - lowestPriorityEvent = itEvent; - lowestPriority = itPriority; - if( lowestPriority == AP_LOWEST ) - { - return lowestPriorityEvent; - } - } - } - } - } - return lowestPriorityEvent; -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::isPlayingLowerPriority( AudioEventRTS *event ) const -{ - //We don't actually want to do anything to this CONST function. Remember, we're - //just checking to see if there is a lower priority sound. - AudioPriority priority = event->getAudioEventInfo()->m_priority; - if( priority == AP_LOWEST ) - { - //If the event we pass in is the lowest priority, don't bother checking because - //there is nothing lower priority than lowest. - return false; - } - std::list::const_iterator it; - if (!event->isPositionalAudio()) { - // 2-D - for ( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) { - if ((*it)->m_audioEventRTS->getAudioEventInfo()->m_priority < priority) { - //event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle()); - return true; - } - } - } else { - // 3-D - for ( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) { - if ((*it)->m_audioEventRTS->getAudioEventInfo()->m_priority < priority) { - //event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle()); - return true; - } - } - } - - return false; -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::killLowestPrioritySoundImmediately( AudioEventRTS *event ) -{ - //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 ); - if( lowestPriorityEvent ) - { - std::list::iterator it; - if( event->isPositionalAudio() ) - { - for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) - { - PlayingAudio *playing = (*it); - if( !playing ) - { - continue; - } - - if( playing->m_audioEventRTS && playing->m_audioEventRTS == lowestPriorityEvent ) - { - //Release this 3D sound channel immediately because we are going to play another sound in it's place. - releasePlayingAudio( playing ); - m_playing3DSounds.erase( it ); - return TRUE; - } - } - } - else - { - for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) - { - PlayingAudio *playing = (*it); - if( !playing ) - { - continue; - } - - if( playing->m_audioEventRTS && playing->m_audioEventRTS == lowestPriorityEvent ) - { - //Release this sound channel immediately because we are going to play another sound in it's place. - releasePlayingAudio( playing ); - m_playingSounds.erase( it ); - return TRUE; - } - } - } - } - return FALSE; -} - - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::adjustVolumeOfPlayingAudio(AsciiString eventName, Real newVolume) -{ - Real pan; - std::list::iterator it; - - PlayingAudio *playing = NULL; - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getEventName() == eventName) { - // Adjust it - playing->m_audioEventRTS->setVolume(newVolume); - Real desiredVolume = playing->m_audioEventRTS->getVolume() * playing->m_audioEventRTS->getVolumeShift(); - AIL_sample_volume_pan(playing->m_sample, NULL, &pan); - AIL_set_sample_volume_pan(playing->m_sample, desiredVolume, pan); - } - } - - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getEventName() == eventName) { - // Adjust it - playing->m_audioEventRTS->setVolume(newVolume); - Real desiredVolume = playing->m_audioEventRTS->getVolume() * playing->m_audioEventRTS->getVolumeShift(); - AIL_set_3D_sample_volume(playing->m_3DSample, desiredVolume); - } - } - - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { - playing = *it; - if (playing && playing->m_audioEventRTS->getEventName() == eventName) { - // Adjust it - playing->m_audioEventRTS->setVolume(newVolume); - Real desiredVolume = playing->m_audioEventRTS->getVolume() * playing->m_audioEventRTS->getVolumeShift(); - AIL_stream_volume_pan(playing->m_stream, NULL, &pan); - AIL_set_stream_volume_pan(playing->m_stream, desiredVolume, pan); - } - } -} - - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::removePlayingAudio( AsciiString eventName ) -{ - std::list::iterator it; - - PlayingAudio *playing = NULL; - for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ) - { - playing = *it; - if( playing && playing->m_audioEventRTS->getEventName() == eventName ) - { - releasePlayingAudio( playing ); - it = m_playingSounds.erase(it); - } - else - { - it++; - } - } - - for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ) - { - playing = *it; - if( playing && playing->m_audioEventRTS->getEventName() == eventName ) - { - releasePlayingAudio( playing ); - it = m_playing3DSounds.erase(it); - } - else - { - it++; - } - } - - for( it = m_playingStreams.begin(); it != m_playingStreams.end(); ) - { - playing = *it; - if( playing && playing->m_audioEventRTS->getEventName() == eventName ) - { - releasePlayingAudio( playing ); - it = m_playingStreams.erase(it); - } - else - { - it++; - } - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::removeAllDisabledAudio() -{ - std::list::iterator it; - - PlayingAudio *playing = NULL; - for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ) - { - playing = *it; - if( playing && playing->m_audioEventRTS->getVolume() == 0.0f ) - { - releasePlayingAudio( playing ); - it = m_playingSounds.erase(it); - } - else - { - it++; - } - } - - for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ) - { - playing = *it; - if( playing && playing->m_audioEventRTS->getVolume() == 0.0f ) - { - releasePlayingAudio( playing ); - it = m_playing3DSounds.erase(it); - } - else - { - it++; - } - } - - for( it = m_playingStreams.begin(); it != m_playingStreams.end(); ) - { - playing = *it; - if( playing && playing->m_audioEventRTS->getVolume() == 0.0f ) - { - releasePlayingAudio( playing ); - it = m_playingStreams.erase(it); - } - else - { - it++; - } - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::processRequestList( void ) -{ - std::list::iterator it; - for (it = m_audioRequests.begin(); it != m_audioRequests.end(); /* empty */) { - AudioRequest *req = (*it); - if (req == NULL) { - continue; - } - - if (!shouldProcessRequestThisFrame(req)) { - adjustRequest(req); - ++it; - continue; - } - - if (!req->m_requiresCheckForSample || checkForSample(req)) { - processRequest(req); - } - deleteInstance(req); - it = m_audioRequests.erase(it); - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::processPlayingList( void ) -{ - // There are two types of processing we have to do here. - // 1. Move the item to the stopped list if it has become stopped. - // 2. Update the position of the audio if it is positional - std::list::iterator it; - PlayingAudio *playing; - - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); /* empty */) { - playing = (*it); - if (!playing) - { - it = m_playingSounds.erase(it); - continue; - } - - if (playing->m_status == PS_Stopped) - { - //m_stoppedAudio.push_back(playing); - releasePlayingAudio( playing ); - it = m_playingSounds.erase(it); - } - else - { - if (m_volumeHasChanged) - { - adjustPlayingVolume(playing); - } - ++it; - } - } - - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ) - { - playing = (*it); - if (!playing) - { - it = m_playing3DSounds.erase(it); - continue; - } - - if (playing->m_status == PS_Stopped) - { - //m_stoppedAudio.push_back(playing); - releasePlayingAudio( playing ); - it = m_playing3DSounds.erase(it); - } - else - { - if (m_volumeHasChanged) - { - adjustPlayingVolume(playing); - } - - const Coord3D *pos = getCurrentPositionFromEvent(playing->m_audioEventRTS); - if (pos) - { - if( playing->m_audioEventRTS->isDead() ) - { - stopAudioEvent( playing->m_audioEventRTS->getPlayingHandle() ); - it++; - continue; - } - else - { - Real volForConsideration = getEffectiveVolume(playing->m_audioEventRTS); - volForConsideration /= (m_sound3DVolume > 0.0f ? m_soundVolume : 1.0f); - Bool playAnyways = BitIsSet( playing->m_audioEventRTS->getAudioEventInfo()->m_type, ST_GLOBAL) || playing->m_audioEventRTS->getAudioEventInfo()->m_priority == AP_CRITICAL; - if( volForConsideration < m_audioSettings->m_minVolume && !playAnyways ) - { - // don't want to get an additional callback for this sample - AIL_register_3D_EOS_callback(playing->m_3DSample, NULL); - //m_stoppedAudio.push_back(playing); - releasePlayingAudio( playing ); - it = m_playing3DSounds.erase(it); - continue; - } - else - { - Real x = pos->x; - Real y = pos->y; - Real z = pos->z; - AIL_set_3D_position( playing->m_3DSample, x, y, z ); - } - } - } - else - { - AIL_register_3D_EOS_callback(playing->m_3DSample, NULL); - //m_stoppedAudio.push_back(playing); - releasePlayingAudio( playing ); - it = m_playing3DSounds.erase(it); - continue; - } - - ++it; - } - } - - for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ) { - playing = (*it); - if (!playing) - { - it = m_playingStreams.erase(it); - continue; - } - - if (playing->m_status == PS_Stopped) - { - //m_stoppedAudio.push_back(playing); - releasePlayingAudio( playing ); - it = m_playingStreams.erase(it); - } - else - { - if (m_volumeHasChanged) - { - adjustPlayingVolume(playing); - } - - ++it; - } - } - - if (m_volumeHasChanged) { - m_volumeHasChanged = false; - } -} - -//Patch for a rare bug (only on about 5% of in-studio machines suffer, and not all the time) . -//The actual mechanics of this problem are still elusive as of the date of this comment. 8/21/03 -//but the cause is clear. Some cinematics do a radical change in the microphone position, which -//calls for a radical 3DSoundVolume adjustment. If this happens while a stereo stream is *ENDING*, -//low-level code gets caught in a tight loop. (Hangs) on some machines. -//To prevent this condition, we just suppress the updating of 3DSoundVolume while one of these -//is on the list. Since the music tracks play continuously, they never *END* during these cinematics. -//so we filter them out as, *NOT SENSITIVE*... we do want to update 3DSoundVolume during music, -//which is almost all of the time. - -Bool MilesAudioManager::has3DSensitiveStreamsPlaying( void ) const -{ - if ( m_playingStreams.empty() ) - return FALSE; - - for ( std::list< PlayingAudio* >::const_iterator it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it ) - { - const PlayingAudio *playing = (*it); - - if ( ! playing ) - continue; - - if ( playing->m_audioEventRTS->getAudioEventInfo()->m_soundType != AT_Music ) - { - return TRUE; - } - - if ( playing->m_audioEventRTS->getEventName().startsWith("Game_") == FALSE ) - { - return TRUE; - } - } - - return FALSE; - -} - - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::processFadingList( void ) -{ - std::list::iterator it; - PlayingAudio *playing; - - for (it = m_fadingAudio.begin(); it != m_fadingAudio.end(); /* emtpy */) { - playing = *it; - if (!playing) { - continue; - } - - if (playing->m_framesFaded >= getAudioSettings()->m_fadeAudioFrames) { - playing->m_status = PS_Stopped; - playing->m_requestStop = true; - //m_stoppedAudio.push_back(playing); - releasePlayingAudio( playing ); - it = m_fadingAudio.erase(it); - continue; - } - - ++playing->m_framesFaded; - Real volume = getEffectiveVolume(playing->m_audioEventRTS); - volume *= (1.0f - 1.0f * playing->m_framesFaded / getAudioSettings()->m_fadeAudioFrames); - - switch(playing->m_type) - { - case PAT_Sample: - { - AIL_set_sample_volume_pan(playing->m_sample, volume, 0.5f); - break; - } - - case PAT_3DSample: - { - AIL_set_3D_sample_volume(playing->m_3DSample, volume); - break; - } - - case PAT_Stream: - { - AIL_set_stream_volume_pan(playing->m_stream, volume, 0.5f); - break; - } - - } - - ++it; - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::processStoppedList( void ) -{ - std::list::iterator it; - PlayingAudio *playing; - - for (it = m_stoppedAudio.begin(); it != m_stoppedAudio.end(); /* emtpy */) { - playing = *it; - if (playing) { - releasePlayingAudio(playing); - } - it = m_stoppedAudio.erase(it); - } -} - - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::shouldProcessRequestThisFrame( AudioRequest *req ) const -{ - if (!req->m_usePendingEvent) { - return true; - } - - if (req->m_pendingEvent->getDelay() < MSEC_PER_LOGICFRAME_REAL) { - return true; - } - - return false; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::adjustRequest( AudioRequest *req ) -{ - if (!req->m_usePendingEvent) { - return; - } - - req->m_pendingEvent->decrementDelay(MSEC_PER_LOGICFRAME_REAL); - req->m_requiresCheckForSample = true; -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::checkForSample( AudioRequest *req ) -{ - if (!req->m_usePendingEvent) { - return true; - } - - if ( req->m_pendingEvent->getAudioEventInfo() == NULL ) - { - // Fill in event info - getInfoForAudioEvent( req->m_pendingEvent ); - } - - if (req->m_pendingEvent->getAudioEventInfo()->m_type != AT_SoundEffect) - { - return true; - } - - return m_sound->canPlayNow(req->m_pendingEvent); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::setHardwareAccelerated(Bool accel) -{ - // Extends - Bool retEarly = (accel == m_hardwareAccel); - AudioManager::setHardwareAccelerated(accel); - - if (retEarly) { - return; - } - - if (m_hardwareAccel) { - for (Int i = 0; i < MAX_HW_PROVIDERS; ++i) { - UnsignedInt providerNdx = TheAudio->getProviderIndex(TheAudio->getAudioSettings()->m_preferred3DProvider[i]); - TheAudio->selectProvider(providerNdx); - if (getSelectedProvider() == providerNdx) { - return; - } - } - } - - // set it false - AudioManager::setHardwareAccelerated(FALSE); - UnsignedInt providerNdx = TheAudio->getProviderIndex(TheAudio->getAudioSettings()->m_preferred3DProvider[MAX_HW_PROVIDERS]); - TheAudio->selectProvider(providerNdx); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::setSpeakerSurround(Bool surround) -{ - // Extends - Bool retEarly = (surround == m_surroundSpeakers); - AudioManager::setSpeakerSurround(surround); - - if (retEarly) { - return; - } - - UnsignedInt speakerType; - if (m_surroundSpeakers) { - speakerType = TheAudio->getAudioSettings()->m_defaultSpeakerType3D; - } else { - speakerType = TheAudio->getAudioSettings()->m_defaultSpeakerType2D; - } - - TheAudio->setSpeakerType(speakerType); -} - -//------------------------------------------------------------------------------------------------- -Real MilesAudioManager::getFileLengthMS( AsciiString strToLoad ) const -{ - if (strToLoad.isEmpty()) { - return 0.0f; - } - - // Load it as a stream to get the file info without actually opening the file. - HSTREAM stream = AIL_open_stream(m_digitalHandle, strToLoad.str(), 0); - if (!stream) { - return 0.0f; - } - - long retVal; - AIL_stream_ms_position(stream, &retVal, NULL); - // Now close the stream - AIL_close_stream(stream); - - return INT_TO_REAL(retVal); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::closeAnySamplesUsingFile( const void *fileToClose ) -{ - std::list::iterator it; - PlayingAudio *playing; - - for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ) { - playing = *it; - if (!playing) { - continue; - } - - if (playing->m_file == fileToClose) { - releasePlayingAudio(playing); - it = m_playingSounds.erase(it); - } else { - ++it; - } - } - - for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ) { - playing = *it; - if (!playing) { - continue; - } - - if (playing->m_file == fileToClose) { - releasePlayingAudio(playing); - it = m_playing3DSounds.erase(it); - } else { - ++it; - } - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::setDeviceListenerPosition( void ) -{ - if (m_listener) { - AIL_set_3D_orientation(m_listener, m_listenerOrientation.x, m_listenerOrientation.y, m_listenerOrientation.z, 0, 0, -1); - - Real x = m_listenerPosition.x; - Real y = m_listenerPosition.y; - Real z = m_listenerPosition.z; - AIL_set_3D_position( m_listener, x, y, z ); - } -} - -//------------------------------------------------------------------------------------------------- -const Coord3D *MilesAudioManager::getCurrentPositionFromEvent( AudioEventRTS *event ) -{ - if (!event->isPositionalAudio()) { - return NULL; - } - - return event->getCurrentPosition(); -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::isOnScreen( const Coord3D *pos ) const -{ - static ICoord2D dummy; - // WorldToScreen will return True if the point is onscreen and false if it is offscreen. - return TheTacticalView->worldToScreen(pos, &dummy); -} - -//------------------------------------------------------------------------------------------------- -Real MilesAudioManager::getEffectiveVolume(AudioEventRTS *event) const -{ - Real volume = 1.0f; - volume *= (event->getVolume() * event->getVolumeShift()); - if (event->getAudioEventInfo()->m_soundType == AT_Music) - { - volume *= m_musicVolume; - } - else if (event->getAudioEventInfo()->m_soundType == AT_Streaming) - { - volume *= m_speechVolume; - } - else - { - if (event->isPositionalAudio()) - { - volume *= m_sound3DVolume; - Coord3D distance = m_listenerPosition; - const Coord3D *pos = event->getCurrentPosition(); - if (pos) - { - distance.sub(pos); - Real objMinDistance; - Real objMaxDistance; - - if (event->getAudioEventInfo()->m_type & ST_GLOBAL) - { - objMinDistance = TheAudio->getAudioSettings()->m_globalMinRange; - objMaxDistance = TheAudio->getAudioSettings()->m_globalMaxRange; - } - else - { - objMinDistance = event->getAudioEventInfo()->m_minDistance; - objMaxDistance = event->getAudioEventInfo()->m_maxDistance; - } - - Real objDistance = distance.length(); - if( objDistance > objMinDistance ) - { - volume *= 1 / (objDistance / objMinDistance); - } - if( objDistance >= objMaxDistance ) - { - volume = 0.0f; - } - //else if( objDistance > objMinDistance ) - //{ - // volume *= 1.0f - (objDistance - objMinDistance) / (objMaxDistance - objMinDistance); - //} - } - } - else - { - volume *= m_soundVolume; - } - } - - return volume; -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::startNextLoop( PlayingAudio *looping ) -{ - closeFile(looping->m_file); - looping->m_file = NULL; - - if (looping->m_requestStop) { - return false; - } - - if (looping->m_audioEventRTS->hasMoreLoops()) { - // generate a new filename, and test to see whether we can play with it now - looping->m_audioEventRTS->generateFilename(); - - if (looping->m_audioEventRTS->getDelay() > MSEC_PER_LOGICFRAME_REAL) { - // fake it out so that this sound appears done, but also so that it will not - // delete the sound on completion (which would suck) - looping->m_cleanupAudioEventRTS = false; - looping->m_requestStop = true; - looping->m_status = PS_Stopped; - - - AudioRequest *req = allocateAudioRequest(true); - req->m_pendingEvent = looping->m_audioEventRTS; - req->m_requiresCheckForSample = true; - appendAudioRequest(req); - return true; - } - - if (looping->m_type == PAT_3DSample) { - looping->m_file = playSample3D(looping->m_audioEventRTS, looping->m_3DSample); - } else { - looping->m_file = playSample(looping->m_audioEventRTS, looping->m_sample); - } - - return looping->m_file != NULL; - } - return false; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::playStream( AudioEventRTS *event, HSTREAM stream ) -{ - // Force it to the beginning - if (event->getAudioEventInfo()->m_soundType == AT_Music) { - AIL_set_stream_loop_count(stream, INFINITE_LOOP_COUNT); - } - - AIL_register_stream_callback(stream, setStreamCompleted); - AIL_start_stream(stream); - if (event->getAudioEventInfo()->m_soundType == AT_Music) { - // Need to stop/fade out the old music here. - } -} - -//------------------------------------------------------------------------------------------------- -void *MilesAudioManager::playSample( AudioEventRTS *event, HSAMPLE sample ) -{ - AIL_init_sample(sample); - - // Prep any sort of filtering, etc, here - AIL_register_EOS_callback(sample, setSampleCompleted); - initFilters(sample, event); - - // Load the file in - void *fileBuffer = NULL; - fileBuffer = loadFileForRead(event); - if (fileBuffer) { - AIL_set_sample_file(sample, fileBuffer, 0); - - // Start playback - AIL_start_sample(sample); - } - - return fileBuffer; -} - -//------------------------------------------------------------------------------------------------- -void *MilesAudioManager::playSample3D( AudioEventRTS *event, H3DSAMPLE sample3D ) -{ - const Coord3D *pos = getCurrentPositionFromEvent(event); - if (pos) { - // Load the file in - void *fileBuffer = loadFileForRead(event); - if (fileBuffer) { - AIL_set_3D_sample_file(sample3D, fileBuffer); - - // Prep any sort of filtering, etc, here - AIL_register_3D_EOS_callback(sample3D, set3DSampleCompleted); - - // Set the position values of the sample here - if (event->getAudioEventInfo()->m_type & ST_GLOBAL) { - AIL_set_3D_sample_distances(sample3D, TheAudio->getAudioSettings()->m_globalMinRange, TheAudio->getAudioSettings()->m_globalMaxRange ); - } else { - AIL_set_3D_sample_distances(sample3D, event->getAudioEventInfo()->m_minDistance, event->getAudioEventInfo()->m_maxDistance ); - } - - // Set the position of the sample here - Real x = pos->x; - Real y = pos->y; - Real z = pos->z; - AIL_set_3D_position( sample3D, x, y, z ); - initFilters3D(sample3D, event, pos); - - // Start playback - AIL_start_3D_sample(sample3D); - } - return fileBuffer; - } - - return NULL; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::buildProviderList( void ) -{ - HPROENUM next = HPROENUM_FIRST; - - char *name; - UnsignedInt index = 0; - while (index < MAXPROVIDERS && AIL_enumerate_3D_providers(&next, &m_provider3D[index].id, &name)) { - m_provider3D[index].name.set(name); // set it to the AsciiString - ++index; - } - - m_providerCount = index; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::createListener( void ) -{ - if (!(isOn(AudioAffect_Sound3D) && isValidProvider())) { - return; - } - - m_listener = AIL_open_3D_listener(m_provider3D[m_selectedProvider].id); - // initial listener position will be (0, 0, 0) -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::initDelayFilter( void ) -{ - if (m_delayFilter != NULL) { - return; - } - - char* filterName; - HPROENUM enumFLTs = HPROENUM_FIRST; - HPROVIDER currentProvider; - - while (AIL_enumerate_filters(&enumFLTs, ¤tProvider, &filterName )) { - if (strcmp(filterName,"Mono Delay Filter") == 0) { - m_delayFilter = currentProvider; - break; - } - } -} - -//------------------------------------------------------------------------------------------------- -Bool MilesAudioManager::isValidProvider( void ) -{ - return (m_selectedProvider < m_providerCount); -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::initSamplePools( void ) -{ - if (!(isOn(AudioAffect_Sound3D) && isValidProvider())) { - return; - } - - int i = 0; - for (i = 0; i < getAudioSettings()->m_sampleCount2D; ++i) { - HSAMPLE sample = AIL_allocate_sample_handle(m_digitalHandle); - DEBUG_ASSERTCRASH(sample, ("Couldn't get %d 2D samples", i + 1)); - if (sample) { - AIL_init_sample(sample); - AIL_set_sample_user_data(sample, 0, i + 1); - m_availableSamples.push_back(sample); - ++m_num2DSamples; - } - } - - for (i = 0; i < getAudioSettings()->m_sampleCount3D; ++i) { - H3DSAMPLE sample = AIL_allocate_3D_sample_handle(m_provider3D[m_selectedProvider].id); - DEBUG_ASSERTCRASH(sample, ("Couldn't get %d 3D samples", i + 1)); - if (sample) { - AIL_set_3D_user_data(sample, 0, i + 1); - m_available3DSamples.push_back(sample); - ++m_num3DSamples; - } - } - - // Streams are basically free, so we can just allocate the appropriate number - m_numStreams = getAudioSettings()->m_streamCount; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::processRequest( AudioRequest *req ) -{ - switch (req->m_request) - { - case AR_Play: - { - playAudioEvent(req->m_pendingEvent); - break; - } - case AR_Pause: - { - pauseAudioEvent(req->m_handleToInteractOn); - break; - } - case AR_Stop: - { - stopAudioEvent(req->m_handleToInteractOn); - break; - } - } -} - -//------------------------------------------------------------------------------------------------- -void *MilesAudioManager::getHandleForBink( void ) -{ - if (m_binkHandle == NULL) { - PlayingAudio *aud = allocatePlayingAudio(); - aud->m_audioEventRTS = NEW AudioEventRTS("BinkHandle"); // poolify - getInfoForAudioEvent(aud->m_audioEventRTS); - aud->m_sample = getFirst2DSample(aud->m_audioEventRTS); - aud->m_type = PAT_Sample; - - if (!aud->m_sample) { - releasePlayingAudio(aud); - return NULL; - } - - m_binkHandle = aud; - } - - AILLPDIRECTSOUND lpDS; - AIL_get_DirectSound_info(m_binkHandle->m_sample, &lpDS, NULL); - return lpDS; -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::releaseHandleForBink( void ) -{ - if (m_binkHandle) { - releasePlayingAudio(m_binkHandle); - m_binkHandle = NULL; - } -} - -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::friend_forcePlayAudioEventRTS(const AudioEventRTS* eventToPlay) -{ - if (!eventToPlay->getAudioEventInfo()) { - getInfoForAudioEvent(eventToPlay); - if (!eventToPlay->getAudioEventInfo()) { - DEBUG_CRASH(("No info for forced audio event '%s'", eventToPlay->getEventName().str())); - return; - } - } - - switch (eventToPlay->getAudioEventInfo()->m_soundType) - { - case AT_Music: - if (!isOn(AudioAffect_Music)) - return; - break; - case AT_SoundEffect: - if (!isOn(AudioAffect_Sound) || !isOn(AudioAffect_Sound3D)) - return; - break; - case AT_Streaming: - if (!isOn(AudioAffect_Speech)) - return; - break; - } - - AudioEventRTS event = *eventToPlay; - - event.generateFilename(); - event.generatePlayInfo(); - - std::list >::iterator it; - for (it = m_adjustedVolumes.begin(); it != m_adjustedVolumes.end(); ++it) { - if (it->first == event.getEventName()) { - event.setVolume(it->second); - break; - } - } - - AsciiString fileToPlay = event.getFilename(); - HAUDIO haud = AIL_quick_load_and_play(fileToPlay.str(), 1, 0); - - // Even though the event type is not Speech, this is used only for mission briefings, so use the - // speech slider to adjust the volume. - // Get the volume from the event, and pass 0.5 to play the audio in the middle. (0.0 is full left, 1.0 is full right) - AIL_quick_set_volume(haud, event.getVolume() * getVolume(AudioAffect_Speech), 0.5); - m_audioForcePlayed.push_back(haud); -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -void AILCALLBACK setSampleCompleted( HSAMPLE sampleCompleted ) -{ - TheAudio->notifyOfAudioCompletion((UnsignedInt) sampleCompleted, PAT_Sample); -} - -//------------------------------------------------------------------------------------------------- -void AILCALLBACK set3DSampleCompleted( H3DSAMPLE sample3DCompleted ) -{ - TheAudio->notifyOfAudioCompletion((UnsignedInt) sample3DCompleted, PAT_3DSample); -} - -//------------------------------------------------------------------------------------------------- -void AILCALLBACK setStreamCompleted( HSTREAM streamCompleted ) -{ - TheAudio->notifyOfAudioCompletion((UnsignedInt) streamCompleted, PAT_Stream); -} - -//------------------------------------------------------------------------------------------------- -U32 AILCALLBACK streamingFileOpen(char const *fileName, U32 *file_handle) -{ -#if defined(RTS_DEBUG) - if (sizeof(U32) != sizeof(File*)) { - RELEASE_CRASH(("streamingFileOpen - This function requires work in order to compile on non 32-bit platforms.")); - } -#endif - - (*file_handle) = (U32) TheFileSystem->openFile(fileName, File::READ | File::STREAMING); - return ((*file_handle) != 0); -} - -//------------------------------------------------------------------------------------------------- -void AILCALLBACK streamingFileClose(U32 fileHandle) -{ - ((File*) fileHandle)->close(); -} - -//------------------------------------------------------------------------------------------------- -S32 AILCALLBACK streamingFileSeek(U32 fileHandle, S32 offset, U32 type) -{ - return ((File*) fileHandle)->seek(offset, (File::seekMode) type); -} - -//------------------------------------------------------------------------------------------------- -U32 AILCALLBACK streamingFileRead(U32 file_handle, void *buffer, U32 bytes) -{ - return ((File*) file_handle)->read(buffer, bytes); -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -AudioFileCache::AudioFileCache() : m_maxSize(0), m_currentlyUsedSize(0), m_mutexName("AudioFileCacheMutex") -{ - m_mutex = CreateMutex(NULL, FALSE, m_mutexName); -} - -//------------------------------------------------------------------------------------------------- -AudioFileCache::~AudioFileCache() -{ - { - ScopedMutex mut(m_mutex); - - // Free all the samples that are open. - OpenFilesHashIt it; - for ( it = m_openFiles.begin(); it != m_openFiles.end(); ++it ) { - if (it->second.m_openCount > 0) { - DEBUG_CRASH(("Sample '%s' is still playing, and we're trying to quit.", it->second.m_eventInfo->m_audioName.str())); - } - - releaseOpenAudioFile(&it->second); - // Don't erase it from the map, cause it makes this whole process way more complicated, and - // we're about to go away anyways. - } - } - - CloseHandle(m_mutex); -} - -//------------------------------------------------------------------------------------------------- -void *AudioFileCache::openFile( AudioEventRTS *eventToOpenFrom ) -{ - // Protect the entire openFile function - ScopedMutex mut(m_mutex); - - AsciiString strToFind; - switch (eventToOpenFrom->getNextPlayPortion()) - { - case PP_Attack: - strToFind = eventToOpenFrom->getAttackFilename(); - break; - case PP_Sound: - strToFind = eventToOpenFrom->getFilename(); - break; - case PP_Decay: - strToFind = eventToOpenFrom->getDecayFilename(); - break; - case PP_Done: - return NULL; - } - - OpenFilesHash::iterator it; - it = m_openFiles.find(strToFind); - - if (it != m_openFiles.end()) { - ++it->second.m_openCount; - return it->second.m_file; - } - - // Couldn't find the file, so actually open it. - File *file = TheFileSystem->openFile(strToFind.str()); - if (!file) { - DEBUG_ASSERTLOG(strToFind.isEmpty(), ("Missing Audio File: '%s'", strToFind.str())); - return NULL; - } - - UnsignedInt fileSize = file->size(); - char* buffer = file->readEntireAndClose(); - - OpenAudioFile openedAudioFile; - openedAudioFile.m_eventInfo = eventToOpenFrom->getAudioEventInfo(); - - AILSOUNDINFO soundInfo; - AIL_WAV_info(buffer, &soundInfo); - - if (eventToOpenFrom->isPositionalAudio()) { - if (soundInfo.channels > 1) { - DEBUG_CRASH(("Requested Positional Play of audio '%s', but it is in stereo.", strToFind.str())); - delete [] buffer; - return NULL; - } - } - - if (soundInfo.format == WAVE_FORMAT_IMA_ADPCM) { - void *decompressFileBuffer; - U32 newFileSize; - AIL_decompress_ADPCM(&soundInfo, &decompressFileBuffer, &newFileSize); - fileSize = newFileSize; - openedAudioFile.m_compressed = TRUE; - delete [] buffer; - openedAudioFile.m_file = decompressFileBuffer; - openedAudioFile.m_soundInfo = soundInfo; - openedAudioFile.m_openCount = 1; - } else if (soundInfo.format == WAVE_FORMAT_PCM) { - openedAudioFile.m_compressed = FALSE; - openedAudioFile.m_file = buffer; - openedAudioFile.m_soundInfo = soundInfo; - openedAudioFile.m_openCount = 1; - } else { - DEBUG_CRASH(("Unexpected compression type in '%s'", strToFind.str())); - // prevent leaks - delete [] buffer; - return NULL; - } - - openedAudioFile.m_fileSize = fileSize; - m_currentlyUsedSize += openedAudioFile.m_fileSize; - if (m_currentlyUsedSize > m_maxSize) { - // We need to free some samples, or we're not going to be able to play this sound. - if (!freeEnoughSpaceForSample(openedAudioFile)) { - m_currentlyUsedSize -= openedAudioFile.m_fileSize; - releaseOpenAudioFile(&openedAudioFile); - return NULL; - } - } - - m_openFiles[strToFind] = openedAudioFile; - return openedAudioFile.m_file; -} - -//------------------------------------------------------------------------------------------------- -void AudioFileCache::closeFile( void *fileToClose ) -{ - if (!fileToClose) { - return; - } - - // Protect the entire closeFile function - ScopedMutex mut(m_mutex); - - OpenFilesHash::iterator it; - for ( it = m_openFiles.begin(); it != m_openFiles.end(); ++it ) { - if ( it->second.m_file == fileToClose ) { - --it->second.m_openCount; - return; - } - } -} - -//------------------------------------------------------------------------------------------------- -void AudioFileCache::setMaxSize( UnsignedInt size ) -{ - // Protect the function, in case we're trying to use this value elsewhere. - ScopedMutex mut(m_mutex); - - m_maxSize = size; -} - -//------------------------------------------------------------------------------------------------- -void AudioFileCache::releaseOpenAudioFile( OpenAudioFile *fileToRelease ) -{ - if (fileToRelease->m_openCount > 0) { - // This thing needs to be terminated IMMEDIATELY. - TheAudio->closeAnySamplesUsingFile(fileToRelease->m_file); - } - - if (fileToRelease->m_file) { - if (fileToRelease->m_compressed) { - // Files read in via AIL_decompress_ADPCM must be freed with AIL_mem_free_lock. - AIL_mem_free_lock(fileToRelease->m_file); - } else { - // Otherwise, we read it, we own it, blow it away. - delete [] fileToRelease->m_file; - } - fileToRelease->m_file = NULL; - fileToRelease->m_eventInfo = NULL; - } -} - -//------------------------------------------------------------------------------------------------- -Bool AudioFileCache::freeEnoughSpaceForSample(const OpenAudioFile& sampleThatNeedsSpace) -{ - - Int spaceRequired = m_currentlyUsedSize - m_maxSize; - Int runningTotal = 0; - - std::list filesToClose; - // First, search for any samples that have ref counts of 0. They are low-hanging fruit, and - // should be considered immediately. - OpenFilesHashIt it; - for (it = m_openFiles.begin(); it != m_openFiles.end(); ++it) { - if (it->second.m_openCount == 0) { - // This is said low-hanging fruit. - filesToClose.push_back(it->first); - - runningTotal += it->second.m_fileSize; - - if (runningTotal >= spaceRequired) { - break; - } - } - } - - // If we don't have enough space yet, then search through the events who have a count of 1 or more - // and who are lower priority than this sound. - // Mical said that at this point, sounds shouldn't care if other sounds are interruptable or not. - // Kill any files of lower priority necessary to clear our the buffer. - if (runningTotal < spaceRequired) { - for (it = m_openFiles.begin(); it != m_openFiles.end(); ++it) { - if (it->second.m_openCount > 0) { - if (it->second.m_eventInfo->m_priority < sampleThatNeedsSpace.m_eventInfo->m_priority) { - filesToClose.push_back(it->first); - runningTotal += it->second.m_fileSize; - - if (runningTotal >= spaceRequired) { - break; - } - } - } - } - } - - // We weren't able to find enough sounds to truncate. Therefore, this sound is not going to play. - if (runningTotal < spaceRequired) { - return FALSE; - } - - std::list::iterator ait; - for (ait = filesToClose.begin(); ait != filesToClose.end(); ++ait) { - OpenFilesHashIt itToErase = m_openFiles.find(*ait); - if (itToErase != m_openFiles.end()) { - releaseOpenAudioFile(&itToErase->second); - m_currentlyUsedSize -= itToErase->second.m_fileSize; - m_openFiles.erase(itToErase); - } - } - - return TRUE; -} - - -#if defined(RTS_DEBUG) -//------------------------------------------------------------------------------------------------- -void MilesAudioManager::dumpAllAssetsUsed() -{ - if (!TheGlobalData->m_preloadReport) { - return; - } - - // Dump all the audio assets we've used. - FILE *logfile=fopen("PreloadedAssets.txt","a+"); //append to log - if (!logfile) - return; - - std::list missingEvents; - std::list usedFiles; - - std::list::iterator lit; - - fprintf(logfile, "\nAudio Asset Report - BEGIN\n"); - { - SetAsciiStringIt it; - std::vector::iterator asIt; - for (it = m_allEventsLoaded.begin(); it != m_allEventsLoaded.end(); ++it) { - AsciiString astr = *it; - AudioEventInfo *aei = findAudioEventInfo(astr); - if (!aei) { - missingEvents.push_back(astr); - continue; - } - - for (asIt = aei->m_attackSounds.begin(); asIt != aei->m_attackSounds.end(); ++asIt) { - usedFiles.push_back(*asIt); - } - - for (asIt = aei->m_sounds.begin(); asIt != aei->m_sounds.end(); ++asIt) { - usedFiles.push_back(*asIt); - } - - for (asIt = aei->m_decaySounds.begin(); asIt != aei->m_decaySounds.end(); ++asIt) { - usedFiles.push_back(*asIt); - } - - if (!aei->m_filename.isEmpty()) { - usedFiles.push_back(aei->m_filename); - } - } - - fprintf(logfile, "\nEvents Requested that are missing information - BEGIN\n"); - for (lit = missingEvents.begin(); lit != missingEvents.end(); ++lit) { - fprintf(logfile, "%s\n", (*lit).str()); - } - fprintf(logfile, "\nEvents Requested that are missing information - END\n"); - - fprintf(logfile, "\nFiles Used - BEGIN\n"); - for (lit = usedFiles.begin(); lit != usedFiles.end(); ++lit) { - fprintf(logfile, "%s\n", (*lit).str()); - } - fprintf(logfile, "\nFiles Used - END\n"); - } - fprintf(logfile, "\nAudio Asset Report - END\n"); - fclose(logfile); - logfile = NULL; -} -#endif diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt index 9aa5607b51c..b3028b50a78 100644 --- a/GeneralsMD/Code/GameEngine/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngine/CMakeLists.txt @@ -4,13 +4,13 @@ set(GAMEENGINE_SRC # Include/Common/ArchiveFile.h # Include/Common/ArchiveFileSystem.h # Include/Common/AsciiString.h - Include/Common/AudioAffect.h - Include/Common/AudioEventInfo.h - Include/Common/AudioEventRTS.h - Include/Common/AudioHandleSpecialValues.h - Include/Common/AudioRandomValue.h - Include/Common/AudioRequest.h - Include/Common/AudioSettings.h +# Include/Common/AudioAffect.h +# Include/Common/AudioEventInfo.h +# Include/Common/AudioEventRTS.h +# Include/Common/AudioHandleSpecialValues.h +# Include/Common/AudioRandomValue.h +# Include/Common/AudioRequest.h +# Include/Common/AudioSettings.h Include/Common/BattleHonors.h Include/Common/BezFwdIterator.h Include/Common/BezierSegment.h @@ -33,21 +33,21 @@ set(GAMEENGINE_SRC Include/Common/DisabledTypes.h Include/Common/DiscreteCircle.h Include/Common/DrawModule.h - Include/Common/DynamicAudioEventInfo.h +# Include/Common/DynamicAudioEventInfo.h Include/Common/encrypt.h Include/Common/Energy.h Include/Common/Errors.h # Include/Common/file.h # Include/Common/FileSystem.h Include/Common/FunctionLexicon.h - Include/Common/GameAudio.h +# Include/Common/GameAudio.h Include/Common/GameCommon.h # Include/Common/GameDefines.h Include/Common/GameEngine.h Include/Common/GameLOD.h Include/Common/GameMemory.h - Include/Common/GameMusic.h - Include/Common/GameSounds.h +# Include/Common/GameMusic.h +# Include/Common/GameSounds.h Include/Common/GameSpyMiscPreferences.h Include/Common/GameState.h Include/Common/GameStateMap.h @@ -69,7 +69,7 @@ set(GAMEENGINE_SRC Include/Common/MapReaderWriterInfo.h Include/Common/MessageStream.h Include/Common/MiniLog.h - Include/Common/MiscAudio.h +# Include/Common/MiscAudio.h Include/Common/MissionStats.h Include/Common/ModelState.h Include/Common/Module.h @@ -100,7 +100,7 @@ set(GAMEENGINE_SRC Include/Common/Science.h Include/Common/ScopedMutex.h Include/Common/ScoreKeeper.h - Include/Common/simpleplayer.h +# Include/Common/simpleplayer.h Include/Common/SkirmishBattleHonors.h Include/Common/SkirmishPreferences.h Include/Common/Snapshot.h @@ -126,7 +126,7 @@ set(GAMEENGINE_SRC # Include/Common/UnicodeString.h Include/Common/UnitTimings.h Include/Common/Upgrade.h - Include/Common/urllaunch.h +# Include/Common/urllaunch.h Include/Common/UserPreferences.h Include/Common/version.h Include/Common/WellKnownKeys.h @@ -551,14 +551,14 @@ set(GAMEENGINE_SRC Include/GameNetwork/WOLBrowser/FEBDispatch.h Include/GameNetwork/WOLBrowser/WebBrowser.h Include/Precompiled/PreRTS.h - Source/Common/Audio/AudioEventRTS.cpp - Source/Common/Audio/AudioRequest.cpp - Source/Common/Audio/DynamicAudioEventInfo.cpp - Source/Common/Audio/GameAudio.cpp - Source/Common/Audio/GameMusic.cpp - Source/Common/Audio/GameSounds.cpp - #Source/Common/Audio/simpleplayer.cpp - #Source/Common/Audio/urllaunch.cpp +# Source/Common/Audio/AudioEventRTS.cpp +# Source/Common/Audio/AudioRequest.cpp +# Source/Common/Audio/DynamicAudioEventInfo.cpp +# Source/Common/Audio/GameAudio.cpp +# Source/Common/Audio/GameMusic.cpp +# Source/Common/Audio/GameSounds.cpp + #Source/Common/Audio/simpleplayer.cpp # unused + #Source/Common/Audio/urllaunch.cpp # unused Source/Common/Bezier/BezFwdIterator.cpp Source/Common/Bezier/BezierSegment.cpp Source/Common/BitFlags.cpp @@ -575,7 +575,7 @@ set(GAMEENGINE_SRC Source/Common/INI/INI.cpp Source/Common/INI/INIAiData.cpp Source/Common/INI/INIAnimation.cpp - Source/Common/INI/INIAudioEventInfo.cpp +# Source/Common/INI/INIAudioEventInfo.cpp Source/Common/INI/INICommandButton.cpp Source/Common/INI/INICommandSet.cpp Source/Common/INI/INIControlBarScheme.cpp @@ -586,7 +586,7 @@ set(GAMEENGINE_SRC Source/Common/INI/INIMapCache.cpp Source/Common/INI/INIMapData.cpp Source/Common/INI/INIMappedImage.cpp - Source/Common/INI/INIMiscAudio.cpp +# Source/Common/INI/INIMiscAudio.cpp Source/Common/INI/INIModel.cpp Source/Common/INI/INIMultiplayer.cpp Source/Common/INI/INIObject.cpp @@ -814,7 +814,7 @@ set(GAMEENGINE_SRC Source/GameClient/Statistics.cpp Source/GameClient/System/Anim2D.cpp Source/GameClient/System/CampaignManager.cpp - "Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp" +# "Source/GameClient/System/Debug Displayers/AudioDebugDisplay.cpp" Source/GameClient/System/DebugDisplay.cpp Source/GameClient/System/Image.cpp Source/GameClient/System/ParticleSys.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt index f9cf1653686..b352d5f4200 100644 --- a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt @@ -1,5 +1,5 @@ set(GAMEENGINEDEVICE_SRC - Include/MilesAudioDevice/MilesAudioManager.h +# Include/MilesAudioDevice/MilesAudioManager.h Include/VideoDevice/Bink/BinkVideoPlayer.h Include/W3DDevice/Common/W3DConvert.h Include/W3DDevice/Common/W3DFunctionLexicon.h @@ -90,7 +90,7 @@ set(GAMEENGINEDEVICE_SRC Include/Win32Device/GameClient/Win32DIKeyboard.h Include/Win32Device/GameClient/Win32DIMouse.h Include/Win32Device/GameClient/Win32Mouse.h - Source/MilesAudioDevice/MilesAudioManager.cpp +# Source/MilesAudioDevice/MilesAudioManager.cpp Source/VideoDevice/Bink/BinkVideoPlayer.cpp Source/W3DDevice/Common/System/W3DFunctionLexicon.cpp Source/W3DDevice/Common/System/W3DRadar.cpp