From ad0400113511afaaf8574bfad5b30ddf38070b52 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 19 Nov 2018 18:13:23 +0100 Subject: [PATCH] - fixed some issues with the bodyque and moved this variable into FLevelLocals * it was never saved in savegames, leaving the state of dead bodies undefined * it shouldn't be subjected to pointer substitution because all it contains is old dead bodies, not live ones. --- src/dobject.cpp | 11 ----------- src/dobjgc.cpp | 11 ++--------- src/dobjgc.h | 7 +++++-- src/doomstat.h | 2 -- src/g_game.cpp | 14 ++++++-------- src/g_game.h | 5 +---- src/g_level.cpp | 18 ++++++++++++++++++ src/g_levellocals.h | 6 ++++++ src/p_mobj.cpp | 5 +---- src/p_saveg.cpp | 4 +++- src/p_setup.cpp | 6 +++--- src/r_data/r_translate.cpp | 3 ++- 12 files changed, 47 insertions(+), 45 deletions(-) diff --git a/src/dobject.cpp b/src/dobject.cpp index c0139c82d3..fc48960543 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -38,7 +38,6 @@ #include "actor.h" #include "doomstat.h" // Ideally, DObjects can be used independant of Doom. #include "d_player.h" // See p_user.cpp to find out why this doesn't work. -#include "g_game.h" // Needed for bodyque. #include "c_dispatch.h" #include "dsectoreffect.h" #include "serializer.h" @@ -500,16 +499,6 @@ size_t DObject::StaticPointerSubstitution (AActor *old, AActor *notOld) last = probe; } - // Go through the bodyque. - for (i = 0; i < BODYQUESIZE; ++i) - { - if (bodyque[i] == old) - { - bodyque[i] = notOld; - changed++; - } - } - // Go through players. for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 38eed8fb47..cd1b49a103 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -325,15 +325,8 @@ static void MarkRoot() FCanvasTextureInfo::Mark(); Mark(E_FirstEventHandler); Mark(E_LastEventHandler); - for (auto &s : level.sectorPortals) - { - Mark(s.mSkybox); - } - // Mark dead bodies. - for (i = 0; i < BODYQUESIZE; ++i) - { - Mark(bodyque[i]); - } + level.Mark(); + // Mark players. for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/dobjgc.h b/src/dobjgc.h index 41ae9ba238..82db1de206 100644 --- a/src/dobjgc.h +++ b/src/dobjgc.h @@ -224,7 +224,10 @@ template inline T barrier_cast(TObjPtr &o) return static_cast(static_cast(o)); } -template inline void GC::Mark(TObjPtr &obj) +namespace GC { - GC::Mark(&obj.o); + template inline void Mark(TObjPtr &obj) + { + GC::Mark(&obj.o); + } } diff --git a/src/doomstat.h b/src/doomstat.h index 8086a8f0fd..6f0007f4c4 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -197,8 +197,6 @@ EXTERN_CVAR (Float, mouse_sensitivity) // debug flag to cancel adaptiveness extern bool singletics; -extern int bodyqueslot; - // Needed to store the number of the dummy sky flat. diff --git a/src/g_game.cpp b/src/g_game.cpp index 54ca664cf7..9be9b54559 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -70,6 +70,7 @@ #include "p_spec.h" #include "serializer.h" #include "vm.h" +#include "dobjgc.h" #include "g_hub.h" #include "g_levellocals.h" @@ -211,9 +212,6 @@ FString savedescription; // [RH] Name of screenshot file to generate (usually NULL) FString shotfile; -AActor* bodyque[BODYQUESIZE]; -int bodyqueslot; - FString savename; FString BackupSaveName; @@ -1676,13 +1674,14 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart) static void G_QueueBody (AActor *body) { // flush an old corpse if needed - int modslot = bodyqueslot%BODYQUESIZE; + int modslot = level.bodyqueslot%level.BODYQUESIZE; + level.bodyqueslot = modslot + 1; - if (bodyqueslot >= BODYQUESIZE && bodyque[modslot] != NULL) + if (level.bodyqueslot >= level.BODYQUESIZE && level.bodyque[modslot] != NULL) { - bodyque[modslot]->Destroy (); + level.bodyque[modslot]->Destroy (); } - bodyque[modslot] = body; + level.bodyque[modslot] = body; // Copy the player's translation, so that if they change their color later, only // their current body will change and not all their old corpses. @@ -1706,7 +1705,6 @@ static void G_QueueBody (AActor *body) body->Scale.Y *= skin.Scale.Y / defaultActor->Scale.Y; } - bodyqueslot++; } // diff --git a/src/g_game.h b/src/g_game.h index 7ac49a413d..6f5f93261f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -30,6 +30,7 @@ struct event_t; +#include "dobjgc.h" // // GAME @@ -94,10 +95,6 @@ void G_AddViewPitch (int look, bool mouse = false); // Adds to consoleplayer's viewangle if allowed void G_AddViewAngle (int yaw, bool mouse = false); -#define BODYQUESIZE 32 -class AActor; -extern AActor *bodyque[BODYQUESIZE]; -extern int bodyqueslot; class AInventory; extern const AInventory *SendItemUse, *SendItemDrop; extern int SendItemDropAmount; diff --git a/src/g_level.cpp b/src/g_level.cpp index b1a7cb3ad2..775d226fa0 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1956,6 +1956,24 @@ void FLevelLocals::Tick () // //========================================================================== +void FLevelLocals::Mark() +{ + for (auto &s : sectorPortals) + { + GC::Mark(s.mSkybox); + } + // Mark dead bodies. + for (auto &p : bodyque) + { + GC::Mark(p); + } +} + +//========================================================================== +// +// +//========================================================================== + void FLevelLocals::AddScroller (int secnum) { if (secnum < 0) diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 1e3aed96f7..86050b68cc 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -47,6 +47,7 @@ struct FLevelLocals { void Tick (); + void Mark(); void AddScroller (int secnum); void SetInterMusic(const char *nextmap); void SetMusicVolume(float v); @@ -85,6 +86,11 @@ struct FLevelLocals TArray gamenodes; node_t *headgamenode; TArray rejectmatrix; + + static const int BODYQUESIZE = 32; + TObjPtr bodyque[BODYQUESIZE]; + int bodyqueslot; + TArray sectorPortals; TArray linePortals; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index ff48ab79d3..9d3b7d931c 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5772,10 +5772,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) } DObject::StaticPointerSubstitution (oldactor, p->mo); - // PointerSubstitution() will also affect the bodyque, so undo that now. - for (int ii=0; ii < BODYQUESIZE; ++ii) - if (bodyque[ii] == p->mo) - bodyque[ii] = oldactor; + E_PlayerRespawned(int(p - players)); FBehavior::StaticStartTypedScripts (SCRIPT_Respawn, p->mo, true); } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index a8dff68680..e5c111a8f6 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -971,7 +971,9 @@ void G_SerializeLevel(FSerializer &arc, bool hubload) ("level.skytexture2", level.skytexture2) ("level.fogdensity", level.fogdensity) ("level.outsidefogdensity", level.outsidefogdensity) - ("level.skyfog", level.skyfog); + ("level.skyfog", level.skyfog) + ("level.bodyqueslot", level.bodyqueslot) + .Array("level.bodyque", level.bodyque, level.BODYQUESIZE); // Hub transitions must keep the current total time if (!hubload) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 8d502b42bd..820596ecb0 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4048,12 +4048,12 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame) FixHoles(); } - bodyqueslot = 0; + level.bodyqueslot = 0; // phares 8/10/98: Clear body queue so the corpses from previous games are // not assumed to be from this one. - for (i = 0; i < BODYQUESIZE; i++) - bodyque[i] = NULL; + for(auto & p : level.bodyque) + p = nullptr; CreateSections(level.sections); diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index eeca418641..c11f9be946 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -49,6 +49,7 @@ #include "vm.h" #include "v_text.h" #include "m_crc32.h" +#include "g_levellocals.h" #include "gi.h" @@ -926,7 +927,7 @@ void R_InitTranslationTables () // Each player corpse has its own translation so they won't change // color if the player who created them changes theirs. - for (i = 0; i < BODYQUESIZE; ++i) + for (i = 0; i < level.BODYQUESIZE; ++i) { PushIdentityTable(TRANSLATION_PlayerCorpses); }