- 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.
This commit is contained in:
Christoph Oelckers 2021-04-04 13:01:32 +02:00
parent 97a0cb2a10
commit 6ebbf1288d
3 changed files with 8 additions and 6 deletions

View file

@ -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);
}
}
}

View file

@ -256,6 +256,7 @@ enum
STAT_DESTRUCT = 100,
STAT_BOWLING = 105,
STAT_REMOVED = MAXSTATUS-2,
STAT_NETALLOC = MAXSTATUS-1
};

View file

@ -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;