diff --git a/Core/GameEngine/Include/Common/GameAudio.h b/Core/GameEngine/Include/Common/GameAudio.h index 74f6c7120c0..ba81d473bfc 100644 --- a/Core/GameEngine/Include/Common/GameAudio.h +++ b/Core/GameEngine/Include/Common/GameAudio.h @@ -387,55 +387,5 @@ class AudioManager : public SubsystemInterface 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 nullptr; } - 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 nullptr; } - 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; diff --git a/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h b/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h index 6d6f52f2d55..bca2c8539e9 100644 --- a/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h +++ b/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h @@ -330,3 +330,53 @@ class MilesAudioManager : public AudioManager }; +// TheSuperHackers @feature helmutbuhler 17/05/2025 AudioManager that does almost nothing. Used for Headless Mode. +// @bugfix Caball009 16/02/2026 Scripts may require the actual audio file length to function properly. +// The Miles AudioManager handles the device opening / closure, so that getFileLengthMS can function as intended. +class MilesAudioManagerDummy : public MilesAudioManager +{ +#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 nullptr; } + virtual void notifyOfAudioCompletion(UnsignedInt audioCompleted, UnsignedInt flags) {} + virtual UnsignedInt getProviderCount() 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() {} + virtual UnsignedInt getSelectedProvider() const { return 0; } + virtual void setSpeakerType(UnsignedInt speakerType) {} + virtual UnsignedInt getSpeakerType() { return 0; } + virtual UnsignedInt getNum2DSamples() const { return 0; } + virtual UnsignedInt getNum3DSamples() const { return 0; } + virtual UnsignedInt getNumStreams() 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() const { return false; } + virtual void* getHandleForBink() { return nullptr; } + virtual void releaseHandleForBink() {} + virtual void friend_forcePlayAudioEventRTS(const AudioEventRTS* eventToPlay) {} + virtual void setPreferredProvider(AsciiString providerNdx) {} + virtual void setPreferredSpeaker(AsciiString speakerType) {} + //virtual Real getFileLengthMS(AsciiString strToLoad) const { return 0.0f; } + virtual void closeAnySamplesUsingFile(const void* fileToClose) {} + virtual void setDeviceListenerPosition() {} +}; diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h b/GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h index 62d3502eed1..6473eef7f98 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h @@ -95,7 +95,7 @@ class GameEngine : public SubsystemInterface virtual Radar *createRadar( void ) = 0; ///< Factory for radar virtual WebBrowser *createWebBrowser( void ) = 0; ///< Factory for embedded browser virtual ParticleSystemManager* createParticleSystemManager( void ) = 0; - virtual AudioManager *createAudioManager( void ) = 0; ///< Factory for Audio Manager + virtual AudioManager *createAudioManager( bool headless ) = 0; ///< Factory for Audio Manager Real m_logicTimeAccumulator; ///< Frame time accumulated towards submitting a new logic frame diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp index 5aa3a1e7b4d..ceebf85f1ee 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp @@ -522,7 +522,7 @@ void GameEngine::init() startTime64 = endTime64;//Reset the clock //////////////////////////////////////////////////////// DEBUG_LOG(("%s", Buf));//////////////////////////////////////////////////////////////////////////// #endif///////////////////////////////////////////////////////////////////////////////////////////// - initSubsystem(TheAudio,"TheAudio", TheGlobalData->m_headless ? NEW AudioManagerDummy : createAudioManager(), nullptr); + initSubsystem(TheAudio,"TheAudio", createAudioManager(TheGlobalData->m_headless), nullptr); if (!TheAudio->isMusicAlreadyLoaded()) setQuitting(TRUE); diff --git a/GeneralsMD/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h b/GeneralsMD/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h index 8eac1dccc1c..87cab864e76 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h +++ b/GeneralsMD/Code/GameEngineDevice/Include/Win32Device/Common/Win32GameEngine.h @@ -77,7 +77,7 @@ class Win32GameEngine : public GameEngine virtual NetworkInterface *createNetwork( void ); ///< Factory for the network virtual Radar *createRadar( void ); ///< Factory for radar virtual WebBrowser *createWebBrowser( void ); ///< Factory for embedded browser - virtual AudioManager *createAudioManager( void ); ///< Factory for audio device + virtual AudioManager *createAudioManager( bool headless ); ///< Factory for audio device virtual ParticleSystemManager* createParticleSystemManager( void ); @@ -98,4 +98,4 @@ inline ParticleSystemManager* Win32GameEngine::createParticleSystemManager( void inline NetworkInterface *Win32GameEngine::createNetwork( void ) { return NetworkInterface::createNetwork(); } inline Radar *Win32GameEngine::createRadar( void ) { return NEW W3DRadar; } inline WebBrowser *Win32GameEngine::createWebBrowser( void ) { return NEW CComObject; } -inline AudioManager *Win32GameEngine::createAudioManager( void ) { return NEW MilesAudioManager; } +inline AudioManager *Win32GameEngine::createAudioManager( bool headless ) { return headless ? NEW MilesAudioManagerDummy : NEW MilesAudioManager; }