mirror of
https://github.com/ZDoom/Raze.git
synced 2025-06-01 17:52:13 +00:00
- SW/Exhumed fixed sound relinking on actor destruction.
This still passed the sprites instead of the actors. Moved the relinking code to DCoreActor::Destroy because it is the same for all games. Also did a little bit of sound cleanup to ensure the sound backend does not hold stale actor pointers.
This commit is contained in:
parent
7c5080f654
commit
d1f088a858
8 changed files with 66 additions and 57 deletions
|
@ -35,6 +35,7 @@
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include "coreactor.h"
|
#include "coreactor.h"
|
||||||
#include "gamefuncs.h"
|
#include "gamefuncs.h"
|
||||||
|
#include "raze_sound.h"
|
||||||
|
|
||||||
// Doubly linked ring list of Actors
|
// Doubly linked ring list of Actors
|
||||||
|
|
||||||
|
@ -367,6 +368,21 @@ DCoreActor* InsertActor(PClass* type, sectortype* sector, int stat, bool tail)
|
||||||
|
|
||||||
void DCoreActor::OnDestroy()
|
void DCoreActor::OnDestroy()
|
||||||
{
|
{
|
||||||
|
FVector3 pos = GetSoundPos(&spr.pos);
|
||||||
|
soundEngine->RelinkSound(SOURCE_Actor, this, nullptr, &pos);
|
||||||
|
|
||||||
|
// also scan all other sounds if they have this actor as source. If so, null the source and stop looped sounds.
|
||||||
|
soundEngine->EnumerateChannels([=](FSoundChan* chan)
|
||||||
|
{
|
||||||
|
if (chan->Source == this)
|
||||||
|
{
|
||||||
|
if (chan->ChanFlags & CHANF_LOOP) soundEngine->StopChannel(chan);
|
||||||
|
else chan->Source = nullptr;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
if(link_stat == INT_MAX) return;
|
if(link_stat == INT_MAX) return;
|
||||||
|
|
||||||
int stat = link_stat;
|
int stat = link_stat;
|
||||||
|
|
|
@ -216,50 +216,61 @@ void S_SerializeSounds(FSerializer& arc)
|
||||||
{
|
{
|
||||||
FSoundChan* chan;
|
FSoundChan* chan;
|
||||||
|
|
||||||
GSnd->Sync(true);
|
GSnd->Sync(true);
|
||||||
|
|
||||||
if (arc.isWriting())
|
if (arc.isWriting())
|
||||||
{
|
|
||||||
// Count channels and accumulate them so we can store them in
|
|
||||||
// reverse order. That way, they will be in the same order when
|
|
||||||
// reloaded later as they are now.
|
|
||||||
TArray<FSoundChan*> chans = soundEngine->AllActiveChannels();
|
|
||||||
|
|
||||||
if (chans.Size() > 0 && arc.BeginArray("sounds"))
|
|
||||||
{
|
{
|
||||||
for (unsigned int i = chans.Size(); i-- != 0; )
|
// Count channels and accumulate them so we can store them in
|
||||||
{
|
// reverse order. That way, they will be in the same order when
|
||||||
// Replace start time with sample position.
|
// reloaded later as they are now.
|
||||||
uint64_t start = chans[i]->StartTime;
|
TArray<FSoundChan*> chans = soundEngine->AllActiveChannels();
|
||||||
chans[i]->StartTime = GSnd ? GSnd->GetPosition(chans[i]) : 0;
|
|
||||||
arc(nullptr, *chans[i]);
|
|
||||||
chans[i]->StartTime = start;
|
|
||||||
}
|
|
||||||
arc.EndArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned int count;
|
|
||||||
|
|
||||||
soundEngine->StopAllChannels();
|
if (chans.Size() > 0 && arc.BeginArray("sounds"))
|
||||||
if (arc.BeginArray("sounds"))
|
|
||||||
{
|
|
||||||
count = arc.ArraySize();
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
|
||||||
{
|
{
|
||||||
chan = (FSoundChan*)soundEngine->GetChannel(nullptr);
|
for (unsigned int i = chans.Size(); i-- != 0; )
|
||||||
arc(nullptr, *chan);
|
{
|
||||||
// Sounds always start out evicted when restored from a save.
|
// Replace start time with sample position.
|
||||||
chan->ChanFlags |= CHANF_EVICTED | CHANF_ABSTIME;
|
uint64_t start = chans[i]->StartTime;
|
||||||
|
chans[i]->StartTime = GSnd ? GSnd->GetPosition(chans[i]) : 0;
|
||||||
|
arc(nullptr, *chans[i]);
|
||||||
|
chans[i]->StartTime = start;
|
||||||
|
}
|
||||||
|
arc.EndArray();
|
||||||
}
|
}
|
||||||
arc.EndArray();
|
|
||||||
}
|
}
|
||||||
// Add a small delay so that eviction only runs once the game is up and runnnig.
|
else
|
||||||
soundEngine->SetRestartTime(I_GetTime() + 2);
|
{
|
||||||
}
|
unsigned int count;
|
||||||
GSnd->Sync(false);
|
|
||||||
GSnd->UpdateSounds();
|
soundEngine->StopAllChannels();
|
||||||
|
if (arc.BeginArray("sounds"))
|
||||||
|
{
|
||||||
|
count = arc.ArraySize();
|
||||||
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
chan = (FSoundChan*)soundEngine->GetChannel(nullptr);
|
||||||
|
arc(nullptr, *chan);
|
||||||
|
// Sounds always start out evicted when restored from a save.
|
||||||
|
chan->ChanFlags |= CHANF_EVICTED | CHANF_ABSTIME;
|
||||||
|
}
|
||||||
|
arc.EndArray();
|
||||||
|
}
|
||||||
|
// Add a small delay so that eviction only runs once the game is up and runnnig.
|
||||||
|
soundEngine->SetRestartTime(I_GetTime() + 2);
|
||||||
|
}
|
||||||
|
// Check if there's actor sounds without an actor. This can happen if a savegame is badly timed with a freshly destroyed actor.
|
||||||
|
soundEngine->EnumerateChannels([](FSoundChan* chan)
|
||||||
|
{
|
||||||
|
auto eng = static_cast<RazeSoundEngine*>(soundEngine);
|
||||||
|
if (eng->SourceIsActor(chan) && chan->Source == nullptr)
|
||||||
|
{
|
||||||
|
eng->StopChannel(chan);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
GSnd->Sync(false);
|
||||||
|
GSnd->UpdateSounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -50,10 +50,6 @@ DBloodActor* InsertSprite(sectortype* pSector, int nStat)
|
||||||
|
|
||||||
int DeleteSprite(DBloodActor* actor)
|
int DeleteSprite(DBloodActor* actor)
|
||||||
{
|
{
|
||||||
auto sp = &actor->s();
|
|
||||||
FVector3 pos = GetSoundPos(&actor->s().pos);
|
|
||||||
soundEngine->RelinkSound(SOURCE_Actor, actor, nullptr, &pos);
|
|
||||||
|
|
||||||
#ifdef NOONE_EXTENSIONS
|
#ifdef NOONE_EXTENSIONS
|
||||||
for (auto& ctrl : gPlayerCtrl) if (ctrl.qavScene.initiator == actor) ctrl.qavScene.initiator = nullptr;
|
for (auto& ctrl : gPlayerCtrl) if (ctrl.qavScene.initiator == actor) ctrl.qavScene.initiator = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,8 +76,7 @@ void deletesprite(DDukeActor *const actor)
|
||||||
{
|
{
|
||||||
if (actor->s->picnum == MUSICANDSFX && actor->temp_data[0] == 1)
|
if (actor->s->picnum == MUSICANDSFX && actor->temp_data[0] == 1)
|
||||||
S_StopSound(actor->s->lotag, actor);
|
S_StopSound(actor->s->lotag, actor);
|
||||||
else
|
|
||||||
S_RelinkActorSound(actor, nullptr);
|
|
||||||
actor->Destroy();
|
actor->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -553,12 +553,6 @@ int S_PlayActorSound(int soundNum, DDukeActor* actor, int channel, EChanFlags fl
|
||||||
S_PlaySound3D(soundNum, actor, &actor->s->pos, channel, flags));
|
S_PlaySound3D(soundNum, actor, &actor->s->pos, channel, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_RelinkActorSound(DDukeActor* from, DDukeActor* to)
|
|
||||||
{
|
|
||||||
FVector3 pos = GetSoundPos(&from->s->pos);
|
|
||||||
soundEngine->RelinkSound(SOURCE_Actor, from, to, &pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S_StopSound(int sndNum, DDukeActor* actor, int channel)
|
void S_StopSound(int sndNum, DDukeActor* actor, int channel)
|
||||||
{
|
{
|
||||||
sndNum = GetReplacementSound(sndNum);
|
sndNum = GetReplacementSound(sndNum);
|
||||||
|
|
|
@ -42,7 +42,6 @@ void S_WorldTourMappingsForOldSounds();
|
||||||
int S_PlaySound(int num, int channel = CHAN_AUTO, EChanFlags flags = 0, float vol =0.8f);
|
int S_PlaySound(int num, int channel = CHAN_AUTO, EChanFlags flags = 0, float vol =0.8f);
|
||||||
int S_PlaySound3D(int num, DDukeActor* spriteNum, const vec3_t* pos, int channel = CHAN_AUTO, EChanFlags flags = 0);
|
int S_PlaySound3D(int num, DDukeActor* spriteNum, const vec3_t* pos, int channel = CHAN_AUTO, EChanFlags flags = 0);
|
||||||
int S_PlayActorSound(int soundNum, DDukeActor* spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0);
|
int S_PlayActorSound(int soundNum, DDukeActor* spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0);
|
||||||
void S_RelinkActorSound(DDukeActor* from, DDukeActor* to);
|
|
||||||
void S_MenuSound(void);
|
void S_MenuSound(void);
|
||||||
|
|
||||||
void S_StopSound(int sndNum, DDukeActor* spr = nullptr, int flags = -1);
|
void S_StopSound(int sndNum, DDukeActor* spr = nullptr, int flags = -1);
|
||||||
|
|
|
@ -532,9 +532,6 @@ void DeleteActor(DExhumedActor* actor)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FVector3 pos = GetSoundPos(&actor->s().pos);
|
|
||||||
soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos);
|
|
||||||
|
|
||||||
if (actor == bestTarget) {
|
if (actor == bestTarget) {
|
||||||
bestTarget = nullptr;
|
bestTarget = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -765,9 +765,6 @@ void KillActor(DSWActor* actor)
|
||||||
actor->clearUser();
|
actor->clearUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
FVector3 pos = GetSoundPos(&actor->s().pos);
|
|
||||||
soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos);
|
|
||||||
|
|
||||||
// shred your garbage
|
// shred your garbage
|
||||||
sp->clear();
|
sp->clear();
|
||||||
actor->Destroy();
|
actor->Destroy();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue