diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 0f5f0a33d..2bc9bc381 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -97,12 +97,12 @@ struct sectortype { uint8_t keyinfo; uint8_t shadedsector; - DCoreActor* hitagactor; // we need this because Duke stores an actor in the hitag field. Is really a DDukeActor, but cannot be declared here safely. + TObjPtr hitagactor; // we need this because Duke stores an actor in the hitag field. Is really a DDukeActor, but cannot be declared here safely. }; struct // Blood { BLD_NS::XSECTOR* _xs; - DCoreActor* upperLink, *lowerLink; + TObjPtr upperLink, lowerLink; int baseFloor, baseCeil; int velFloor, velCeil; uint8_t slopewallofs; diff --git a/source/common/objects/dobjgc.h b/source/common/objects/dobjgc.h index 125070a54..cbfe758f0 100644 --- a/source/common/objects/dobjgc.h +++ b/source/common/objects/dobjgc.h @@ -186,8 +186,6 @@ class TObjPtr public: TObjPtr() = default; - TObjPtr(const TObjPtr &q) = delete; - TObjPtr(T q) noexcept : pp(q) { diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 82d2f8dfd..ef67b9685 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -145,6 +145,7 @@ bool PreBindTexture(FRenderState* state, FGameTexture*& tex, EUpscaleFlags& flag void highTileSetup(); void FontCharCreated(FGameTexture* base, FGameTexture* untranslated); void LoadVoxelModels(); +void MarkMap(); DStatusBarCore* StatusBar; @@ -1054,6 +1055,7 @@ int RunGame() StartScreen->Progress(); engineInit(); + GC::AddMarkerFunc(MarkMap); gi->app_init(); StartScreen->Progress(); G_ParseMapInfo(); @@ -1382,6 +1384,7 @@ void GameInterface::FreeLevelData() sector.Reset(); wall.Reset(); currentLevel = nullptr; + GC::FullGC(); } //--------------------------------------------------------------------------- diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp index bc5077989..d5b7b2321 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -526,3 +526,18 @@ void setWallSectors() } } + +void MarkMap() +{ + for (auto& sect : sectors()) + { + GC::Mark(sect.firstEntry); + GC::Mark(sect.lastEntry); + if (isDukeLike()) GC::Mark(sect.hitagactor); + else if (isBlood()) + { + GC::Mark(sect.upperLink); + GC::Mark(sect.lowerLink); + } + } +} diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index 47ba6f8d0..af47ae6b7 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -61,6 +61,7 @@ #include "sectorgeometry.h" #include "d_net.h" #include "ns.h" +#include "serialize_obj.h" #include "games/blood/src/mapstructs.h" #include diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index f45577378..3e08298de 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -4950,8 +4950,8 @@ void MoveDude(DBloodActor* actor) if (pXSector->Underwater) bUnderwater = 1; if (pXSector->Depth) bDepth = 1; } - auto pUpperLink = pSector->upperLink; - auto pLowerLink = pSector->lowerLink; + DCoreActor* pUpperLink = pSector->upperLink; + DCoreActor* pLowerLink = pSector->lowerLink; if (pUpperLink && (pUpperLink->s().type == kMarkerUpWater || pUpperLink->s().type == kMarkerUpGoo)) bDepth = 1; if (pLowerLink && (pLowerLink->s().type == kMarkerLowWater || pLowerLink->s().type == kMarkerLowGoo)) bDepth = 1; if (pPlayer) wd += 16; @@ -5076,7 +5076,7 @@ void MoveDude(DBloodActor* actor) if (gModernMap) { pPlayer->nWaterPal = 0; - auto pUpper = static_cast(pSector->upperLink); + auto pUpper = barrier_cast(pSector->upperLink); if (pUpper && pUpper->hasX()) pPlayer->nWaterPal = pUpper->x().data2; } #endif diff --git a/source/games/blood/src/gameutil.cpp b/source/games/blood/src/gameutil.cpp index 25338a98d..ba38baa20 100644 --- a/source/games/blood/src/gameutil.cpp +++ b/source/games/blood/src/gameutil.cpp @@ -523,7 +523,7 @@ int VectorScan(DBloodActor *actor, int nOffset, int nZOffset, int dx, int dy, in { if (dz > 0) { - auto actor = static_cast(gHitInfo.hitSector->upperLink); + auto actor = barrier_cast(gHitInfo.hitSector->upperLink); if (!actor) return 2; auto link = actor->GetOwner(); gHitInfo.clearObj(); @@ -537,7 +537,7 @@ int VectorScan(DBloodActor *actor, int nOffset, int nZOffset, int dx, int dy, in } else { - auto actor = static_cast(gHitInfo.hitSector->lowerLink); + auto actor = barrier_cast(gHitInfo.hitSector->lowerLink); if (!actor) return 1; auto link = actor->GetOwner(); gHitInfo.clearObj(); @@ -574,7 +574,7 @@ void GetZRange(DBloodActor *actor, int *ceilZ, Collision *ceilColl, int *floorZ, XSECTOR *pXSector = &pSector->xs(); *floorZ += pXSector->Depth << 10; } - auto actor = static_cast(pSector->upperLink); + auto actor = barrier_cast(pSector->upperLink); if (actor) { auto link = actor->GetOwner(); @@ -588,7 +588,7 @@ void GetZRange(DBloodActor *actor, int *ceilZ, Collision *ceilColl, int *floorZ, auto pSector = ceilColl->hitSector; if ((nClipParallax & PARALLAXCLIP_CEILING) == 0 && (pSector->ceilingstat & 1)) *ceilZ = 0x80000000; - auto actor = static_cast(pSector->lowerLink); + auto actor = barrier_cast(pSector->lowerLink); if (actor) { auto link = actor->GetOwner(); @@ -616,7 +616,7 @@ void GetZRangeAtXYZ(int x, int y, int z, sectortype* pSector, int *ceilZ, Collis XSECTOR* pXSector = &pSector->xs(); *floorZ += pXSector->Depth << 10; } - auto actor = static_cast(pSector->upperLink); + auto actor = barrier_cast(pSector->upperLink); if (actor) { auto link = actor->GetOwner(); @@ -630,7 +630,7 @@ void GetZRangeAtXYZ(int x, int y, int z, sectortype* pSector, int *ceilZ, Collis auto pSector = ceilColl->hitSector; if ((nClipParallax & PARALLAXCLIP_CEILING) == 0 && (pSector->ceilingstat & 1)) *ceilZ = 0x80000000; - auto actor = static_cast(pSector->lowerLink); + auto actor = barrier_cast(pSector->lowerLink); if (actor) { auto link = actor->GetOwner(); diff --git a/source/games/blood/src/mirrors.cpp b/source/games/blood/src/mirrors.cpp index cd12a683c..d97447f0f 100644 --- a/source/games/blood/src/mirrors.cpp +++ b/source/games/blood/src/mirrors.cpp @@ -113,7 +113,7 @@ void InitMirrors(void) auto secti = §or[i]; if (secti->floorpicnum == 504) { - auto link = static_cast(secti->upperLink); + auto link = barrier_cast(secti->upperLink); if (link == nullptr) continue; auto link2 = link->GetOwner(); diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 7e05fa504..d3522a40a 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -2840,7 +2840,7 @@ void usePropertiesChanger(DBloodActor* sourceactor, int objType, sectortype* pSe spritetype* pUpper = NULL; XSPRITE* pXUpper = NULL; - auto aLower = static_cast(pSector->lowerLink); + auto aLower = barrier_cast(pSector->lowerLink); spritetype* pLower = nullptr; XSPRITE* pXLower = nullptr; if (aLower) @@ -2851,7 +2851,7 @@ void usePropertiesChanger(DBloodActor* sourceactor, int objType, sectortype* pSe // must be sure we found exact same upper link for (auto& sec : sectors()) { - auto aUpper = static_cast(sec.upperLink); + auto aUpper = barrier_cast(sec.upperLink); if (aUpper == nullptr || aUpper->x().data1 != pXLower->data1) continue; pUpper = &aUpper->s(); pXUpper = &aUpper->x(); @@ -3016,14 +3016,14 @@ void useTeleportTarget(DBloodActor* sourceactor, DBloodActor* actor) if (pXSector->Underwater) { - auto aLink = static_cast(pSource->sector()->lowerLink); + auto aLink = barrier_cast(pSource->sector()->lowerLink); spritetype* pLink = nullptr; if (aLink) { // must be sure we found exact same upper link for(auto& sec : sectors()) { - auto aUpper = static_cast(sec.upperLink); + auto aUpper = barrier_cast(sec.upperLink); if (aUpper == nullptr || aUpper->x().data1 != aLink->x().data1) continue; pLink = &aLink->s(); break; diff --git a/source/games/blood/src/warp.cpp b/source/games/blood/src/warp.cpp index 6e17dc5a1..243a9c9ca 100644 --- a/source/games/blood/src/warp.cpp +++ b/source/games/blood/src/warp.cpp @@ -163,7 +163,7 @@ void warpInit(TArray& actors) for(auto& sect : sectors()) { - auto actor = static_cast(sect.upperLink); + auto actor = barrier_cast(sect.upperLink); if (actor && actor->hasX()) { spritetype *pSprite = &actor->s(); @@ -171,7 +171,7 @@ void warpInit(TArray& actors) int nLink = pXSprite->data1; for(auto& sect : sectors()) { - auto actor2 = static_cast(sect.lowerLink); + auto actor2 = barrier_cast(sect.lowerLink); if (actor2 && actor2->hasX()) { spritetype *pSprite2 = &actor2->s(); @@ -192,8 +192,8 @@ int CheckLink(DBloodActor *actor) { auto pSprite = &actor->s(); auto pSector = pSprite->sector(); - auto aUpper = static_cast(pSector->upperLink); - auto aLower = static_cast(pSector->lowerLink); + auto aUpper = barrier_cast(pSector->upperLink); + auto aLower = barrier_cast(pSector->lowerLink); if (aUpper) { spritetype* pUpper = &aUpper->s(); @@ -253,8 +253,8 @@ int CheckLink(DBloodActor *actor) int CheckLink(int *x, int *y, int *z, sectortype** pSector) { - auto upper = static_cast((*pSector)->upperLink); - auto lower = static_cast((*pSector)->lowerLink); + auto upper = barrier_cast((*pSector)->upperLink); + auto lower = barrier_cast((*pSector)->lowerLink); if (upper) { spritetype *pUpper = &upper->s(); diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 385cf6c71..d7d9580a0 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -3072,7 +3072,7 @@ HORIZONLY: psectp = s->sector(); if (ud.clipping == 0 && psectp->lotag == 31) { - auto secact = static_cast(psectp->hitagactor); + auto secact = barrier_cast(psectp->hitagactor); if (secact && secact->s->xvel && secact->temp_data[0] == 0) { quickkill(p); diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 5688d9306..55cc9ecac 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -3909,7 +3909,7 @@ HORIZONLY: psectp = s->sector(); if (ud.clipping == 0 && psectp->lotag == ST_31_TWO_WAY_TRAIN) { - auto act = static_cast(psectp->hitagactor); + auto act = barrier_cast(psectp->hitagactor); if (act && act->s->xvel && act->temp_data[0] == 0) { quickkill(p); diff --git a/source/games/duke/src/sectors.cpp b/source/games/duke/src/sectors.cpp index a2b609eed..765645de8 100644 --- a/source/games/duke/src/sectors.cpp +++ b/source/games/duke/src/sectors.cpp @@ -980,7 +980,7 @@ void operatesectors(sectortype* sptr, DDukeActor *actor) case ST_30_ROTATE_RISE_BRIDGE: { - auto act = static_cast(sptr->hitagactor); + auto act = barrier_cast(sptr->hitagactor); if (!act) break; if (act->tempang == 0 || act->tempang == 256) callsound(sptr, actor); if (act->s->extra == 1) act->s->extra = 3; @@ -990,7 +990,7 @@ void operatesectors(sectortype* sptr, DDukeActor *actor) case ST_31_TWO_WAY_TRAIN: { - auto act = static_cast(sptr->hitagactor); + auto act = barrier_cast(sptr->hitagactor); if (!act) break; if (act->temp_data[4] == 0) act->temp_data[4] = 1;