From 7d22e2e2e540563246dfd3d2ba778969ef62118f Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Fri, 13 Feb 2026 17:53:57 +0100 Subject: [PATCH 1/5] bugfix(audio): Fix particle cannon being inaudible after saveload --- .../Object/Update/ParticleUplinkCannonUpdate.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index e360f8842ff..3bdd3421e84 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -1559,4 +1559,20 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) } } + // TheSuperHackers @info stephanmeesters 13/02/2026 + // Fix issue where sound from the particle cannon is not audible after saveload + if( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || m_status == STATUS_PACKING ) + { + if( m_firingToIdleSound.getEventName().isNotEmpty() ) + { + m_firingToIdleSound.setObjectID( getObject()->getID() ); + m_firingToIdleSound.setPlayingHandle( TheAudio->addAudioEvent( &m_firingToIdleSound ) ); + } + if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID && m_annihilationSound.getEventName().isNotEmpty() ) + { + m_annihilationSound.setDrawableID( m_orbitToTargetBeamID ); + m_annihilationSound.setPlayingHandle( TheAudio->addAudioEvent( &m_annihilationSound ) ); + } + } + } From 169ce11104f32b987391f2175b63682de1048911 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:30:07 +0100 Subject: [PATCH 2/5] Reevaluate code based on table of results, add code for some more previously inaudible sounds --- .../Update/ParticleUplinkCannonUpdate.cpp | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 3bdd3421e84..04765320654 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -1559,20 +1559,36 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) } } - // TheSuperHackers @info stephanmeesters 13/02/2026 - // Fix issue where sound from the particle cannon is not audible after saveload - if( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || m_status == STATUS_PACKING ) + // TheSuperHackers @bugfix stephanmeesters 13/02/2026 + // Fix issue where particle cannon sounds are not audible after saveload. + + if( (m_status == STATUS_CHARGING || m_status == STATUS_PREPARING || m_status == STATUS_ALMOST_READY) && + m_powerupSound.getEventName().isNotEmpty() ) + { + m_powerupSound.setObjectID( getObject()->getID() ); + m_powerupSound.setPlayingHandle( TheAudio->addAudioEvent( &m_powerupSound ) ); + } + + if( (m_status == STATUS_PREPARING || m_status == STATUS_ALMOST_READY || m_status == STATUS_READY_TO_FIRE || m_status == STATUS_PREFIRE) && + m_unpackToReadySound.getEventName().isNotEmpty() ) + { + m_unpackToReadySound.setObjectID( getObject()->getID() ); + m_unpackToReadySound.setPlayingHandle( TheAudio->addAudioEvent( &m_unpackToReadySound ) ); + } + + if ( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || + (m_status == STATUS_PACKING && (m_laserStatus == LASERSTATUS_DECAYING || m_laserStatus == LASERSTATUS_DEAD)) ) { if( m_firingToIdleSound.getEventName().isNotEmpty() ) { m_firingToIdleSound.setObjectID( getObject()->getID() ); m_firingToIdleSound.setPlayingHandle( TheAudio->addAudioEvent( &m_firingToIdleSound ) ); } + if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID && m_annihilationSound.getEventName().isNotEmpty() ) { m_annihilationSound.setDrawableID( m_orbitToTargetBeamID ); m_annihilationSound.setPlayingHandle( TheAudio->addAudioEvent( &m_annihilationSound ) ); } } - } From fdbc5c85853683de67ad6a279b06cc98fea1a508 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Wed, 25 Feb 2026 21:28:48 +0100 Subject: [PATCH 3/5] Add old xfer version requirement, update comment to clarify retail compatibility fix --- .../Update/ParticleUplinkCannonUpdate.cpp | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 04765320654..9fed1856a9c 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -1557,38 +1557,37 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) DEBUG_CRASH(( "ParticleUplinkCannonUpdate::loadPostProcess - Unable to find drawable for m_orbitToTargetBeamID" )); } } - } - - // TheSuperHackers @bugfix stephanmeesters 13/02/2026 - // Fix issue where particle cannon sounds are not audible after saveload. - - if( (m_status == STATUS_CHARGING || m_status == STATUS_PREPARING || m_status == STATUS_ALMOST_READY) && - m_powerupSound.getEventName().isNotEmpty() ) - { - m_powerupSound.setObjectID( getObject()->getID() ); - m_powerupSound.setPlayingHandle( TheAudio->addAudioEvent( &m_powerupSound ) ); - } - if( (m_status == STATUS_PREPARING || m_status == STATUS_ALMOST_READY || m_status == STATUS_READY_TO_FIRE || m_status == STATUS_PREFIRE) && - m_unpackToReadySound.getEventName().isNotEmpty() ) - { - m_unpackToReadySound.setObjectID( getObject()->getID() ); - m_unpackToReadySound.setPlayingHandle( TheAudio->addAudioEvent( &m_unpackToReadySound ) ); - } + // TheSuperHackers @bugfix stephanmeesters 13/02/2026 + // For retail game compatibility, this fixes an issue where particle cannon sounds are not audible after saveload. + if( (m_status == STATUS_CHARGING || m_status == STATUS_PREPARING || m_status == STATUS_ALMOST_READY) && + m_powerupSound.getEventName().isNotEmpty() ) + { + m_powerupSound.setObjectID( getObject()->getID() ); + m_powerupSound.setPlayingHandle( TheAudio->addAudioEvent( &m_powerupSound ) ); + } - if ( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || - (m_status == STATUS_PACKING && (m_laserStatus == LASERSTATUS_DECAYING || m_laserStatus == LASERSTATUS_DEAD)) ) - { - if( m_firingToIdleSound.getEventName().isNotEmpty() ) + if( (m_status == STATUS_PREPARING || m_status == STATUS_ALMOST_READY || m_status == STATUS_READY_TO_FIRE || m_status == STATUS_PREFIRE) && + m_unpackToReadySound.getEventName().isNotEmpty() ) { - m_firingToIdleSound.setObjectID( getObject()->getID() ); - m_firingToIdleSound.setPlayingHandle( TheAudio->addAudioEvent( &m_firingToIdleSound ) ); + m_unpackToReadySound.setObjectID( getObject()->getID() ); + m_unpackToReadySound.setPlayingHandle( TheAudio->addAudioEvent( &m_unpackToReadySound ) ); } - if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID && m_annihilationSound.getEventName().isNotEmpty() ) + if ( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || + (m_status == STATUS_PACKING && (m_laserStatus == LASERSTATUS_DECAYING || m_laserStatus == LASERSTATUS_DEAD)) ) { - m_annihilationSound.setDrawableID( m_orbitToTargetBeamID ); - m_annihilationSound.setPlayingHandle( TheAudio->addAudioEvent( &m_annihilationSound ) ); + if( m_firingToIdleSound.getEventName().isNotEmpty() ) + { + m_firingToIdleSound.setObjectID( getObject()->getID() ); + m_firingToIdleSound.setPlayingHandle( TheAudio->addAudioEvent( &m_firingToIdleSound ) ); + } + + if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID && m_annihilationSound.getEventName().isNotEmpty() ) + { + m_annihilationSound.setDrawableID( m_orbitToTargetBeamID ); + m_annihilationSound.setPlayingHandle( TheAudio->addAudioEvent( &m_annihilationSound ) ); + } } } } From c3e23a7fea14379f97d829f283233f7b0b53b74d Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Wed, 25 Feb 2026 21:34:32 +0100 Subject: [PATCH 4/5] Apply suggestion from @greptile-apps[bot] Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- .../GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 9fed1856a9c..29c963f9939 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -1574,7 +1574,7 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) m_unpackToReadySound.setPlayingHandle( TheAudio->addAudioEvent( &m_unpackToReadySound ) ); } - if ( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || + if( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || (m_status == STATUS_PACKING && (m_laserStatus == LASERSTATUS_DECAYING || m_laserStatus == LASERSTATUS_DEAD)) ) { if( m_firingToIdleSound.getEventName().isNotEmpty() ) From 63f36463c9f0cc67bbc522ce50441544d0561846 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:56:49 +0100 Subject: [PATCH 5/5] Replicate to Generals --- .../Update/ParticleUplinkCannonUpdate.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index eb73cb3eb89..8f3b587e442 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -1464,6 +1464,38 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) DEBUG_CRASH(( "ParticleUplinkCannonUpdate::loadPostProcess - Unable to find drawable for m_orbitToTargetBeamID" )); } } + + // TheSuperHackers @bugfix stephanmeesters 13/02/2026 + // For retail game compatibility, this fixes an issue where particle cannon sounds are not audible after saveload. + if( (m_status == STATUS_CHARGING || m_status == STATUS_PREPARING || m_status == STATUS_ALMOST_READY) && + m_powerupSound.getEventName().isNotEmpty() ) + { + m_powerupSound.setObjectID( getObject()->getID() ); + m_powerupSound.setPlayingHandle( TheAudio->addAudioEvent( &m_powerupSound ) ); + } + + if( (m_status == STATUS_PREPARING || m_status == STATUS_ALMOST_READY || m_status == STATUS_READY_TO_FIRE || m_status == STATUS_PREFIRE) && + m_unpackToReadySound.getEventName().isNotEmpty() ) + { + m_unpackToReadySound.setObjectID( getObject()->getID() ); + m_unpackToReadySound.setPlayingHandle( TheAudio->addAudioEvent( &m_unpackToReadySound ) ); + } + + if( m_status == STATUS_FIRING || m_status == STATUS_POSTFIRE || + (m_status == STATUS_PACKING && (m_laserStatus == LASERSTATUS_DECAYING || m_laserStatus == LASERSTATUS_DEAD)) ) + { + if( m_firingToIdleSound.getEventName().isNotEmpty() ) + { + m_firingToIdleSound.setObjectID( getObject()->getID() ); + m_firingToIdleSound.setPlayingHandle( TheAudio->addAudioEvent( &m_firingToIdleSound ) ); + } + + if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID && m_annihilationSound.getEventName().isNotEmpty() ) + { + m_annihilationSound.setDrawableID( m_orbitToTargetBeamID ); + m_annihilationSound.setPlayingHandle( TheAudio->addAudioEvent( &m_annihilationSound ) ); + } + } } }