diff --git a/source/games/sw/src/game.cpp b/source/games/sw/src/game.cpp index 5634c9eb9..4d151affe 100644 --- a/source/games/sw/src/game.cpp +++ b/source/games/sw/src/game.cpp @@ -32,6 +32,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "names2.h" #include "panel.h" #include "game.h" +#include "swactor.h" #include "interpso.h" #include "tags.h" #include "sector.h" @@ -102,6 +103,48 @@ IMPLEMENT_POINTER(user.attachActor) IMPLEMENT_POINTER(user.WpnGoalActor) IMPLEMENT_POINTERS_END +void MarkSOInterp(); + +void markgcroots() +{ + MarkSOInterp(); + GC::MarkArray(StarQueue, MAX_STAR_QUEUE); + GC::MarkArray(HoleQueue, MAX_HOLE_QUEUE); + GC::MarkArray(WallBloodQueue, MAX_WALLBLOOD_QUEUE); + GC::MarkArray(FloorBloodQueue, MAX_FLOORBLOOD_QUEUE); + GC::MarkArray(GenericQueue, MAX_GENERIC_QUEUE); + GC::MarkArray(LoWangsQueue, MAX_LOWANGS_QUEUE); + GC::MarkArray(BossSpriteNum, 3); + for (auto& pl : Player) + { + GC::Mark(pl.actor); + GC::Mark(pl.lowActor); + GC::Mark(pl.highActor); + GC::Mark(pl.remoteActor); + GC::Mark(pl.PlayerUnderActor); + GC::Mark(pl.KillerActor); + GC::Mark(pl.HitBy); + GC::Mark(pl.last_camera_act); + } + for (auto& so : SectorObject) + { + GC::Mark(so.controller); + GC::Mark(so.sp_child); + GC::MarkArray(so.so_actors, MAX_SO_SPRITE); + GC::Mark(so.match_event_actor); + } + for (int i = 0; i < AnimCnt; i++) + { + GC::Mark(Anim[i].animactor); + } + for (auto& mir : mirror) + { + GC::Mark(mir.cameraActor); + GC::Mark(mir.camspriteActor); + } +} + + void pClearSpriteList(PLAYERp pp); extern int sw_snd_scratch; @@ -191,6 +234,7 @@ void GameInterface::LoadGameTextures() void GameInterface::app_init() { SetupActors(RUNTIME_CLASS(DSWActor)); + GC::AddMarkerFunc(markgcroots); GameTicRate = TICS_PER_SEC / synctics; InitCheats(); diff --git a/source/games/sw/src/game.h b/source/games/sw/src/game.h index 64fb7c15a..47d9aa08a 100644 --- a/source/games/sw/src/game.h +++ b/source/games/sw/src/game.h @@ -51,6 +51,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "gamestruct.h" #include "packet.h" #include "gameinput.h" +#include "serialize_obj.h" EXTERN_CVAR(Bool, sw_ninjahack) EXTERN_CVAR(Bool, sw_darts) @@ -731,14 +732,15 @@ struct PLAYERstruct vec3_t pos; }; - DSWActor* actor; - DSWActor* lowActor, * highActor; - DSWActor* remoteActor; - DSWActor* PlayerUnderActor; - DSWActor* KillerActor; //who killed me - DSWActor* HitBy; // Sprite num of whatever player was last hit by + TObjPtr actor; + TObjPtr lowActor, highActor; + TObjPtr remoteActor; + TObjPtr PlayerUnderActor; + TObjPtr KillerActor; //who killed me + TObjPtr HitBy; // Sprite num of whatever player was last hit by + TObjPtr last_camera_act; - DSWActor* Actor() const + DSWActor* Actor() { return actor; } @@ -761,7 +763,6 @@ struct PLAYERstruct int ceiling_dist,floor_dist; SECTORp hi_sectp, lo_sectp; - DSWActor* last_camera_act; int circle_camera_dist; int six,siy,siz; // save player interp position for PlayerSprite int16_t siang; @@ -1093,12 +1094,12 @@ struct USER // sector object - contains info for the SO // referenced actors - DSWActor* lowActor, * highActor; - DSWActor* targetActor; // target player for the enemy - can only handle one player at at time - DSWActor* flameActor; - DSWActor* attachActor; // attach to sprite if needed - electro snake - DSWActor* flagOwnerActor; - DSWActor* WpnGoalActor; + TObjPtr lowActor, highActor; + TObjPtr targetActor; // target player for the enemy - can only handle one player at at time + TObjPtr flameActor; + TObjPtr attachActor; // attach to sprite if needed - electro snake + TObjPtr flagOwnerActor; + TObjPtr WpnGoalActor; int Flags; int Flags2; @@ -1625,9 +1626,9 @@ struct SECTOR_OBJECTstruct soANIMATORp PreMoveAnimator; soANIMATORp PostMoveAnimator; soANIMATORp Animator; - DSWActor* controller; + TObjPtr controller; - DSWActor* sp_child; // child sprite that holds info for the sector object + TObjPtr sp_child; // child sprite that holds info for the sector object union { @@ -1635,8 +1636,8 @@ struct SECTOR_OBJECTstruct vec3_t pmid; }; - DSWActor* so_actors[MAX_SO_SPRITE]; // hold the actors of the object - DSWActor* match_event_actor; // spritenum of the match event sprite + TObjPtr so_actors[MAX_SO_SPRITE]; // hold the actors of the object + TObjPtr match_event_actor; // spritenum of the match event sprite sectortype *sectp[MAX_SO_SECTOR], @@ -2240,12 +2241,13 @@ struct ANIMstruct int goal; int vel; short vel_adj; - DSWActor* animactor; + TObjPtr animactor; ANIM_CALLBACKp callback; SECTOR_OBJECTp callbackdata; // only gets used in one place for this so having a proper type makes serialization easier. int& Addr() { + static int scratch; switch (animtype) { case ANIM_Floorz: @@ -2253,9 +2255,11 @@ struct ANIMstruct case ANIM_SopZ: return SectorObject[animindex].zmid; case ANIM_Spritez: + if (animactor == nullptr) return scratch; return animactor->s().z; case ANIM_Userz: - return animactor->u()->sz; + if (animactor == nullptr) return scratch; + return animactor->u()->sz; case ANIM_SUdepth: return sector[animindex].depth_fixed; default: diff --git a/source/games/sw/src/interpso.cpp b/source/games/sw/src/interpso.cpp index 3cc02ffea..37966afc9 100644 --- a/source/games/sw/src/interpso.cpp +++ b/source/games/sw/src/interpso.cpp @@ -61,7 +61,7 @@ static struct so_interp int32_t lastipos; int32_t lastoldipos; int32_t lastangdiff; - DSWActor* actorofang; + TObjPtr actorofang; } data[SO_MAXINTERPOLATIONS]; int32_t numinterpolations; @@ -69,6 +69,25 @@ static struct so_interp bool hasvator; } so_interpdata[MAX_SECTOR_OBJECTS]; +void MarkSOInterp() +{ + int32_t i; + SECTOR_OBJECTp sop; + so_interp* interp; + so_interp::interp_data* data; + + for (sop = SectorObject, interp = so_interpdata; + sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++) + { + if (SO_EMPTY(sop)) + continue; + for (i = 0, data = interp->data; i < interp->numinterpolations; i++, data++) + { + GC::Mark(data->actorofang); + } + } +} + static int &getvalue(so_interp::interp_data& element, bool write) { static int scratch; diff --git a/source/games/sw/src/jsector.h b/source/games/sw/src/jsector.h index 6167edf25..ff2ea80d9 100644 --- a/source/games/sw/src/jsector.h +++ b/source/games/sw/src/jsector.h @@ -40,8 +40,8 @@ typedef enum typedef struct { - DSWActor* cameraActor; // Contains number of ST1 sprite used as a camera - DSWActor* camspriteActor; // sprite pointing to campic + TObjPtr cameraActor; // Contains number of ST1 sprite used as a camera + TObjPtr camspriteActor; // sprite pointing to campic walltype* mirrorWall; // Wall number containing the mirror tile sectortype* mirrorSector; // used internally to draw mirror rooms short campic; // Editart tile number to draw a screen to diff --git a/source/games/sw/src/sprite.cpp b/source/games/sw/src/sprite.cpp index 3e1c1db2f..357e9e8f0 100644 --- a/source/games/sw/src/sprite.cpp +++ b/source/games/sw/src/sprite.cpp @@ -591,7 +591,7 @@ void SetOwner(DSWActor* ownr, DSWActor* child, bool flag) DSWActor* GetOwner(DSWActor* child) { - return child ? child->ownerActor : nullptr; + return child ? child->ownerActor.Get() : nullptr; } void ClearOwner(DSWActor* child) diff --git a/source/games/sw/src/swactor.h b/source/games/sw/src/swactor.h index e8a757e80..a02bcac8e 100644 --- a/source/games/sw/src/swactor.h +++ b/source/games/sw/src/swactor.h @@ -15,7 +15,7 @@ public: bool hasUser; USER user; walltype* tempwall; // transient, to replace a hack using a 16 bit sprite field. - DSWActor* ownerActor; + TObjPtr ownerActor; DSWActor() = default; DSWActor& operator=(const DSWActor& other) = default; @@ -43,7 +43,6 @@ public: } void Serialize(FSerializer& arc) override; - }; diff --git a/source/games/sw/src/weapon.cpp b/source/games/sw/src/weapon.cpp index e82ab64a1..6efe74641 100644 --- a/source/games/sw/src/weapon.cpp +++ b/source/games/sw/src/weapon.cpp @@ -72,17 +72,17 @@ int ShellCount = 0; //int Zombies = 0; int StarQueueHead=0; -DSWActor* StarQueue[MAX_STAR_QUEUE]; +TObjPtr StarQueue[MAX_STAR_QUEUE]; int HoleQueueHead=0; -DSWActor* HoleQueue[MAX_HOLE_QUEUE]; +TObjPtr HoleQueue[MAX_HOLE_QUEUE]; int WallBloodQueueHead=0; -DSWActor* WallBloodQueue[MAX_WALLBLOOD_QUEUE]; +TObjPtr WallBloodQueue[MAX_WALLBLOOD_QUEUE]; int FloorBloodQueueHead=0; -DSWActor* FloorBloodQueue[MAX_FLOORBLOOD_QUEUE]; +TObjPtr FloorBloodQueue[MAX_FLOORBLOOD_QUEUE]; int GenericQueueHead=0; -DSWActor* GenericQueue[MAX_GENERIC_QUEUE]; +TObjPtr GenericQueue[MAX_GENERIC_QUEUE]; int LoWangsQueueHead=0; -DSWActor* LoWangsQueue[MAX_LOWANGS_QUEUE]; +TObjPtr LoWangsQueue[MAX_LOWANGS_QUEUE]; void SpawnBreakStaticFlames(DSWActor* actor); bool GlobalSkipZrange = false; diff --git a/source/games/sw/src/weapon.h b/source/games/sw/src/weapon.h index 640f051ac..0b4e65053 100644 --- a/source/games/sw/src/weapon.h +++ b/source/games/sw/src/weapon.h @@ -59,17 +59,17 @@ enum extern int StarQueueHead; -extern DSWActor* StarQueue[MAX_STAR_QUEUE]; +extern TObjPtr StarQueue[MAX_STAR_QUEUE]; extern int HoleQueueHead; -extern DSWActor* HoleQueue[MAX_HOLE_QUEUE]; +extern TObjPtr HoleQueue[MAX_HOLE_QUEUE]; extern int WallBloodQueueHead; -extern DSWActor* WallBloodQueue[MAX_WALLBLOOD_QUEUE]; +extern TObjPtr WallBloodQueue[MAX_WALLBLOOD_QUEUE]; extern int FloorBloodQueueHead; -extern DSWActor* FloorBloodQueue[MAX_FLOORBLOOD_QUEUE]; +extern TObjPtr FloorBloodQueue[MAX_FLOORBLOOD_QUEUE]; extern int GenericQueueHead; -extern DSWActor* GenericQueue[MAX_GENERIC_QUEUE]; +extern TObjPtr GenericQueue[MAX_GENERIC_QUEUE]; extern int LoWangsQueueHead; -extern DSWActor* LoWangsQueue[MAX_LOWANGS_QUEUE]; +extern TObjPtr LoWangsQueue[MAX_LOWANGS_QUEUE]; void ChangeState(DSWActor* actor, STATEp statep); void DoPlayerBeginRecoil(PLAYERp pp, short pix_amt);