diff --git a/Core/GameEngine/Include/Common/AudioEventRTS.h b/Core/GameEngine/Include/Common/AudioEventRTS.h index f38f1e5417a..15d441dd428 100644 --- a/Core/GameEngine/Include/Common/AudioEventRTS.h +++ b/Core/GameEngine/Include/Common/AudioEventRTS.h @@ -199,14 +199,27 @@ class AudioEventRTS PortionToPlay m_portionToPlayNext; ///< Which portion (attack, sound, decay) should be played next? }; -class DynamicAudioEventRTS : public MemoryPoolObject +class DynamicAudioEventRTS : public MemoryPoolObject, public RefCountClass, public AudioEventRTS { MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(DynamicAudioEventRTS, "DynamicAudioEventRTS" ) public: - DynamicAudioEventRTS() { } - DynamicAudioEventRTS(const AudioEventRTS& a) : m_event(a) { } + DynamicAudioEventRTS() {} + DynamicAudioEventRTS( const AsciiString& eventName ) : AudioEventRTS(eventName) {} + DynamicAudioEventRTS( const AsciiString& eventName, ObjectID ownerID ) : AudioEventRTS(eventName, ownerID) {} + DynamicAudioEventRTS( const AsciiString& eventName, DrawableID drawableID ) : AudioEventRTS(eventName, drawableID) {} + DynamicAudioEventRTS( const AsciiString& eventName, const Coord3D *positionOfAudio ) : AudioEventRTS(eventName, positionOfAudio) {} - AudioEventRTS m_event; + DynamicAudioEventRTS(const AudioEventRTS& a) : AudioEventRTS(a) {} + DynamicAudioEventRTS& operator=( const AudioEventRTS& right ) + { + *static_cast(this) = right; + return *this; + } + + void Delete_This() override + { + deleteInstance(this); + } }; EMPTY_DTOR(DynamicAudioEventRTS) diff --git a/Core/GameEngine/Include/Common/AudioRequest.h b/Core/GameEngine/Include/Common/AudioRequest.h index 3174fe85a8a..cf0504f8c2c 100644 --- a/Core/GameEngine/Include/Common/AudioRequest.h +++ b/Core/GameEngine/Include/Common/AudioRequest.h @@ -30,8 +30,9 @@ #include "Common/GameAudio.h" #include "Common/GameMemory.h" +#include "Common/AudioHandleSpecialValues.h" -class AudioEventRTS; +class DynamicAudioEventRTS; enum RequestType CPP_11(: Int) { @@ -45,14 +46,16 @@ struct AudioRequest : public MemoryPoolObject MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AudioRequest, "AudioRequest" ) public: - AudioEventRTS* releasePendingEvent(); + + AudioRequest() + : m_request(AR_Play) + , m_pendingEvent(nullptr) + , m_handleToInteractOn(AHSV_Error) + , m_requiresCheckForSample(false) + {} RequestType m_request; - union - { - AudioEventRTS *m_pendingEvent; - AudioHandle m_handleToInteractOn; - }; - Bool m_usePendingEvent; + RefCountPtr m_pendingEvent; + AudioHandle m_handleToInteractOn; Bool m_requiresCheckForSample; }; diff --git a/Core/GameEngine/Include/Common/GameAudio.h b/Core/GameEngine/Include/Common/GameAudio.h index cc9d6cf8338..1d712178412 100644 --- a/Core/GameEngine/Include/Common/GameAudio.h +++ b/Core/GameEngine/Include/Common/GameAudio.h @@ -45,6 +45,7 @@ #include "Lib/BaseType.h" #include "Common/STLTypedefs.h" #include "Common/SubsystemInterface.h" +#include "mutex.h" // Forward Declarations @@ -255,9 +256,9 @@ class AudioManager : public SubsystemInterface virtual void setListenerPosition( const Coord3D *newListenerPos, const Coord3D *newListenerOrientation ); virtual const Coord3D *getListenerPosition() const; - virtual AudioRequest *allocateAudioRequest( Bool useAudioEvent ); + virtual AudioRequest *allocateAudioRequest(); virtual void releaseAudioRequest( AudioRequest *requestToRelease ); - virtual void appendAudioRequest( AudioRequest *m_request ); + virtual void appendAudioRequest( AudioRequest *request ); virtual void processRequestList(); virtual AudioEventInfo *newAudioEventInfo( AsciiString newEventName ); @@ -267,9 +268,6 @@ class AudioManager : public SubsystemInterface const AudioSettings *getAudioSettings() const; const MiscAudio *getMiscAudio() const; - // This function should only be called by AudioManager, MusicManager and SoundManager - virtual void releaseAudioEventRTS( AudioEventRTS *&eventToRelease ); - // For INI AudioSettings *friend_getAudioSettings(); MiscAudio *friend_getMiscAudio(); diff --git a/Core/GameEngine/Include/Common/GameMusic.h b/Core/GameEngine/Include/Common/GameMusic.h index cd47a3f8ece..346cb402ade 100644 --- a/Core/GameEngine/Include/Common/GameMusic.h +++ b/Core/GameEngine/Include/Common/GameMusic.h @@ -102,10 +102,10 @@ class MusicManager MusicManager(); virtual ~MusicManager(); - void playTrack( AudioEventRTS *eventToUse ); + void playTrack( DynamicAudioEventRTS *eventToUse ); void stopTrack( AudioHandle eventToRemove ); - virtual void addAudioEvent(AudioEventRTS *eventToAdd); // pre-copied + virtual void addAudioEvent( DynamicAudioEventRTS *eventToAdd ); // pre-copied virtual void removeAudioEvent( AudioHandle eventToRemove ); void setVolume( Real m_volume ); diff --git a/Core/GameEngine/Include/Common/GameSounds.h b/Core/GameEngine/Include/Common/GameSounds.h index 83c846957ac..f239b15162d 100644 --- a/Core/GameEngine/Include/Common/GameSounds.h +++ b/Core/GameEngine/Include/Common/GameSounds.h @@ -45,8 +45,8 @@ #include "Common/GameAudio.h" #include "Common/GameType.h" -// Forward declarations class AudioEventRTS; +class DynamicAudioEventRTS; class SoundManager : public SubsystemInterface { @@ -67,7 +67,7 @@ class SoundManager : public SubsystemInterface virtual void setCameraAudibleDistance( Real audibleDistance ); virtual Real getCameraAudibleDistance(); - virtual void addAudioEvent(AudioEventRTS *&eventToAdd); // pre-copied + virtual Bool addAudioEvent(DynamicAudioEventRTS *eventToAdd); // pre-copied virtual void notifyOf2DSampleStart(); virtual void notifyOf3DSampleStart(); diff --git a/Core/GameEngine/Source/Common/Audio/AudioRequest.cpp b/Core/GameEngine/Source/Common/Audio/AudioRequest.cpp index 36876f35449..6fcf9b80c98 100644 --- a/Core/GameEngine/Source/Common/Audio/AudioRequest.cpp +++ b/Core/GameEngine/Source/Common/Audio/AudioRequest.cpp @@ -30,20 +30,4 @@ AudioRequest::~AudioRequest() { - if (m_usePendingEvent) - { - delete m_pendingEvent; - } -} - -AudioEventRTS* AudioRequest::releasePendingEvent() -{ - if (m_usePendingEvent) - { - m_usePendingEvent = false; - AudioEventRTS* event = m_pendingEvent; - m_pendingEvent = nullptr; - return event; - } - return nullptr; } diff --git a/Core/GameEngine/Source/Common/Audio/GameAudio.cpp b/Core/GameEngine/Source/Common/Audio/GameAudio.cpp index 41be35aeeed..91b236fdff1 100644 --- a/Core/GameEngine/Source/Common/Audio/GameAudio.cpp +++ b/Core/GameEngine/Source/Common/Audio/GameAudio.cpp @@ -437,7 +437,8 @@ AudioHandle AudioManager::addAudioEvent(const AudioEventRTS *eventToAdd) return AHSV_NotForLocal; } - AudioEventRTS *audioEvent = MSGNEW("AudioEventRTS") AudioEventRTS(*eventToAdd); // poolify + DynamicAudioEventRTS *newEvent = newInstance(DynamicAudioEventRTS)(*eventToAdd); + RefCountPtr audioEvent = RefCountPtr::Create_NoAddRef(newEvent); audioEvent->setPlayingHandle( allocateNewHandle() ); audioEvent->generateFilename(); // which file are we actually going to play? eventToAdd->setPlayingAudioIndex( audioEvent->getPlayingAudioIndex() ); @@ -454,7 +455,6 @@ AudioHandle AudioManager::addAudioEvent(const AudioEventRTS *eventToAdd) #if RETAIL_COMPATIBLE_CRC if (notForLocal) { - releaseAudioEventRTS(audioEvent); return AHSV_NotForLocal; } #endif @@ -464,21 +464,22 @@ AudioHandle AudioManager::addAudioEvent(const AudioEventRTS *eventToAdd) #ifdef INTENSIVE_AUDIO_DEBUG DEBUG_LOG((" - culled due to muting (%d).", audioEvent->getVolume())); #endif - releaseAudioEventRTS(audioEvent); return AHSV_Muted; } if (soundType == AT_Music) { - m_music->addAudioEvent(audioEvent); + m_music->addAudioEvent(audioEvent.Peek()); } else { - //Possible to nuke audioEvent inside. - m_sound->addAudioEvent(audioEvent); + if (!m_sound->addAudioEvent(audioEvent.Peek())) + { + audioEvent.Clear(); + } } - if( audioEvent ) + if( audioEvent != nullptr ) { return audioEvent->getPlayingHandle(); } @@ -576,7 +577,7 @@ void AudioManager::removeAudioEvent(AudioHandle audioEvent) return; } - AudioRequest *req = allocateAudioRequest( false ); + AudioRequest *req = allocateAudioRequest(); req->m_handleToInteractOn = audioEvent; req->m_request = AR_Stop; appendAudioRequest( req ); @@ -786,10 +787,9 @@ const Coord3D *AudioManager::getListenerPosition() const } //------------------------------------------------------------------------------------------------- -AudioRequest *AudioManager::allocateAudioRequest( Bool useAudioEvent ) +AudioRequest *AudioManager::allocateAudioRequest() { AudioRequest *audioReq = newInstance(AudioRequest); - audioReq->m_usePendingEvent = useAudioEvent; audioReq->m_requiresCheckForSample = false; return audioReq; } @@ -801,21 +801,20 @@ void AudioManager::releaseAudioRequest( AudioRequest *requestToRelease ) } //------------------------------------------------------------------------------------------------- -void AudioManager::appendAudioRequest( AudioRequest *m_request ) +void AudioManager::appendAudioRequest( AudioRequest *request ) { - m_audioRequests.push_back(m_request); + m_audioRequests.push_back(request); } //------------------------------------------------------------------------------------------------- // Remove all pending audio requests void AudioManager::removeAllAudioRequests() { - std::list::iterator it; - for ( it = m_audioRequests.begin(); it != m_audioRequests.end(); it++ ) { - releaseAudioRequest( *it ); - } - - m_audioRequests.clear(); + std::list::iterator it; + for ( it = m_audioRequests.begin(); it != m_audioRequests.end(); ++it ) { + releaseAudioRequest( *it ); + } + m_audioRequests.clear(); } //------------------------------------------------------------------------------------------------- @@ -1043,17 +1042,10 @@ Bool AudioManager::shouldPlayLocally(const AudioEventRTS *audioEvent) //------------------------------------------------------------------------------------------------- AudioHandle AudioManager::allocateNewHandle() { - // note, intenionally a post increment rather than a pre increment. + // note, intentionally a post increment rather than a pre increment. return theAudioHandlePool++; } -//------------------------------------------------------------------------------------------------- -void AudioManager::releaseAudioEventRTS( AudioEventRTS *&eventToRelease ) -{ - delete eventToRelease; - eventToRelease = nullptr; -} - //------------------------------------------------------------------------------------------------- void AudioManager::muteAudio( MuteAudioReason reason ) { diff --git a/Core/GameEngine/Source/Common/Audio/GameMusic.cpp b/Core/GameEngine/Source/Common/Audio/GameMusic.cpp index 5e05c6ee4d3..2e547693c87 100644 --- a/Core/GameEngine/Source/Common/Audio/GameMusic.cpp +++ b/Core/GameEngine/Source/Common/Audio/GameMusic.cpp @@ -95,10 +95,10 @@ MusicManager::~MusicManager() } //------------------------------------------------------------------------------------------------- -void MusicManager::playTrack( AudioEventRTS *eventToUse ) +void MusicManager::playTrack( DynamicAudioEventRTS *eventToUse ) { - AudioRequest *audioRequest = TheAudio->allocateAudioRequest( true ); - audioRequest->m_pendingEvent = eventToUse; + AudioRequest *audioRequest = TheAudio->allocateAudioRequest(); + audioRequest->m_pendingEvent = RefCountPtr::Create_AddRef(eventToUse); audioRequest->m_request = AR_Play; TheAudio->appendAudioRequest( audioRequest ); } @@ -106,14 +106,14 @@ void MusicManager::playTrack( AudioEventRTS *eventToUse ) //------------------------------------------------------------------------------------------------- void MusicManager::stopTrack( AudioHandle eventToRemove ) { - AudioRequest *audioRequest = TheAudio->allocateAudioRequest( false ); + AudioRequest *audioRequest = TheAudio->allocateAudioRequest(); audioRequest->m_handleToInteractOn = eventToRemove; audioRequest->m_request = AR_Stop; TheAudio->appendAudioRequest( audioRequest ); } //------------------------------------------------------------------------------------------------- -void MusicManager::addAudioEvent( AudioEventRTS *eventToAdd ) +void MusicManager::addAudioEvent( DynamicAudioEventRTS *eventToAdd ) { playTrack( eventToAdd ); } diff --git a/Core/GameEngine/Source/Common/Audio/GameSounds.cpp b/Core/GameEngine/Source/Common/Audio/GameSounds.cpp index c1f1afeedfe..2fababd8fd9 100644 --- a/Core/GameEngine/Source/Common/Audio/GameSounds.cpp +++ b/Core/GameEngine/Source/Common/Audio/GameSounds.cpp @@ -133,7 +133,7 @@ Real SoundManager::getCameraAudibleDistance() } //------------------------------------------------------------------------------------------------- -void SoundManager::addAudioEvent(AudioEventRTS *&eventToAdd) +Bool SoundManager::addAudioEvent(DynamicAudioEventRTS *eventToAdd) { if (m_num2DSamples == 0 && m_num3DSamples == 0) { m_num2DSamples = TheAudio->getNum2DSamples(); @@ -144,13 +144,14 @@ void SoundManager::addAudioEvent(AudioEventRTS *&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 *audioRequest = TheAudio->allocateAudioRequest(); + audioRequest->m_pendingEvent = RefCountPtr::Create_AddRef(eventToAdd); audioRequest->m_request = AR_Play; TheAudio->appendAudioRequest(audioRequest); - } else { - TheAudio->releaseAudioEventRTS(eventToAdd); + return true; } + + return false; } //------------------------------------------------------------------------------------------------- diff --git a/Core/GameEngine/Source/Common/INI/INI.cpp b/Core/GameEngine/Source/Common/INI/INI.cpp index b3a26a5f4c1..086dec018a5 100644 --- a/Core/GameEngine/Source/Common/INI/INI.cpp +++ b/Core/GameEngine/Source/Common/INI/INI.cpp @@ -1167,23 +1167,22 @@ void INI::parseICoord2D( INI* ini, void * /*instance*/, void *store, const void* void INI::parseDynamicAudioEventRTS( INI *ini, void * /*instance*/, void *store, const void* userData ) { const char *token = ini->getNextToken(); - DynamicAudioEventRTS** theSound = (DynamicAudioEventRTS**)store; + RefCountPtr* theSound = (RefCountPtr*)store; // translate the string into a sound if (stricmp(token, "NoSound") == 0) { - deleteInstance(*theSound); - *theSound = nullptr; + theSound->Clear(); } else { if (*theSound == nullptr) - *theSound = newInstance(DynamicAudioEventRTS); - (*theSound)->m_event.setEventName(AsciiString(token)); + *theSound = RefCountPtr::Create_NoAddRef(newInstance(DynamicAudioEventRTS)); + (*theSound)->setEventName(AsciiString(token)); } if (*theSound) - TheAudio->getInfoForAudioEvent(&(*theSound)->m_event); + TheAudio->getInfoForAudioEvent(theSound->Peek()); } //------------------------------------------------------------------------------------------------- diff --git a/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h b/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h index 6000d1c8f8b..c89bc7cdab9 100644 --- a/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h +++ b/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h @@ -26,6 +26,7 @@ #include "mutex.h" class AudioEventRTS; +class DynamicAudioEventRTS; enum { MAXPROVIDERS = 64 }; @@ -61,13 +62,13 @@ struct PlayingAudio HSTREAM m_stream; }; - AudioEventRTS *m_audioEventRTS; + RefCountPtr m_audioEventRTS; void *m_file; // The file that was opened to play this PlayingAudioType m_type; volatile PlayingStatus m_status; // This member is adjusted by another running thread. Short m_framesFaded; Bool m_fade; - Bool m_cleanupAudioEventRTS; + Bool m_rerequestOnNextUpdate; PlayingAudio() : m_sample(nullptr) @@ -77,7 +78,7 @@ struct PlayingAudio , m_status(PS_Playing) , m_framesFaded(0) , m_fade(false) - , m_cleanupAudioEventRTS(true) + , m_rerequestOnNextUpdate(false) {} static_assert(sizeof(m_status) == sizeof(long), "Must be size of long, because it is used with Interlocked functions"); @@ -175,7 +176,7 @@ class MilesAudioManager : public AudioManager ///< NOTE NOTE NOTE !!DO NOT USE THIS IN FOR GAMELOGIC PURPOSES!! NOTE NOTE NOTE virtual Bool isCurrentlyPlaying( AudioHandle handle ) override; - virtual void notifyOfAudioCompletion( UnsignedInt handle, UnsignedInt flags ) override; + virtual void notifyOfAudioCompletion( UnsignedInt handle, UnsignedInt flags ) override; ///< Is called on MSS Timer thread virtual PlayingAudio *findPlayingAudioFrom( UnsignedInt handle, UnsignedInt flags ); virtual UnsignedInt getProviderCount() const override; @@ -263,6 +264,7 @@ class MilesAudioManager : public AudioManager void releaseMilesHandles( PlayingAudio *release ); void releasePlayingAudio( PlayingAudio *release ); void stopPlayingAudio( PlayingAudio *release ); + void rerequestPlayingAudio( PlayingAudio *playing ); void fadePlayingAudio( PlayingAudio *playing ); PlayingAudio *findActiveMusic( const AsciiString *trackName = nullptr ); diff --git a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp index f3e16790c58..0f95be493de 100644 --- a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp +++ b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp @@ -38,7 +38,6 @@ /* 7/18/2002 : Initial creation */ /*---------------------------------------------------------------------------*/ -#include #include "Lib/BaseType.h" #include "MilesAudioDevice/MilesAudioManager.h" @@ -66,8 +65,9 @@ #include "Common/file.h" -#include +#include "win.h" +#include enum { INFINITE_LOOP_COUNT = 1000000 }; @@ -237,18 +237,19 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL for (Int i = 1; i <= maxChannels && i <= channelCount; ++i) { playing = playingArray[i]; if (!playing) { - dd->printf("%d: Silence\n", i); + dd->printf("%2d: Silence\n", i); continue; } - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); + AudioEventRTS *event = playing->m_audioEventRTS.Peek(); + filenameNoSlashes = event->getFilename(); filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1; // Calculate Sample volume volume = 100.0f; - volume *= getEffectiveVolume(playing->m_audioEventRTS); + volume *= getEffectiveVolume(event); - dd->printf("%2d: %-20s - (%s) Volume: %d (2D)\n", i, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume)); + dd->printf("%2d: %-20s - (%s) Volume: %d (2D)\n", i, event->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume)); playingArray[i] = nullptr; } } @@ -260,18 +261,19 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) { playing = *it; - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); + AudioEventRTS *event = playing->m_audioEventRTS.Peek(); + filenameNoSlashes = event->getFilename(); filenameNoSlashes = filenameNoSlashes.reverseFind( '\\' ) + 1; // Calculate Sample volume volume = 100.0f; - volume *= getEffectiveVolume( playing->m_audioEventRTS ); + volume *= getEffectiveVolume( event ); - fprintf( fp, "%2d: %-20s - (%s) Volume: %d (2D)\n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) ); + fprintf( fp, "%2d: %-20s - (%s) Volume: %d (2D)\n", channel++, event->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) ); } for( int i = channel; i <= channelCount; ++i ) { - fprintf( fp, "%d: Silence\n", i ); + fprintf( fp, "%2d: Silence\n", i ); } } @@ -292,18 +294,19 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL playing = playingArray[i]; if (!playing) { - dd->printf("%d: Silence\n", i); + dd->printf("%2d: Silence\n", i); continue; } - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); + AudioEventRTS *event = playing->m_audioEventRTS.Peek(); + filenameNoSlashes = event->getFilename(); filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1; // Calculate Sample volume volume = 100.0f; - volume *= getEffectiveVolume(playing->m_audioEventRTS); + volume *= getEffectiveVolume(event); Real dist = -1.0f; - const Coord3D *pos = playing->m_audioEventRTS->getPosition(); + const Coord3D *pos = event->getPosition(); char distStr[32]; if( pos ) { @@ -317,7 +320,7 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL sprintf( distStr, "???" ); } char str[32]; - switch( playing->m_audioEventRTS->getOwnerType() ) + switch( event->getOwnerType() ) { case OT_Positional: sprintf( str, "(3D)" ); @@ -335,7 +338,7 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL } 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 ); + i, event->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume), distStr, str ); playingArray[i] = nullptr; } } @@ -347,13 +350,14 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) { playing = *it; - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); + AudioEventRTS *event = playing->m_audioEventRTS.Peek(); + filenameNoSlashes = event->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 ) ); + volume *= getEffectiveVolume( event ); + fprintf( fp, "%2d: %-24s - (%s) Volume: %d \n", channel++, event->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) ); } for( int i = channel; i <= channelCount; ++i ) @@ -370,14 +374,15 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL channel = 1; for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { playing = *it; - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); + AudioEventRTS *event = playing->m_audioEventRTS.Peek(); + filenameNoSlashes = event->getFilename(); filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1; // Calculate Sample volume volume = 100.0f; - volume *= getEffectiveVolume(playing->m_audioEventRTS); + volume *= getEffectiveVolume(event); - dd->printf("%2d: %-24s - (%s) Volume: %d (Stream)\n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume)); + dd->printf("%2d: %-24s - (%s) Volume: %d (Stream)\n", channel++, event->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT(volume)); } for ( int i = channel; i <= channelCount; ++i) { @@ -393,14 +398,15 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL for( it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it ) { playing = *it; - filenameNoSlashes = playing->m_audioEventRTS->getFilename(); + AudioEventRTS *event = playing->m_audioEventRTS.Peek(); + filenameNoSlashes = event->getFilename(); filenameNoSlashes = filenameNoSlashes.reverseFind('\\') + 1; // Calculate Sample volume volume = 100.0f; - volume *= getEffectiveVolume(playing->m_audioEventRTS); + volume *= getEffectiveVolume(event); - fprintf( fp, "%2d: %-24s - (%s) Volume: %d (Stream)\n", channel++, playing->m_audioEventRTS->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) ); + fprintf( fp, "%2d: %-24s - (%s) Volume: %d (Stream)\n", channel++, event->getEventName().str(), filenameNoSlashes.str(), REAL_TO_INT( volume ) ); } for( int i = channel; i <= channelCount; ++i ) @@ -611,9 +617,9 @@ void MilesAudioManager::pauseAmbient( Bool shouldPause ) //------------------------------------------------------------------------------------------------- void MilesAudioManager::playAudioEvent( AudioRequest* req ) { - DEBUG_ASSERTCRASH(req->m_usePendingEvent && req->m_pendingEvent, ("audio request was expected to contain a valid audio event")); + DEBUG_ASSERTCRASH(req->m_pendingEvent != nullptr, ("audio request was expected to contain a valid audio event")); - AudioEventRTS* event = req->m_pendingEvent; + AudioEventRTS* event = req->m_pendingEvent.Peek(); #ifdef INTENSIVE_AUDIO_DEBUG DEBUG_LOG(("MILES (%d) - Processing play request: %d (%s)", TheGameLogic->getFrame(), event->getPlayingHandle(), event->getEventName().str())); @@ -666,7 +672,7 @@ void MilesAudioManager::playAudioEvent( AudioRequest* req ) } // Put this on here, so that the audio event RTS will be cleaned up regardless. - audio->m_audioEventRTS = event = req->releasePendingEvent(); + audio->m_audioEventRTS = req->m_pendingEvent; audio->m_stream = stream; audio->m_type = PAT_Stream; @@ -733,7 +739,7 @@ void MilesAudioManager::playAudioEvent( AudioRequest* req ) sample3D = nullptr; } // Push it onto the list of playing things - audio->m_audioEventRTS = event = req->releasePendingEvent(); + audio->m_audioEventRTS = req->m_pendingEvent; audio->m_3DSample = sample3D; audio->m_file = nullptr; audio->m_type = PAT_3DSample; @@ -800,7 +806,7 @@ void MilesAudioManager::playAudioEvent( AudioRequest* req ) } // Push it onto the list of playing things - audio->m_audioEventRTS = event = req->releasePendingEvent(); + audio->m_audioEventRTS = req->m_pendingEvent; audio->m_sample = sample; audio->m_file = nullptr; audio->m_type = PAT_Sample; @@ -902,7 +908,7 @@ void MilesAudioManager::killAudioEventImmediately( AudioHandle audioEvent ) for( ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ait++ ) { AudioRequest *req = (*ait); - if( req->m_usePendingEvent && req->m_pendingEvent->getPlayingHandle() == audioEvent ) + if( req->m_pendingEvent && req->m_pendingEvent->getPlayingHandle() == audioEvent ) { deleteInstance(req); ait = m_audioRequests.erase(ait); @@ -1025,10 +1031,6 @@ void MilesAudioManager::releasePlayingAudio( PlayingAudio *release ) release->m_file = nullptr; } - if (release->m_cleanupAudioEventRTS) { - releaseAudioEventRTS(release->m_audioEventRTS); - } - delete release; } @@ -1056,6 +1058,17 @@ void MilesAudioManager::stopPlayingAudio( PlayingAudio *release ) releaseMilesHandles(release); } +//------------------------------------------------------------------------------------------------- +void MilesAudioManager::rerequestPlayingAudio( PlayingAudio *playing ) +{ + playing->m_audioEventRTS->generateFilename(); + + AudioRequest *req = allocateAudioRequest(); + req->m_pendingEvent = playing->m_audioEventRTS; + req->m_requiresCheckForSample = true; + appendAudioRequest(req); +} + //------------------------------------------------------------------------------------------------- void MilesAudioManager::fadePlayingAudio( PlayingAudio *playing ) { @@ -1226,18 +1239,18 @@ void MilesAudioManager::adjustPlayingVolume( PlayingAudio *audio ) Real pan; if (audio->m_type == PAT_Sample) { AIL_sample_volume_pan(audio->m_sample, nullptr, &pan); - AIL_set_sample_volume_pan(audio->m_sample, getEffectiveVolume(audio->m_audioEventRTS), pan); + AIL_set_sample_volume_pan(audio->m_sample, getEffectiveVolume(audio->m_audioEventRTS.Peek()), pan); } else if (audio->m_type == PAT_3DSample) { - AIL_set_3D_sample_volume(audio->m_3DSample, getEffectiveVolume(audio->m_audioEventRTS)); + AIL_set_3D_sample_volume(audio->m_3DSample, getEffectiveVolume(audio->m_audioEventRTS.Peek())); } else if (audio->m_type == PAT_Stream) { AIL_stream_volume_pan(audio->m_stream, nullptr, &pan); if (audio->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music ) { - AIL_set_stream_volume_pan(audio->m_stream, getEffectiveVolume(audio->m_audioEventRTS), pan); + AIL_set_stream_volume_pan(audio->m_stream, getEffectiveVolume(audio->m_audioEventRTS.Peek()), pan); } else { - AIL_set_stream_volume_pan(audio->m_stream, getEffectiveVolume(audio->m_audioEventRTS), pan); + AIL_set_stream_volume_pan(audio->m_stream, getEffectiveVolume(audio->m_audioEventRTS.Peek()), pan); } } @@ -1438,7 +1451,7 @@ Bool MilesAudioManager::isCurrentlyPlaying( AudioHandle handle ) AudioRequest *req = nullptr; for (ait = m_audioRequests.begin(); ait != m_audioRequests.end(); ++ait) { req = *ait; - if (req->m_usePendingEvent && req->m_pendingEvent->getPlayingHandle() == handle) { + if (req->m_pendingEvent && req->m_pendingEvent->getPlayingHandle() == handle) { return true; } } @@ -1478,7 +1491,7 @@ void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt handle, UnsignedInt 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); + playing->m_file = playSample(playing->m_audioEventRTS.Peek(), 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. @@ -1487,7 +1500,7 @@ void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt handle, UnsignedInt } } 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); + playing->m_file = playSample3D(playing->m_audioEventRTS.Peek(), 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. @@ -1499,7 +1512,7 @@ void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt handle, UnsignedInt if (playing->m_type == PAT_Stream) { if (playing->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_Music) { - playStream(playing->m_audioEventRTS, playing->m_stream); + playStream(playing->m_audioEventRTS.Peek(), playing->m_stream); return; } } @@ -1795,13 +1808,10 @@ Bool MilesAudioManager::doesViolateLimit( AudioEventRTS *event ) const std::list::const_iterator arIt; for (arIt = m_audioRequests.begin(); arIt != m_audioRequests.end(); ++arIt) { AudioRequest *req = (*arIt); - if( req->m_usePendingEvent ) + if( req->m_pendingEvent && req->m_pendingEvent->getEventName() == event->getEventName() ) { - if( req->m_pendingEvent->getEventName() == event->getEventName() ) - { - totalRequestCount++; - totalCount++; - } + totalRequestCount++; + totalCount++; } } @@ -1903,7 +1913,7 @@ AudioEventRTS* MilesAudioManager::findLowestPrioritySound( AudioEventRTS *event //3D for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) { - AudioEventRTS *itEvent = (*it)->m_audioEventRTS; + AudioEventRTS *itEvent = (*it)->m_audioEventRTS.Peek(); AudioPriority itPriority = itEvent->getAudioEventInfo()->m_priority; if( itPriority < priority ) { @@ -1924,7 +1934,7 @@ AudioEventRTS* MilesAudioManager::findLowestPrioritySound( AudioEventRTS *event //2D for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) { - AudioEventRTS *itEvent = (*it)->m_audioEventRTS; + AudioEventRTS *itEvent = (*it)->m_audioEventRTS.Peek(); AudioPriority itPriority = itEvent->getAudioEventInfo()->m_priority; if( itPriority < priority ) { @@ -1991,8 +2001,7 @@ Bool MilesAudioManager::killLowestPrioritySoundImmediately( AudioEventRTS *event for( it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it ) { PlayingAudio *playing = (*it); - - if( playing->m_audioEventRTS && playing->m_audioEventRTS == lowestPriorityEvent ) + if( playing->m_audioEventRTS.Peek() == lowestPriorityEvent ) { //Release this 3D sound channel immediately because we are going to play another sound in it's place. stopPlayingAudio(playing); @@ -2005,8 +2014,7 @@ Bool MilesAudioManager::killLowestPrioritySoundImmediately( AudioEventRTS *event for( it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it ) { PlayingAudio *playing = (*it); - - if( playing->m_audioEventRTS && playing->m_audioEventRTS == lowestPriorityEvent ) + if( playing->m_audioEventRTS.Peek() == lowestPriorityEvent ) { //Release this sound channel immediately because we are going to play another sound in it's place. stopPlayingAudio(playing); @@ -2028,30 +2036,36 @@ void MilesAudioManager::adjustVolumeOfPlayingAudio(AsciiString eventName, Real n PlayingAudio *playing = nullptr; for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { playing = *it; - if (playing->m_audioEventRTS->getEventName() == eventName) { + AudioEventRTS *itEvent = playing->m_audioEventRTS.Peek(); + + if (itEvent->getEventName() == eventName) { DEBUG_ASSERTCRASH(playing->m_sample, ("Sample is not expected to be null")); - playing->m_audioEventRTS->setVolume(newVolume); + itEvent->setVolume(newVolume); AIL_sample_volume_pan(playing->m_sample, nullptr, &pan); - AIL_set_sample_volume_pan(playing->m_sample, getEffectiveVolume(playing->m_audioEventRTS), pan); + AIL_set_sample_volume_pan(playing->m_sample, getEffectiveVolume(itEvent), pan); } } for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { playing = *it; - if (playing->m_audioEventRTS->getEventName() == eventName) { + AudioEventRTS *itEvent = playing->m_audioEventRTS.Peek(); + + if (itEvent->getEventName() == eventName) { DEBUG_ASSERTCRASH(playing->m_3DSample, ("3D Sample is not expected to be null")); - playing->m_audioEventRTS->setVolume(newVolume); - AIL_set_3D_sample_volume(playing->m_3DSample, getEffectiveVolume(playing->m_audioEventRTS)); + itEvent->setVolume(newVolume); + AIL_set_3D_sample_volume(playing->m_3DSample, getEffectiveVolume(itEvent)); } } for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { playing = *it; - if (playing->m_audioEventRTS->getEventName() == eventName) { + AudioEventRTS *itEvent = playing->m_audioEventRTS.Peek(); + + if (itEvent->getEventName() == eventName) { DEBUG_ASSERTCRASH(playing->m_stream, ("Stream is not expected to be null")); - playing->m_audioEventRTS->setVolume(newVolume); + itEvent->setVolume(newVolume); AIL_stream_volume_pan(playing->m_stream, nullptr, &pan); - AIL_set_stream_volume_pan(playing->m_stream, getEffectiveVolume(playing->m_audioEventRTS), pan); + AIL_set_stream_volume_pan(playing->m_stream, getEffectiveVolume(itEvent), pan); } } } @@ -2158,6 +2172,11 @@ void MilesAudioManager::processPlayingList() for (it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { playing = (*it); + if (playing->m_rerequestOnNextUpdate) { + rerequestPlayingAudio(playing); + playing->m_rerequestOnNextUpdate = false; + } + if (playing->m_status == PS_Stopping) { stopPlayingAudio(playing); continue; @@ -2176,6 +2195,11 @@ void MilesAudioManager::processPlayingList() for (it = m_playing3DSounds.begin(); it != m_playing3DSounds.end(); ++it) { playing = (*it); + if (playing->m_rerequestOnNextUpdate) { + rerequestPlayingAudio(playing); + playing->m_rerequestOnNextUpdate = false; + } + if (playing->m_status == PS_Stopping) { stopPlayingAudio(playing); continue; @@ -2190,7 +2214,7 @@ void MilesAudioManager::processPlayingList() adjustPlayingVolume(playing); } - const Coord3D *pos = getCurrentPositionFromEvent(playing->m_audioEventRTS); + const Coord3D *pos = getCurrentPositionFromEvent(playing->m_audioEventRTS.Peek()); if (pos) { if( playing->m_audioEventRTS->isDead() ) @@ -2199,7 +2223,7 @@ void MilesAudioManager::processPlayingList() } else { - Real volForConsideration = getEffectiveVolume(playing->m_audioEventRTS); + Real volForConsideration = getEffectiveVolume(playing->m_audioEventRTS.Peek()); 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; @@ -2226,6 +2250,11 @@ void MilesAudioManager::processPlayingList() for (it = m_playingStreams.begin(); it != m_playingStreams.end(); ++it) { playing = (*it); + if (playing->m_rerequestOnNextUpdate) { + rerequestPlayingAudio(playing); + playing->m_rerequestOnNextUpdate = false; + } + if (playing->m_status == PS_Stopping) { stopPlayingAudio(playing); continue; @@ -2332,7 +2361,7 @@ void MilesAudioManager::processFadingList() } ++playing->m_framesFaded; - Real volume = getEffectiveVolume(playing->m_audioEventRTS); + Real volume = getEffectiveVolume(playing->m_audioEventRTS.Peek()); volume *= (1.0f - 1.0f * playing->m_framesFaded / getAudioSettings()->m_fadeAudioFrames); switch(playing->m_type) @@ -2366,7 +2395,7 @@ void MilesAudioManager::processFadingList() //------------------------------------------------------------------------------------------------- Bool MilesAudioManager::shouldProcessRequestThisFrame( AudioRequest *req ) const { - if (!req->m_usePendingEvent) { + if (req->m_pendingEvent == nullptr) { return true; } @@ -2380,7 +2409,7 @@ Bool MilesAudioManager::shouldProcessRequestThisFrame( AudioRequest *req ) const //------------------------------------------------------------------------------------------------- void MilesAudioManager::adjustRequest( AudioRequest *req ) { - if (!req->m_usePendingEvent) { + if (req->m_pendingEvent == nullptr) { return; } @@ -2391,14 +2420,14 @@ void MilesAudioManager::adjustRequest( AudioRequest *req ) //------------------------------------------------------------------------------------------------- Bool MilesAudioManager::checkForSample( AudioRequest *req ) { - if (!req->m_usePendingEvent) { + if (req->m_pendingEvent == nullptr) { return true; } if ( req->m_pendingEvent->getAudioEventInfo() == nullptr ) { // Fill in event info - getInfoForAudioEvent( req->m_pendingEvent ); + getInfoForAudioEvent( req->m_pendingEvent.Peek() ); } if (req->m_pendingEvent->getAudioEventInfo()->m_type != AT_SoundEffect) @@ -2406,7 +2435,7 @@ Bool MilesAudioManager::checkForSample( AudioRequest *req ) return true; } - return m_sound->canPlayNow(req->m_pendingEvent); + return m_sound->canPlayNow(req->m_pendingEvent.Peek()); } //------------------------------------------------------------------------------------------------- @@ -2611,26 +2640,20 @@ Bool MilesAudioManager::startNextLoop( PlayingAudio *looping ) } 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_rerequestOnNextUpdate = true; InterlockedCompareExchange(reinterpret_cast(&looping->m_status), PS_Stopping, PS_Playing); - - AudioRequest *req = allocateAudioRequest(true); - req->m_pendingEvent = looping->m_audioEventRTS; - req->m_requiresCheckForSample = true; - appendAudioRequest(req); return true; } + // generate a new filename, and test to see whether we can play with it now + looping->m_audioEventRTS->generateFilename(); + if (looping->m_type == PAT_3DSample) { - looping->m_file = playSample3D(looping->m_audioEventRTS, looping->m_3DSample); + looping->m_file = playSample3D(looping->m_audioEventRTS.Peek(), looping->m_3DSample); } else { - looping->m_file = playSample(looping->m_audioEventRTS, looping->m_sample); + looping->m_file = playSample(looping->m_audioEventRTS.Peek(), looping->m_sample); } return looping->m_file != nullptr; @@ -2823,9 +2846,10 @@ void *MilesAudioManager::getHandleForBink() { if (m_binkHandle == nullptr) { PlayingAudio *aud = allocatePlayingAudio(); - aud->m_audioEventRTS = NEW AudioEventRTS("BinkHandle"); // poolify - getInfoForAudioEvent(aud->m_audioEventRTS); - aud->m_sample = getFirst2DSample(aud->m_audioEventRTS); + DynamicAudioEventRTS *newEvent = newInstance(DynamicAudioEventRTS)("BinkHandle"); + aud->m_audioEventRTS = RefCountPtr::Create_NoAddRef(newEvent); + getInfoForAudioEvent(aud->m_audioEventRTS.Peek()); + aud->m_sample = getFirst2DSample(aud->m_audioEventRTS.Peek()); aud->m_type = PAT_Sample; if (!aud->m_sample) { diff --git a/Core/Libraries/Source/WWVegas/WWLib/WWCommon.h b/Core/Libraries/Source/WWVegas/WWLib/WWCommon.h index b97ec772535..f4fe3f56e3b 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/WWCommon.h +++ b/Core/Libraries/Source/WWVegas/WWLib/WWCommon.h @@ -18,6 +18,7 @@ #pragma once +#include "ref_ptr.h" #include "refcount.h" #include "STLUtils.h" #include "stringex.h" diff --git a/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h b/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h index 4318d1811c0..f9a57c7c1ef 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h +++ b/Core/Libraries/Source/WWVegas/WWLib/ref_ptr.h @@ -37,7 +37,7 @@ #pragma once #include "always.h" -#include "wwdebug.h" +#include "WWDebug/wwdebug.h" /* RefCountPtr is a smart pointer for reference counted objects. diff --git a/Core/Libraries/Source/WWVegas/WWLib/refcount.cpp b/Core/Libraries/Source/WWVegas/WWLib/refcount.cpp index 9801ba4f402..06b6eb26383 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/refcount.cpp +++ b/Core/Libraries/Source/WWVegas/WWLib/refcount.cpp @@ -40,6 +40,7 @@ #include "refcount.h" +#include "win.h" // TheSuperHackers @build feliwir 17/04/2025 include __debugbreak macros #include @@ -204,3 +205,22 @@ void RefCountClass::Dec_Total_Refs(const RefCountClass * obj) } #endif // RTS_DEBUG + +int RefCountMTClass::Add_Ref() const +{ + static_assert(sizeof(int) == sizeof(long), "int and long must be same size"); + return (int)InterlockedIncrement(reinterpret_cast(&NumRefs)); +} + +int RefCountMTClass::Release_Ref() const +{ + static_assert(sizeof(int) == sizeof(long), "int and long must be same size"); + const int ref = (int)InterlockedDecrement(reinterpret_cast(&NumRefs)); + WWASSERT(ref >= 0); + if (ref == 0) + { + const_cast(this)->Delete_This(); + } + + return ref; +} diff --git a/Core/Libraries/Source/WWVegas/WWLib/refcount.h b/Core/Libraries/Source/WWVegas/WWLib/refcount.h index d1522853043..084ab423d76 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/refcount.h +++ b/Core/Libraries/Source/WWVegas/WWLib/refcount.h @@ -243,6 +243,72 @@ class RefCountClass }; +/* +** Note that Add_Ref and Release_Ref are always const, because copying, destroying and reference +** counting const objects is meant to work. +*/ +class RefCountMTClass +{ +public: + + RefCountMTClass() + : NumRefs(1) + { + } + + /* + ** The reference counter value cannot be copied. + */ + RefCountMTClass(const RefCountMTClass &) + : NumRefs(1) + { + } + + RefCountMTClass& operator=(const RefCountMTClass &) { return *this; } + + /* + ** Add_Ref, call this function if you are going to keep a pointer + ** to this object. + */ + int Add_Ref() const; + + /* + ** Release_Ref, call this function when you no longer need the pointer + ** to this object. + */ + int Release_Ref() const; + + /* + ** Check the number of references to this object. Can be outdated at the time of evaluation. + */ + int Num_Refs() const { return NumRefs; } + + /* + ** Delete_This - this function will be called when the object is being + ** destroyed as a result of its last reference being released. Its + ** job is to actually destroy the object. + */ + virtual void Delete_This() { delete this; } + +protected: + + /* + ** Destructor, user should not have access to this... + */ + virtual ~RefCountMTClass() + { + WWASSERT(NumRefs == 0); + } + +private: + + /* + ** Current reference count of this object + */ + mutable volatile int NumRefs; +}; + + /* ** This template class is meant to be used as a class member for compact reference counter placements. ** A 1 byte reference counter can be alright if the counter is not reaching the value limits. diff --git a/Core/Libraries/Source/WWVegas/WWLib/systimer.h b/Core/Libraries/Source/WWVegas/WWLib/systimer.h index 8313aa49de8..bfa3ad9862c 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/systimer.h +++ b/Core/Libraries/Source/WWVegas/WWLib/systimer.h @@ -40,8 +40,7 @@ #include "always.h" #ifdef _WIN32 -#include -#include "mmsys.h" +#include "win.h" #define TIMEGETTIME SystemTime.Get #define MS_TIMER_SECOND 1000 diff --git a/Core/Libraries/Source/WWVegas/WWLib/win.h b/Core/Libraries/Source/WWVegas/WWLib/win.h index 70ef32dc396..d6eb80ae1c0 100644 --- a/Core/Libraries/Source/WWVegas/WWLib/win.h +++ b/Core/Libraries/Source/WWVegas/WWLib/win.h @@ -58,15 +58,15 @@ #endif #include -//#include -//#include -//#include -//#include #if (_MSC_VER >= 1200) #pragma warning(pop) #endif +#include + +#include + extern HINSTANCE ProgramInstance; extern HWND MainWindow; extern bool GameInFocus; diff --git a/Dependencies/Utility/Utility/interlocked_adapter.h b/Dependencies/Utility/Utility/interlocked_adapter.h index 45da6a2f9cb..0f4e6f3591c 100644 --- a/Dependencies/Utility/Utility/interlocked_adapter.h +++ b/Dependencies/Utility/Utility/interlocked_adapter.h @@ -25,4 +25,14 @@ inline long InterlockedCompareExchange(long volatile *Destination, long Exchange return (long)InterlockedCompareExchange((PVOID*)Destination, (PVOID)Exchange, (PVOID)Comparand); } +inline long InterlockedIncrement(long volatile *Addend) +{ + return (long)InterlockedIncrement((long*)Addend); +} + +inline long InterlockedDecrement(long volatile *Addend) +{ + return (long)InterlockedDecrement((long*)Addend); +} + #endif diff --git a/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h b/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h index af1efaa4f10..c35f2b579aa 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h @@ -140,26 +140,18 @@ enum ThingTemplateAudioType CPP_11(: Int) class AudioArray { public: - DynamicAudioEventRTS* m_audio[TTAUDIO_COUNT]; + RefCountPtr m_audio[TTAUDIO_COUNT]; - AudioArray() - { - for (Int i = 0; i < TTAUDIO_COUNT; ++i) - m_audio[i] = nullptr; - } + AudioArray() {} - ~AudioArray() - { - for (Int i = 0; i < TTAUDIO_COUNT; ++i) - deleteInstance(m_audio[i]); - } + ~AudioArray() {} AudioArray(const AudioArray& that) { for (Int i = 0; i < TTAUDIO_COUNT; ++i) { if (that.m_audio[i]) - m_audio[i] = newInstance(DynamicAudioEventRTS)(*that.m_audio[i]); + m_audio[i] = RefCountPtr::Create_NoAddRef(newInstance(DynamicAudioEventRTS)(*that.m_audio[i])); else m_audio[i] = nullptr; } @@ -176,7 +168,7 @@ class AudioArray if (m_audio[i]) *m_audio[i] = *that.m_audio[i]; else - m_audio[i] = newInstance(DynamicAudioEventRTS)(*that.m_audio[i]); + m_audio[i] = RefCountPtr::Create_NoAddRef(newInstance(DynamicAudioEventRTS)(*that.m_audio[i])); } else { @@ -633,7 +625,7 @@ class ThingTemplate : public Overridable Real getBuildTime() const { return m_buildTime; } const PerUnitSoundMap* getAllPerUnitSounds() const { return &m_perUnitSounds; } void validateAudio(); - const AudioEventRTS* getAudio(ThingTemplateAudioType t) const { return m_audioarray.m_audio[t] ? &m_audioarray.m_audio[t]->m_event : &s_audioEventNoSound; } + const AudioEventRTS* getAudio(ThingTemplateAudioType t) const { return m_audioarray.m_audio[t] ? m_audioarray.m_audio[t].Peek() : &s_audioEventNoSound; } Bool hasAudio(ThingTemplateAudioType t) const { return m_audioarray.m_audio[t] != nullptr; } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h index e0e4707f93c..fbe837c39a9 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h @@ -580,7 +580,7 @@ class Drawable : public Thing, // Stuff for overriding ambient sound const AudioEventInfo * getBaseSoundAmbientInfo() const; //< Possible starting point if only some parameters are customized void enableAmbientSoundFromScript( Bool enable ); - const AudioEventRTS * getAmbientSound() const { return m_ambientSound == nullptr ? nullptr : &m_ambientSound->m_event; } + const AudioEventRTS * getAmbientSound() const { return m_ambientSound == nullptr ? nullptr : m_ambientSound.Peek(); } void setCustomSoundAmbientOff(); //< Kill the ambient sound void setCustomSoundAmbientInfo( DynamicAudioEventInfo * customAmbientInfo ); //< Set ambient sound. void clearCustomSoundAmbient() { clearCustomSoundAmbient( true ); } //< Return to using defaults @@ -700,7 +700,7 @@ class Drawable : public Thing, PhysicsXformInfo* m_physicsXform; - DynamicAudioEventRTS* m_ambientSound; ///< sound module for ambient sound (lazily allocated) + RefCountPtr m_ambientSound; ///< sound module for ambient sound (lazily allocated) Module** m_modules[NUM_DRAWABLE_MODULE_TYPES]; diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h index 3b46117adee..4023fa13a7b 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h @@ -34,7 +34,6 @@ #include "Common/GameType.h" #include "GameLogic/Damage.h" #include "Common/STLTypedefs.h" -#include "ref_ptr.h" class AIGroup; class AttackPriorityInfo; diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/PhysicsUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/PhysicsUpdate.h index ad5645896d2..710ac222a07 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/PhysicsUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/PhysicsUpdate.h @@ -191,7 +191,7 @@ class PhysicsBehavior : public UpdateModule, void setExtraFriction(Real b) { m_extraFriction = b; } void setBounceSound(const AudioEventRTS* bounceSound); - const AudioEventRTS* getBounceSound() { return m_bounceSound ? &m_bounceSound->m_event : TheAudio->getValidSilentAudioEvent(); } + const AudioEventRTS* getBounceSound() { return m_bounceSound ? m_bounceSound.Peek() : TheAudio->getValidSilentAudioEvent(); } /** Reset all values (vel, accel, etc) to starting values. @@ -263,7 +263,7 @@ class PhysicsBehavior : public UpdateModule, Real m_yawRate; ///< rate of rotation around up vector Real m_rollRate; ///< rate of rotation around forward vector Real m_pitchRate; ///< rate or rotation around side vector - DynamicAudioEventRTS* m_bounceSound; ///< The sound for when this thing bounces, or nullptr + RefCountPtr m_bounceSound; ///< The sound for when this thing bounces, or nullptr Coord3D m_accel; ///< current acceleration Coord3D m_prevAccel; ///< last frame's acceleration Coord3D m_vel; ///< current velocity diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Object.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Object.h index 29d391b81a3..31a74e9d3d3 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Object.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Object.h @@ -29,7 +29,6 @@ #pragma once #include "Lib/BaseType.h" -#include "ref_ptr.h" #include "Common/Geometry.h" #include "Common/Snapshot.h" diff --git a/GeneralsMD/Code/GameEngine/Source/Common/StateMachine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/StateMachine.cpp index 20c87e80fad..655fb036d87 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/StateMachine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/StateMachine.cpp @@ -37,8 +37,6 @@ #include "GameLogic/GameLogic.h" #include "GameLogic/Object.h" -#include "ref_ptr.h" - //------------------------------------------------------------------------------ Performance Timers //#include "Common/PerfMetrics.h" diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp index da55dbbf2d4..a3d96ba34bb 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp @@ -545,8 +545,7 @@ Drawable::~Drawable() stopAmbientSound(); - deleteInstance(m_ambientSound); - m_ambientSound = nullptr; + m_ambientSound.Clear(); clearCustomSoundAmbient( false ); @@ -1294,15 +1293,15 @@ void Drawable::updateDrawable() // End result: a hack of testing the looping bit and only restarting the sound if the looping // bit is on and the loop count is 0 (loop forever). if( m_ambientSound && m_ambientSoundEnabled && m_ambientSoundEnabledFromScript && - !m_ambientSound->m_event.getEventName().isEmpty() && !m_ambientSound->m_event.isCurrentlyPlaying() ) + !m_ambientSound->getEventName().isEmpty() && !m_ambientSound->isCurrentlyPlaying() ) { - const AudioEventInfo * eventInfo = m_ambientSound->m_event.getAudioEventInfo(); + const AudioEventInfo * eventInfo = m_ambientSound->getAudioEventInfo(); if ( eventInfo == nullptr && TheAudio != nullptr ) { // We'll need this in a second anyway so cache it - TheAudio->getInfoForAudioEvent( &m_ambientSound->m_event ); - eventInfo = m_ambientSound->m_event.getAudioEventInfo(); + TheAudio->getInfoForAudioEvent( m_ambientSound.Peek() ); + eventInfo = m_ambientSound->getAudioEventInfo(); } if ( eventInfo == nullptr || ( eventInfo->isPermanentSound() ) ) @@ -1321,7 +1320,7 @@ void Drawable::onLevelStart() // actually start the sound if the constructor is called during level load. if( m_ambientSoundEnabled && m_ambientSoundEnabledFromScript && ( m_ambientSound == nullptr || - ( !m_ambientSound->m_event.getEventName().isEmpty() && !m_ambientSound->m_event.isCurrentlyPlaying() ) ) ) + ( !m_ambientSound->getEventName().isEmpty() && !m_ambientSound->isCurrentlyPlaying() ) ) ) { // Unlike the check in the update() function, we want to do this for looping & one-shot sounds equally startAmbientSound(); @@ -4075,7 +4074,7 @@ void Drawable::setID( DrawableID id ) { TheGameClient->addDrawableToLookupTable( this ); if (m_ambientSound) - m_ambientSound->m_event.setDrawableID(m_id); + m_ambientSound->setDrawableID(m_id); } } @@ -4383,7 +4382,7 @@ void Drawable::clearCustomSoundAmbient( bool restartSound ) if ( m_ambientSound ) { // Make sure sound doesn't keep a reference to the deleted pointer - m_ambientSound->m_event.setAudioEventInfo( nullptr ); + m_ambientSound->setAudioEventInfo( nullptr ); } // Stop using old info @@ -4413,11 +4412,11 @@ void Drawable::startAmbientSound(BodyDamageType dt, TimeOfDay tod, Bool onlyIfPe if ( m_customSoundAmbientInfo != getNoSoundMarker() ) { if (m_ambientSound == nullptr) - m_ambientSound = newInstance(DynamicAudioEventRTS); + m_ambientSound = RefCountPtr::Create_NoAddRef(newInstance(DynamicAudioEventRTS)); // Make sure m_event will accept the custom info - m_ambientSound->m_event.setEventName( m_customSoundAmbientInfo->m_audioName ); - m_ambientSound->m_event.setAudioEventInfo( m_customSoundAmbientInfo ); + m_ambientSound->setEventName( m_customSoundAmbientInfo->m_audioName ); + m_ambientSound->setAudioEventInfo( m_customSoundAmbientInfo ); trySound = TRUE; } } @@ -4429,9 +4428,9 @@ void Drawable::startAmbientSound(BodyDamageType dt, TimeOfDay tod, Bool onlyIfPe if( audio.getEventName().isNotEmpty() ) { if (m_ambientSound == nullptr) - m_ambientSound = newInstance(DynamicAudioEventRTS); + m_ambientSound = RefCountPtr::Create_NoAddRef(newInstance(DynamicAudioEventRTS)); - (m_ambientSound->m_event) = audio; + *m_ambientSound = audio; trySound = TRUE; } else if( dt != BODY_PRISTINE && dt != BODY_RUBBLE ) @@ -4443,8 +4442,8 @@ void Drawable::startAmbientSound(BodyDamageType dt, TimeOfDay tod, Bool onlyIfPe if( pristineAudio.getEventName().isNotEmpty() ) { if (m_ambientSound == nullptr) - m_ambientSound = newInstance(DynamicAudioEventRTS); - (m_ambientSound->m_event) = pristineAudio; + m_ambientSound = RefCountPtr::Create_NoAddRef(newInstance(DynamicAudioEventRTS)); + *m_ambientSound = pristineAudio; trySound = TRUE; } } @@ -4453,7 +4452,7 @@ void Drawable::startAmbientSound(BodyDamageType dt, TimeOfDay tod, Bool onlyIfPe if( trySound && m_ambientSound ) { - const AudioEventInfo *info = m_ambientSound->m_event.getAudioEventInfo(); + const AudioEventInfo *info = m_ambientSound->getAudioEventInfo(); if( info ) { if ( !onlyIfPermanent || info->isPermanentSound() ) @@ -4461,9 +4460,9 @@ void Drawable::startAmbientSound(BodyDamageType dt, TimeOfDay tod, Bool onlyIfPe if( BitIsSet( info->m_type, ST_GLOBAL) || info->m_priority == AP_CRITICAL ) { //Play it anyways. - m_ambientSound->m_event.setDrawableID(getID()); - m_ambientSound->m_event.setTimeOfDay(tod); - m_ambientSound->m_event.setPlayingHandle(TheAudio->addAudioEvent( &m_ambientSound->m_event )); + m_ambientSound->setDrawableID(getID()); + m_ambientSound->setTimeOfDay(tod); + m_ambientSound->setPlayingHandle(TheAudio->addAudioEvent( m_ambientSound.Peek() )); } else { @@ -4473,18 +4472,17 @@ void Drawable::startAmbientSound(BodyDamageType dt, TimeOfDay tod, Bool onlyIfPe Real distSqr = vector.lengthSqr(); if( distSqr < sqr( info->m_maxDistance ) ) { - m_ambientSound->m_event.setDrawableID(getID()); - m_ambientSound->m_event.setTimeOfDay(tod); - m_ambientSound->m_event.setPlayingHandle(TheAudio->addAudioEvent( &m_ambientSound->m_event )); + m_ambientSound->setDrawableID(getID()); + m_ambientSound->setTimeOfDay(tod); + m_ambientSound->setPlayingHandle(TheAudio->addAudioEvent( m_ambientSound.Peek() )); } } } } else { - DEBUG_CRASH( ("Ambient sound %s missing! Skipping...", m_ambientSound->m_event.getEventName().str() ) ); - deleteInstance(m_ambientSound); - m_ambientSound = nullptr; + DEBUG_CRASH( ("Ambient sound %s missing! Skipping...", m_ambientSound->getEventName().str() ) ); + m_ambientSound.Clear(); } } } @@ -4515,7 +4513,7 @@ void Drawable::stopAmbientSound() { if (m_ambientSound) { - TheAudio->removeAudioEvent(m_ambientSound->m_event.getPlayingHandle()); + TheAudio->removeAudioEvent(m_ambientSound->getPlayingHandle()); } } @@ -4882,9 +4880,8 @@ void Drawable::xfer( Xfer *xfer ) //and restore it in loadPostProcess(). if( xfer->getXferMode() == XFER_LOAD && m_ambientSound ) { - TheAudio->killAudioEventImmediately( m_ambientSound->m_event.getPlayingHandle() ); - deleteInstance(m_ambientSound); - m_ambientSound = nullptr; + TheAudio->killAudioEventImmediately( m_ambientSound->getPlayingHandle() ); + m_ambientSound.Clear(); } // drawable id diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index fcef6cd591d..ab1c43c1230 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -257,8 +257,6 @@ void PhysicsBehavior::onObjectCreated() //------------------------------------------------------------------------------------------------- PhysicsBehavior::~PhysicsBehavior() { - deleteInstance(m_bounceSound); - m_bounceSound = nullptr; } //------------------------------------------------------------------------------------------------- @@ -600,14 +598,13 @@ void PhysicsBehavior::setBounceSound(const AudioEventRTS* bounceSound) if (bounceSound) { if (m_bounceSound == nullptr) - m_bounceSound = newInstance(DynamicAudioEventRTS); + m_bounceSound = RefCountPtr::Create_NoAddRef(newInstance(DynamicAudioEventRTS)); - m_bounceSound->m_event = *bounceSound; + *m_bounceSound = *bounceSound; } else { - deleteInstance(m_bounceSound); - m_bounceSound = nullptr; + m_bounceSound.Clear(); } } @@ -1115,7 +1112,7 @@ void PhysicsBehavior::doBounceSound(const Coord3D& prevPos) const Real NORMAL_MASS = 50.0f; // get the per-unit sound for the collision which was stuffed in on Object creation. - AudioEventRTS collisionSound = m_bounceSound->m_event; + AudioEventRTS collisionSound = *m_bounceSound.Peek(); //Real vel = fabs(getVelocity()->z); // can't use velocity, because it's already been updated this frame, and will be zero... (srj) diff --git a/GeneralsMD/Code/Tools/GUIEdit/Source/Dialog Procedures/TabControlProperties.cpp b/GeneralsMD/Code/Tools/GUIEdit/Source/Dialog Procedures/TabControlProperties.cpp index 97fe8fd9887..32fe97df88e 100644 --- a/GeneralsMD/Code/Tools/GUIEdit/Source/Dialog Procedures/TabControlProperties.cpp +++ b/GeneralsMD/Code/Tools/GUIEdit/Source/Dialog Procedures/TabControlProperties.cpp @@ -335,7 +335,7 @@ static LRESULT CALLBACK tabControlPropertiesCallback( HWND hWndDialog, //safeties tabData->tabCount = max( tabData->tabCount, 1 ); - tabData->tabCount = min( tabData->tabCount, NUM_TAB_PANES ); + tabData->tabCount = min( tabData->tabCount, (Int)NUM_TAB_PANES ); GadgetTabControlComputeTabRegion( tabControl ); GadgetTabControlResizeSubPanes( tabControl );