From 50d59e99cb36bb130a70a62aff6ff1e1625f341b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 28 Jan 2019 23:53:40 +0100 Subject: [PATCH] - moved sound sequence head of list into FLevelLocals. --- src/dobjgc.cpp | 2 -- src/g_level.cpp | 2 ++ src/g_levellocals.h | 4 +++ src/p_saveg.cpp | 7 +++-- src/p_setup.cpp | 9 +++--- src/s_sndseq.cpp | 71 +++++++++++++++++++++------------------------ src/s_sndseq.h | 18 +++++------- src/s_sound.cpp | 11 +++++-- src/wi_stuff.cpp | 5 +++- 9 files changed, 67 insertions(+), 62 deletions(-) diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 5f0a995c0..f86cdb1d3 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -315,8 +315,6 @@ static void MarkRoot() if (playeringame[i]) players[i].PropagateMark(); } - // Mark sound sequences. - DSeqNode::StaticMarkHead(); // Mark sectors. if (SectorMarker == nullptr && level.sectors.Size() > 0) { diff --git a/src/g_level.cpp b/src/g_level.cpp index 51367df8e..a80b8d6ae 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1984,6 +1984,8 @@ void FLevelLocals::Mark() GC::Mark(ACSThinker); GC::Mark(automap); GC::Mark(interpolator.Head); + GC::Mark(SequenceListHead); + canvasTextureInfo.Mark(); for (auto &c : CorpseQueue) { diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 31b7bf433..ca14ee839 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -87,6 +87,7 @@ struct FPortalBits class DACSThinker; class DFraggleThinker; class DSpotState; +class DSeqNode; struct FStrifeDialogueNode; class DAutomapBase; @@ -487,6 +488,9 @@ public: int airsupply; int DefaultEnvironment; // Default sound environment. + int ActiveSequences; + DSeqNode *SequenceListHead; + TArray Scrolls; // NULL if no DScrollers in this level int8_t WallVertLight; // Light diffs for vert/horiz walls diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index ceac468e9..fd6f7138b 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -528,7 +528,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, zone_t &z, zone_t *def void P_SerializeSounds(FLevelLocals *Level, FSerializer &arc) { S_SerializeSounds(arc); - DSeqNode::SerializeSequences (arc); const char *name = NULL; uint8_t order; float musvol = Level->MusicVolume; @@ -931,6 +930,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload) DThinker::DestroyAllThinkers(); interpolator.ClearInterpolations(); arc.ReadObjects(hubload); + ActiveSequences = 0; } arc("multiplayer", multiplayer); @@ -966,7 +966,8 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload) ("scrolls", Scrolls) ("automap", automap) ("interpolator", interpolator) - ("frozenstate", frozenstate); + ("frozenstate", frozenstate) + ("sndseqlisthead", SequenceListHead); // Hub transitions must keep the current total time @@ -1022,7 +1023,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload) FWeaponSlots::SetupWeaponSlots(players[i].mo); } } - AActor::RecreateAllAttachedLights(); + AActor::RecreateAllAttachedLights(); InitPortalGroups(this); automap->UpdateShowAllLines(); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index bef044331..7b482b0ad 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -267,6 +267,8 @@ void FLevelLocals::ClearLevelData() killed_monsters = found_items = found_secrets = wminfo.maxfrags = 0; + SN_StopAllSequences(this); + FStrifeDialogueNode *node; while (StrifeDialogues.Pop (node)) @@ -351,7 +353,6 @@ void P_FreeLevelData () R_FreePastViewers(); P_ClearUDMFKeys(); - SN_StopAllSequences (); DThinker::DestroyAllThinkers (); level.ClearLevelData(); @@ -611,13 +612,13 @@ CCMD(dumpgeometry) if (seg->linedef) { Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, linedef %d, side %d", - seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), - seg->Index(), seg->linedef->Index(), seg->sidedef != seg->linedef->sidedef[0]); + seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), + seg->Index(), seg->linedef->Index(), seg->sidedef != seg->linedef->sidedef[0]); } else { Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, miniseg", - seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), seg->Index()); + seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), seg->Index()); } if (seg->PartnerSeg) { diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index d08a26732..3d5b347e1 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -219,8 +219,6 @@ static bool TwiddleSeqNum (int &sequence, seqtype_t type); // PUBLIC DATA DEFINITIONS ------------------------------------------------- FSoundSequencePtrArray Sequences; -int ActiveSequences; -DSeqNode *DSeqNode::SequenceListHead; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -289,11 +287,6 @@ static FRandom pr_sndseq ("SndSeq"); // CODE -------------------------------------------------------------------- -void DSeqNode::SerializeSequences (FSerializer &arc) -{ - arc("sndseqlisthead", SequenceListHead); -} - IMPLEMENT_CLASS(DSeqNode, false, true) IMPLEMENT_POINTERS_START(DSeqNode) @@ -345,7 +338,8 @@ void DSeqNode::Serialize(FSerializer &arc) ("parentseqnode", m_ParentSeqNode) ("id", id) ("seqname", seqName) - ("numchoices", numchoices); + ("numchoices", numchoices) + ("level", Level); // The way this is saved makes it hard to encapsulate so just do it the hard way... if (arc.isWriting()) @@ -397,9 +391,9 @@ void DSeqNode::OnDestroy() m_ParentSeqNode->m_ChildSeqNode = nullptr; m_ParentSeqNode = nullptr; } - if (SequenceListHead == this) + if (Level->SequenceListHead == this) { - SequenceListHead = m_Next; + Level->SequenceListHead = m_Next; GC::WriteBarrier(m_Next); } if (m_Prev) @@ -412,7 +406,7 @@ void DSeqNode::OnDestroy() m_Next->m_Prev = m_Prev; GC::WriteBarrier(m_Next, m_Prev); } - ActiveSequences--; + Level->ActiveSequences--; Super::OnDestroy(); } @@ -803,21 +797,22 @@ static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, c Sequences[curseq]->Script[ScriptTemp.Size()] = MakeCommand(SS_CMD_END, 0); } -DSeqNode::DSeqNode (int sequence, int modenum) +DSeqNode::DSeqNode (FLevelLocals *l, int sequence, int modenum) : m_ModeNum(modenum), m_SequenceChoices(0) { + Level = l; ActivateSequence (sequence); - if (!SequenceListHead) + if (!Level->SequenceListHead) { - SequenceListHead = this; - m_Next = m_Prev = NULL; + Level->SequenceListHead = this; + m_Next = m_Prev = nullptr; } else { - SequenceListHead->m_Prev = this; GC::WriteBarrier(SequenceListHead->m_Prev, this); - m_Next = SequenceListHead; GC::WriteBarrier(this, SequenceListHead); - SequenceListHead = this; - m_Prev = NULL; + Level->SequenceListHead->m_Prev = this; GC::WriteBarrier(Level->SequenceListHead->m_Prev, this); + m_Next = Level->SequenceListHead; GC::WriteBarrier(this, Level->SequenceListHead); + Level->SequenceListHead = this; + m_Prev = nullptr; } GC::WriteBarrier(this); m_ParentSeqNode = m_ChildSeqNode = nullptr; @@ -832,24 +827,23 @@ void DSeqNode::ActivateSequence (int sequence) m_CurrentSoundID = 0; m_Volume = 1; // Start at max volume... m_Atten = ATTN_IDLE; // ...and idle attenuation - - ActiveSequences++; + Level->ActiveSequences++; } DSeqActorNode::DSeqActorNode (AActor *actor, int sequence, int modenum) - : DSeqNode (sequence, modenum), + : DSeqNode (actor->Level, sequence, modenum), m_Actor (actor) { } DSeqPolyNode::DSeqPolyNode (FPolyObj *poly, int sequence, int modenum) - : DSeqNode (sequence, modenum), + : DSeqNode (poly->Level, sequence, modenum), m_Poly (poly) { } DSeqSectorNode::DSeqSectorNode (sector_t *sec, int chan, int sequence, int modenum) - : DSeqNode (sequence, modenum), + : DSeqNode (sec->Level, sequence, modenum), Channel (chan), m_Sector (sec) { @@ -1048,7 +1042,8 @@ static int FindSequence (FName seqname) DSeqNode *SN_CheckSequence(sector_t *sector, int chan) { - for (DSeqNode *node = DSeqNode::FirstSequence(); node; ) + auto Level = sector->Level; + for (DSeqNode *node = Level->SequenceListHead; node; ) { DSeqNode *next = node->NextSequence(); if (node->Source() == sector) @@ -1079,7 +1074,7 @@ DEFINE_ACTION_FUNCTION(_Sector, CheckSoundSequence) void SN_StopSequence (AActor *actor) { - SN_DoStop (actor); + SN_DoStop (actor->Level, actor); } DEFINE_ACTION_FUNCTION(AActor, StopSoundSequence) @@ -1109,14 +1104,14 @@ DEFINE_ACTION_FUNCTION(_Sector, StopSoundSequence) void SN_StopSequence (FPolyObj *poly) { - SN_DoStop (poly); + SN_DoStop (poly->Level, poly); } -void SN_DoStop (void *source) +void SN_DoStop (FLevelLocals *Level, void *source) { DSeqNode *node; - for (node = DSeqNode::FirstSequence(); node; ) + for (node = Level->SequenceListHead; node; ) { DSeqNode *next = node->NextSequence(); if (node->Source() == source) @@ -1164,7 +1159,7 @@ bool SN_IsMakingLoopingSound (sector_t *sector) { DSeqNode *node; - for (node = DSeqNode::FirstSequence (); node; ) + for (node = sector->Level->SequenceListHead; node; ) { DSeqNode *next = node->NextSequence(); if (node->Source() == (void *)sector) @@ -1328,7 +1323,7 @@ void DSeqNode::Tick () int seqnum = FindSequence (ENamedName(m_SequencePtr[i*2+1])); if (seqnum >= 0) { // Found a match, and it's a good one too. - ActiveSequences--; + Level->ActiveSequences--; ActivateSequence (seqnum); break; } @@ -1359,15 +1354,15 @@ void DSeqNode::Tick () } } -void SN_UpdateActiveSequences (void) +void SN_UpdateActiveSequences (FLevelLocals *Level) { DSeqNode *node; - if (!ActiveSequences || paused) + if (!Level->ActiveSequences || paused) { // No sequences currently playing/game is paused return; } - for (node = DSeqNode::FirstSequence(); node; node = node->NextSequence()) + for (node =Level->SequenceListHead; node; node = node->NextSequence()) { node->Tick (); } @@ -1379,11 +1374,11 @@ void SN_UpdateActiveSequences (void) // //========================================================================== -void SN_StopAllSequences (void) +void SN_StopAllSequences (FLevelLocals *Level) { DSeqNode *node; - for (node = DSeqNode::FirstSequence(); node; ) + for (node = Level->SequenceListHead; node; ) { DSeqNode *next = node->NextSequence(); node->m_StopSound = 0; // don't play any stop sounds @@ -1470,14 +1465,14 @@ DEFINE_ACTION_FUNCTION(DSeqNode, MarkPrecacheSounds) // nodeNum zero is the first node //========================================================================== -void SN_ChangeNodeData (int nodeNum, int seqOffset, int delayTics, float volume, +void SN_ChangeNodeData (FLevelLocals *Level, int nodeNum, int seqOffset, int delayTics, float volume, int currentSoundID) { int i; DSeqNode *node; i = 0; - node = DSeqNode::FirstSequence(); + node = Level->SequenceListHead; while (node && i < nodeNum) { node = node->NextSequence(); diff --git a/src/s_sndseq.h b/src/s_sndseq.h index 83b0475be..17e4284d2 100644 --- a/src/s_sndseq.h +++ b/src/s_sndseq.h @@ -28,21 +28,18 @@ public: void AddChoice (int seqnum, seqtype_t type); int GetModeNum() const { return m_ModeNum; } FName GetSequenceName() const; - static void StaticMarkHead() { GC::Mark(SequenceListHead); } virtual void MakeSound (int loop, FSoundID id) {} virtual void *Source () { return NULL; } virtual bool IsPlaying () { return false; } virtual DSeqNode *SpawnChild (int seqnum) { return NULL; } - inline static DSeqNode *FirstSequence() { return SequenceListHead; } inline DSeqNode *NextSequence() const { return m_Next; } - static void SerializeSequences (FSerializer &arc); protected: DSeqNode (); - DSeqNode (int sequence, int modenum); + DSeqNode (FLevelLocals *l, int sequence, int modenum); int32_t *m_SequencePtr; int m_Sequence; @@ -54,20 +51,20 @@ protected: float m_Atten; int m_ModeNum; + FLevelLocals *Level; TArray m_SequenceChoices; TObjPtr m_ChildSeqNode; TObjPtr m_ParentSeqNode; private: - static DSeqNode *SequenceListHead; DSeqNode *m_Next, *m_Prev; void ActivateSequence (int sequence); - friend void SN_StopAllSequences (void); + friend void SN_StopAllSequences (FLevelLocals *Level); }; -void SN_StopAllSequences (void); +void SN_StopAllSequences (FLevelLocals *Level); struct FSoundSequence { @@ -92,11 +89,10 @@ void SN_StopSequence (sector_t *sector, int chan); void SN_StopSequence (FPolyObj *poly); bool SN_AreModesSame(int sequence, seqtype_t type, int mode1, int mode2); bool SN_AreModesSame(FName name, int mode1, int mode2); -void SN_UpdateActiveSequences (void); +void SN_UpdateActiveSequences (FLevelLocals *Level); ptrdiff_t SN_GetSequenceOffset (int sequence, int32_t *sequencePtr); -void SN_DoStop (void *); -void SN_ChangeNodeData (int nodeNum, int seqOffset, int delayTics, - float volume, int currentSoundID); +void SN_DoStop (FLevelLocals *Level, void *); +void SN_ChangeNodeData (FLevelLocals *Level, int nodeNum, int seqOffset, int delayTics, float volume, int currentSoundID); FName SN_GetSequenceSlot (int sequence, seqtype_t type); void SN_MarkPrecacheSounds (int sequence, seqtype_t type); bool SN_IsMakingLoopingSound (sector_t *sector); diff --git a/src/s_sound.cpp b/src/s_sound.cpp index ad4eb38ed..606fcd71e 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1751,7 +1751,10 @@ void S_StopSound (const FPolyObj *poly, int channel) void S_StopAllChannels () { - SN_StopAllSequences(); + for (auto Level : AllLevels()) + { + SN_StopAllSequences(Level); + } FSoundChan *chan = Channels; while (chan != NULL) @@ -2178,8 +2181,10 @@ void S_UpdateSounds (AActor *listenactor) chan->ChanFlags &= ~CHAN_JUSTSTARTED; } - SN_UpdateActiveSequences(); - + for (auto Level : AllLevels()) + { + SN_UpdateActiveSequences(Level); + } GSnd->UpdateListener(&listener); GSnd->UpdateSounds(); diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 9fc258ee4..87edc0398 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -769,7 +769,10 @@ void WI_Start(wbstartstruct_t *wbstartstruct) else wbstartstruct->nextname = info->LookupLevelName(); V_SetBlend(0, 0, 0, 0); S_StopAllChannels(); - SN_StopAllSequences(); + for (auto Level : AllLevels()) + { + SN_StopAllSequences(Level); + } WI_Screen = cls->CreateNew(); IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Start) {