From 6ebbf1288dc6ca5ef6b42d38c4191c2359fd3b0c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 4 Apr 2021 13:01:32 +0200 Subject: [PATCH] - Duke/RR: Don't delete master switch sprites. The sound system may play sounds on them after their deletion - this resulted in undefined behavior. To ensure properly defined behavior the sprite needs to be retained at least as long as the sound controller may still need it - which cannot be reliably determined so it has to be kept around forever. This would be easier if the sound controller code had proper start and stop events instead of inferring what to do from secondary information. Fixes #288. --- source/games/duke/src/actors.cpp | 9 +++++++-- source/games/duke/src/constants.h | 1 + source/games/duke/src/sounds.cpp | 4 ---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index a1c737886..04d9e311e 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -1002,7 +1002,7 @@ void movemasterswitch(DDukeActor *actor, int spectype1, int spectype2) break; } } - else if (sj->statnum == 6) + else if (sj->statnum == STAT_STANDABLE) { if (sj->picnum == spectype1 || sj->picnum == spectype2) // SEENINE and OOZFILTER { @@ -1010,7 +1010,12 @@ void movemasterswitch(DDukeActor *actor, int spectype1, int spectype2) } } } - deletesprite(actor); + // we cannot delete this because it may be used as a sound source. + // This originally depended on undefined behavior as the deleted sprite was still used for the sound + // with no checking if it got reused in the mean time. + spri->picnum = 0; // give it a picnum without any behavior attached, just in case + spri->cstat |= CSTAT_SPRITE_INVISIBLE; + changespritestat(actor->GetIndex(), STAT_REMOVED); } } } diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 9251b1042..d88db1693 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -256,6 +256,7 @@ enum STAT_DESTRUCT = 100, STAT_BOWLING = 105, + STAT_REMOVED = MAXSTATUS-2, STAT_NETALLOC = MAXSTATUS-1 }; diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index b4066e57d..79970b348 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -445,10 +445,6 @@ void GameInterface::UpdateSounds(void) int S_PlaySound3D(int sndnum, DDukeActor* actor, const vec3_t* pos, int channel, EChanFlags flags) { - if (sndnum == GENERIC_AMBIENCE1 || sndnum == DUMPSTER_MOVE) - { - int a = 0; - } auto const pl = &ps[myconnectindex]; if (!soundEngine->isValidSoundId(sndnum+1) || !SoundEnabled() || actor == nullptr || !playrunning() || (pl->timebeforeexit > 0 && pl->timebeforeexit <= REALGAMETICSPERSEC * 3)) return -1;