From 8dde6a30742ce995f219f3efd515cd7ac8528045 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Dec 2021 18:53:02 +0100 Subject: [PATCH] - Added GC support to Exhumed --- source/core/actorlist.cpp | 6 ++- source/games/exhumed/src/aistuff.h | 18 +++---- source/games/exhumed/src/anims.cpp | 3 +- source/games/exhumed/src/anubis.cpp | 2 +- source/games/exhumed/src/bullet.cpp | 27 +++++++--- source/games/exhumed/src/engine.h | 2 - source/games/exhumed/src/exhumed.cpp | 39 +++++++++++++- source/games/exhumed/src/exhumed.h | 3 +- source/games/exhumed/src/exhumedactor.h | 2 +- source/games/exhumed/src/fish.cpp | 2 +- source/games/exhumed/src/grenade.cpp | 2 +- source/games/exhumed/src/gun.cpp | 2 +- source/games/exhumed/src/init.cpp | 5 -- source/games/exhumed/src/input.cpp | 9 ++++ source/games/exhumed/src/input.h | 2 +- source/games/exhumed/src/items.cpp | 10 +++- source/games/exhumed/src/lavadude.cpp | 2 +- source/games/exhumed/src/lighting.cpp | 28 ++++++---- source/games/exhumed/src/lion.cpp | 2 +- source/games/exhumed/src/move.cpp | 38 ++++++++----- source/games/exhumed/src/mummy.cpp | 4 +- source/games/exhumed/src/object.cpp | 29 +++++++--- source/games/exhumed/src/player.cpp | 36 +++++++++---- source/games/exhumed/src/player.h | 10 ++-- source/games/exhumed/src/queen.cpp | 72 +++++++++++++++++-------- source/games/exhumed/src/ra.cpp | 22 ++++++-- source/games/exhumed/src/ramses.cpp | 2 +- source/games/exhumed/src/rat.cpp | 6 +-- source/games/exhumed/src/rex.cpp | 2 +- source/games/exhumed/src/roach.cpp | 2 +- source/games/exhumed/src/runlist.cpp | 72 +++++-------------------- source/games/exhumed/src/set.cpp | 4 +- source/games/exhumed/src/snake.cpp | 26 ++++++--- source/games/exhumed/src/spider.cpp | 2 +- source/games/exhumed/src/view.cpp | 9 ++-- source/games/exhumed/src/view.h | 2 +- 36 files changed, 308 insertions(+), 196 deletions(-) diff --git a/source/core/actorlist.cpp b/source/core/actorlist.cpp index cc499ee15..75ff3b5a7 100644 --- a/source/core/actorlist.cpp +++ b/source/core/actorlist.cpp @@ -65,6 +65,7 @@ TArray checked; static bool ValidateStatList(int statnum) { +#if 0 checked.Clear(); for (auto entry = statList[statnum].firstEntry; entry; entry = entry->nextStat) { @@ -75,6 +76,7 @@ static bool ValidateStatList(int statnum) assert(entry->prevStat == nullptr || entry->prevStat->nextStat == entry); assert(entry->nextStat == nullptr || entry->nextStat->prevStat == entry); } +#endif return true; } @@ -197,6 +199,7 @@ int ChangeActorStat(DCoreActor* actor, int statnum, bool tail) static bool ValidateSectList(sectortype* sect, DCoreActor *checkme = nullptr) { +#if 0 assert(sect); checked.Clear(); assert(sect->firstEntry == nullptr || sect->firstEntry->prevSect == nullptr); @@ -211,6 +214,7 @@ static bool ValidateSectList(sectortype* sect, DCoreActor *checkme = nullptr) assert(entry->prevSect == nullptr || entry->prevSect->nextSect == entry); assert(entry->nextSect == nullptr || entry->nextSect->prevSect == entry); } +#endif return true; } @@ -330,8 +334,6 @@ static void InsertActorSect(DCoreActor* actor, sectortype* sector, bool tail) void ChangeActorSect(DCoreActor* actor, sectortype* sect, bool tail) { if (sect == nullptr) return; - auto old_sect = actor->link_sector; - assert(actor->s().insector()); RemoveActorSect(actor); InsertActorSect(actor, sect, tail); } diff --git a/source/games/exhumed/src/aistuff.h b/source/games/exhumed/src/aistuff.h index 9f1cca96e..df45563ff 100644 --- a/source/games/exhumed/src/aistuff.h +++ b/source/games/exhumed/src/aistuff.h @@ -198,7 +198,7 @@ void FuncLion(int, int, int, int); // 16 bytes struct BlockInfo { - DExhumedActor* pActor; + TObjPtr pActor; int x; int y; int field_8; @@ -206,8 +206,8 @@ struct BlockInfo extern BlockInfo sBlockInfo[]; extern Collision hiHit; -extern DExhumedActor* nChunkSprite[]; -extern DExhumedActor* nBodySprite[]; +extern TObjPtr nChunkSprite[]; +extern TObjPtr nBodySprite[]; signed int lsqrt(int a1); void MoveThings(); @@ -259,7 +259,7 @@ extern int bTorch; extern int nSmokeSparks; extern int nDronePitch; extern int lFinaleStart; -extern DExhumedActor* pFinaleSpr; +extern TObjPtr pFinaleSpr; void InitObjects(); void InitElev(); @@ -305,8 +305,8 @@ void FuncQueen(int, int, int, int); struct RA { - DExhumedActor* pActor; - DExhumedActor* pTarget; + TObjPtr pActor; + TObjPtr pTarget; int16_t nAction; int16_t nFrame; @@ -352,7 +352,7 @@ struct RunStruct { int nAIType; // todo later: replace this with an AI pointer int nObjIndex; // If object is a non-actor / not refactored yet. - DExhumedActor* pObjActor; // If object is an actor + TObjPtr pObjActor; // If object is an actor int next; int prev; }; @@ -715,8 +715,8 @@ enum { kSnakeSprites = 8 }; // or rename to kSnakeParts? // 32bytes struct Snake { - DExhumedActor* pEnemy; // nRun - DExhumedActor* pSprites[kSnakeSprites]; + TObjPtr pEnemy; // nRun + TObjPtr pSprites[kSnakeSprites]; int16_t nCountdown; int16_t nRun; diff --git a/source/games/exhumed/src/anims.cpp b/source/games/exhumed/src/anims.cpp index e8b1867e4..ba6efb11a 100644 --- a/source/games/exhumed/src/anims.cpp +++ b/source/games/exhumed/src/anims.cpp @@ -28,7 +28,6 @@ BEGIN_PS_NS int nMagicSeq = -1; int nPreMagicSeq = -1; int nSavePointSeq = -1; -//FreeListArray AnimList; void SerializeAnim(FSerializer& arc) @@ -138,7 +137,7 @@ void AIAnim::Tick(RunListEvent* ev) if (pSprite->statnum == kStatIgnited) { - auto pIgniter = pActor->pTarget; + DExhumedActor* pIgniter = pActor->pTarget; if (pIgniter) { diff --git a/source/games/exhumed/src/anubis.cpp b/source/games/exhumed/src/anubis.cpp index 768ead339..30af8ef39 100644 --- a/source/games/exhumed/src/anubis.cpp +++ b/source/games/exhumed/src/anubis.cpp @@ -136,7 +136,7 @@ void AIAnubis::Tick(RunListEvent* ev) bVal = true; } - auto pTarget = ap->pTarget; + DExhumedActor* pTarget = ap->pTarget; int nFrame = SeqBase[nSeq] + ap->nFrame; int nFlag = FrameFlag[nFrame]; diff --git a/source/games/exhumed/src/bullet.cpp b/source/games/exhumed/src/bullet.cpp index aa7072724..2706bbdd2 100644 --- a/source/games/exhumed/src/bullet.cpp +++ b/source/games/exhumed/src/bullet.cpp @@ -34,8 +34,8 @@ enum { kMaxBullets = 500 }; // 32 bytes struct Bullet { - DExhumedActor* pActor; - DExhumedActor* pEnemy; + TObjPtr pActor; + TObjPtr pEnemy; int16_t nSeq; int16_t nFrame; @@ -56,6 +56,16 @@ FreeListArray BulletList; int lasthitz, lasthitx, lasthity; sectortype* lasthitsect; +size_t MarkBullets() +{ + for (int i = 0; i < kMaxBullets; i++) + { + GC::Mark(BulletList[i].pActor); + GC::Mark(BulletList[i].pEnemy); + } + return 2 * kMaxBullets; +} + int nRadialBullet = 0; FSerializer& Serialize(FSerializer& arc, const char* keyname, Bullet& w, Bullet* def) @@ -138,7 +148,7 @@ int GrabBullet() void DestroyBullet(int nBullet) { - auto pActor = BulletList[nBullet].pActor; + DExhumedActor* pActor = BulletList[nBullet].pActor; auto pSprite = &pActor->s(); runlist_DoSubRunRec(BulletList[nBullet].nRunRec); @@ -223,7 +233,7 @@ void BulletHitsSprite(Bullet *pBullet, DExhumedActor* pBulletActor, DExhumedActo break; } - auto pActor = pBullet->pActor; + DExhumedActor* pActor = pBullet->pActor; spritetype *pSprite = &pActor->s(); if (nStat == kStatAnubisDrum) @@ -307,7 +317,7 @@ int MoveBullet(int nBullet) int nType = pBullet->nType; bulletInfo *pBulletInfo = &BulletInfo[nType]; - auto pActor = BulletList[nBullet].pActor; + DExhumedActor* pActor = BulletList[nBullet].pActor; spritetype *pSprite = &pActor->s(); int x = pSprite->x; @@ -322,7 +332,7 @@ int MoveBullet(int nBullet) if (pBullet->field_10 < 30000) { - auto pEnemyActor = BulletList[nBullet].pEnemy; + DExhumedActor* pEnemyActor = BulletList[nBullet].pEnemy; if (pEnemyActor) { if (!(pEnemyActor->s().cstat & 0x101)) @@ -494,7 +504,8 @@ HITSPRITE: nDamage *= 2; } - runlist_DamageEnemy(EnergyBlocks[pHitWall->nextSector()->extra], pActor, nDamage); + DExhumedActor* eb = EnergyBlocks[pHitWall->nextSector()->extra]; + if (eb) runlist_DamageEnemy(eb, pActor, nDamage); } } } @@ -821,7 +832,7 @@ void AIBullet::Tick(RunListEvent* ev) assert(nBullet >= 0 && nBullet < kMaxBullets); int nSeq = SeqOffsets[BulletList[nBullet].nSeq]; - auto pActor = BulletList[nBullet].pActor; + DExhumedActor* pActor = BulletList[nBullet].pActor; auto pSprite = &pActor->s(); int nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].nFrame]; diff --git a/source/games/exhumed/src/engine.h b/source/games/exhumed/src/engine.h index 9dd7c011f..4538fa526 100644 --- a/source/games/exhumed/src/engine.h +++ b/source/games/exhumed/src/engine.h @@ -60,10 +60,8 @@ extern int16_t inita; extern sectortype* initsectp; extern int nCurChunkNum; -extern DExhumedActor* nBodyGunSprite[50]; extern int movefifoend; extern int movefifopos; -extern int nCurBodyGunNum; // all static counters combined in an array for easier maintenance. enum ECounter diff --git a/source/games/exhumed/src/exhumed.cpp b/source/games/exhumed/src/exhumed.cpp index 545851edb..b88a93994 100644 --- a/source/games/exhumed/src/exhumed.cpp +++ b/source/games/exhumed/src/exhumed.cpp @@ -52,11 +52,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS +TObjPtr bestTarget; + IMPLEMENT_CLASS(DExhumedActor, false, true) IMPLEMENT_POINTERS_START(DExhumedActor) IMPLEMENT_POINTER(pTarget) IMPLEMENT_POINTERS_END +size_t MarkMove(); +size_t MarkBullets(); +size_t MarkInput(); +size_t MarkItems(); +size_t MarkLighting(); +size_t MarkObjects(); +size_t MarkPlayers(); +size_t MarkQueen(); +size_t MarkRa(); +size_t MarkSnake(); +size_t MarkRunlist(); + + +static void markgcroots() +{ + size_t num = MarkMove(); + num += MarkBullets(); + num += MarkInput(); + num += MarkItems(); + num += MarkLighting(); + num += MarkObjects(); + num += MarkPlayers(); + num += MarkQueen(); + num += MarkRa(); + num += MarkSnake(); + num += MarkRunlist(); + + GC::Mark(bestTarget); + GC::Mark(pSpiritSprite); + num += 2; + + Printf("%d objects marked\n", num); +} + static MapRecord* NextMap; void uploadCinemaPalettes(); @@ -138,7 +174,6 @@ bool bInDemo = false; bool bSlipMode = false; bool bDoFlashes = true; -DExhumedActor* bestTarget; int nStartLevel; int nTimeLimit; @@ -468,6 +503,8 @@ static void SetTileNames() void GameInterface::app_init() { SetupActors(RUNTIME_CLASS(DExhumedActor)); + GC::AddMarkerFunc(markgcroots); + #if 0 help_disabled = true; diff --git a/source/games/exhumed/src/exhumed.h b/source/games/exhumed/src/exhumed.h index 53881ca23..5b0bb7939 100644 --- a/source/games/exhumed/src/exhumed.h +++ b/source/games/exhumed/src/exhumed.h @@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamestruct.h" #include "names.h" #include "exhumedactor.h" +#include "serialize_obj.h" BEGIN_PS_NS @@ -111,7 +112,7 @@ extern int nEnergyTowers; extern int nEnergyChan; -extern DExhumedActor* pSpiritSprite; +extern TObjPtr pSpiritSprite; extern bool bInDemo; diff --git a/source/games/exhumed/src/exhumedactor.h b/source/games/exhumed/src/exhumedactor.h index 4b716956b..05d0f4cd7 100644 --- a/source/games/exhumed/src/exhumedactor.h +++ b/source/games/exhumed/src/exhumedactor.h @@ -19,7 +19,7 @@ class DExhumedActor : public DCoreActor HAS_OBJECT_POINTERS public: - DExhumedActor* pTarget; + TObjPtr pTarget; int16_t nPhase; diff --git a/source/games/exhumed/src/fish.cpp b/source/games/exhumed/src/fish.cpp index 1359b43a0..fa8c91698 100644 --- a/source/games/exhumed/src/fish.cpp +++ b/source/games/exhumed/src/fish.cpp @@ -342,7 +342,7 @@ void AIFish::Tick(RunListEvent* ev) pActor->nFrame = 0; } - auto pTargetActor = pActor->pTarget; + DExhumedActor* pTargetActor = pActor->pTarget; switch (nAction) { diff --git a/source/games/exhumed/src/grenade.cpp b/source/games/exhumed/src/grenade.cpp index 7cbc33015..0a218b0c7 100644 --- a/source/games/exhumed/src/grenade.cpp +++ b/source/games/exhumed/src/grenade.cpp @@ -52,7 +52,7 @@ void ThrowGrenade(int nPlayer, int, int, int ecx, int push1) if (PlayerList[nPlayer].pPlayerGrenade == nullptr) return; - auto pActor = PlayerList[nPlayer].pPlayerGrenade; + DExhumedActor* pActor = PlayerList[nPlayer].pPlayerGrenade; auto pGrenadeSprite = &pActor->s(); auto pPlayerActor = PlayerList[nPlayer].Actor(); auto pPlayerSprite = &pPlayerActor->s(); diff --git a/source/games/exhumed/src/gun.cpp b/source/games/exhumed/src/gun.cpp index 37d50d208..5ba03db63 100644 --- a/source/games/exhumed/src/gun.cpp +++ b/source/games/exhumed/src/gun.cpp @@ -807,7 +807,7 @@ loc_flag: DExhumedActor* target = nullptr; if (sPlayerInput[nPlayer].pTarget != nullptr && Autoaim(nPlayer)) { - auto t = sPlayerInput[nPlayer].pTarget; + DExhumedActor* t = sPlayerInput[nPlayer].pTarget; // only autoaim if target is in front of the player. auto pTargetSprite = &t->s(); assert(pTargetSprite->sector()); diff --git a/source/games/exhumed/src/init.cpp b/source/games/exhumed/src/init.cpp index f891d125f..e22100698 100644 --- a/source/games/exhumed/src/init.cpp +++ b/source/games/exhumed/src/init.cpp @@ -45,12 +45,9 @@ sectortype* initsectp; int nCurChunkNum = 0; -DExhumedActor* nBodyGunSprite[50]; int movefifoend; int movefifopos; -int nCurBodyGunNum; - int Counters[kNumCounters]; @@ -846,8 +843,6 @@ void SerializeInit(FSerializer& arc) ("inita", inita) ("initsect", initsectp) ("curchunk", nCurChunkNum) - .Array("bodygunsprite", nBodyGunSprite, countof(nBodyGunSprite)) - ("curbodygun", nCurBodyGunNum) .Array("counters", Counters, kNumCounters) .EndObject(); } diff --git a/source/games/exhumed/src/input.cpp b/source/games/exhumed/src/input.cpp index 985a041c4..806c87e20 100644 --- a/source/games/exhumed/src/input.cpp +++ b/source/games/exhumed/src/input.cpp @@ -27,6 +27,15 @@ BEGIN_PS_NS PlayerInput sPlayerInput[kMaxPlayers]; +size_t MarkInput() +{ + for (auto& p : sPlayerInput) + { + GC::Mark(p.pTarget); + } + return kMaxPlayers; +} + void ClearSpaceBar(int nPlayer) { sPlayerInput[nPlayer].actions &= SB_OPEN; diff --git a/source/games/exhumed/src/input.h b/source/games/exhumed/src/input.h index fb762bb5e..b60072809 100644 --- a/source/games/exhumed/src/input.h +++ b/source/games/exhumed/src/input.h @@ -32,7 +32,7 @@ enum { // 32 bytes struct PlayerInput { - DExhumedActor* pTarget; + TObjPtr pTarget; int xVel; int yVel; uint16_t buttons; diff --git a/source/games/exhumed/src/items.cpp b/source/games/exhumed/src/items.cpp index b2676d924..30baeb86e 100644 --- a/source/games/exhumed/src/items.cpp +++ b/source/games/exhumed/src/items.cpp @@ -98,9 +98,15 @@ AnimInfo nItemAnimInfo[] = { const int16_t nItemMagic[] = { 500, 1000, 100, 500, 400, 200, 700, 0 }; -TArray Regenerates; +TArray Regenerates; // must handle read barriers manually! int nMagicCount; +size_t MarkItems() +{ + GC::MarkArray(Regenerates); + return Regenerates.Size(); +} + void SerializeItems(FSerializer& arc) { if (arc.BeginObject("items")) @@ -395,7 +401,7 @@ void DoRegenerates() { for(unsigned i = 0; i < Regenerates.Size(); i++) { - auto pActor = Regenerates[i]; + DExhumedActor* pActor = GC::ReadBarrier(Regenerates[i]); auto pSprite = &pActor->s(); if (pSprite->extra > 0) { diff --git a/source/games/exhumed/src/lavadude.cpp b/source/games/exhumed/src/lavadude.cpp index 643ef91f7..08394cb0b 100644 --- a/source/games/exhumed/src/lavadude.cpp +++ b/source/games/exhumed/src/lavadude.cpp @@ -255,7 +255,7 @@ void AILavaDude::Tick(RunListEvent* ev) } } - auto pTarget = pActor->pTarget; + DExhumedActor* pTarget = pActor->pTarget; if (pTarget && nAction < 4) { diff --git a/source/games/exhumed/src/lighting.cpp b/source/games/exhumed/src/lighting.cpp index b3bcac95e..b1c6f3027 100644 --- a/source/games/exhumed/src/lighting.cpp +++ b/source/games/exhumed/src/lighting.cpp @@ -42,7 +42,7 @@ struct Flash { walltype* pWall; sectortype* pSector; - DExhumedActor* pActor; + TObjPtr pActor; }; int next; int8_t nType; @@ -100,6 +100,15 @@ int nGlowCount; int bDoFlicks = 0; int bDoGlows = 0; +size_t MarkLighting() +{ + for (int i = 0; i < kMaxFlashes; i++) + { + auto& f = sFlash[i]; + if (f.nType & 4) GC::Mark(f.pActor); + } + return kMaxFlashes; +} FSerializer& Serialize(FSerializer& arc, const char* keyname, Flash& w, Flash* def) { @@ -442,12 +451,10 @@ void UndoFlashes() case 3: { - auto ac = pFlash->pActor; - if (!ac) continue; - auto sp = &ac->s(); - if (sp->pal >= 7) + DExhumedActor* ac = pFlash->pActor; + if (ac && ac->spr.pal >= 7) { - pShade = &sp->shade; + pShade = &ac->spr.shade; } else { goto loc_1868A; @@ -505,12 +512,11 @@ void UndoFlashes() case 3: { - auto ac = pFlash->pActor; - auto sp = &ac->s(); - if (sp->pal >= 7) + DExhumedActor* ac = pFlash->pActor; + if (ac && ac->spr.pal >= 7) { - sp->pal -= 7; - sp->shade = pFlash->shade; + ac->spr.pal -= 7; + ac->spr.shade = pFlash->shade; } break; diff --git a/source/games/exhumed/src/lion.cpp b/source/games/exhumed/src/lion.cpp index 71502108b..6d21129b9 100644 --- a/source/games/exhumed/src/lion.cpp +++ b/source/games/exhumed/src/lion.cpp @@ -222,7 +222,7 @@ void AILion::Tick(RunListEvent* ev) } int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame]; - auto pTarget = pActor->pTarget; + DExhumedActor* pTarget = pActor->pTarget; auto nMov = MoveCreatureWithCaution(pActor); diff --git a/source/games/exhumed/src/move.cpp b/source/games/exhumed/src/move.cpp index f97c9414d..b26c88bee 100644 --- a/source/games/exhumed/src/move.cpp +++ b/source/games/exhumed/src/move.cpp @@ -35,21 +35,33 @@ int nPushBlocks; // TODO - moveme? sectortype* overridesect; -DExhumedActor* nBodySprite[50]; +enum +{ + kMaxPushBlocks = 100, + kMaxMoveChunks = 75 +}; + + +TObjPtr nBodySprite[50]; +TObjPtr nChunkSprite[kMaxMoveChunks]; +BlockInfo sBlockInfo[kMaxPushBlocks]; +TObjPtr nBodyGunSprite[50]; +int nCurBodyGunNum; int sprceiling, sprfloor; Collision loHit, hiHit; -enum -{ - kMaxPushBlocks = 100, - kMaxMoveChunks = 75 -}; - // think this belongs in init.c? -BlockInfo sBlockInfo[kMaxPushBlocks]; -DExhumedActor *nChunkSprite[kMaxMoveChunks]; + +size_t MarkMove() +{ + GC::MarkArray(nBodySprite, 50); + GC::MarkArray(nChunkSprite, kMaxMoveChunks); + for(int i = 0; i < nPushBlocks; i++) + GC::Mark(sBlockInfo[i].pActor); + return 50 + kMaxMoveChunks + nPushBlocks; +} FSerializer& Serialize(FSerializer& arc, const char* keyname, BlockInfo& w, BlockInfo* def) { @@ -73,7 +85,9 @@ void SerializeMove(FSerializer& arc) ("chunkcount", nCurChunkNum) .Array("chunks", nChunkSprite, kMaxMoveChunks) ("overridesect", overridesect) - .Array("bodysprite", nBodySprite, 50) + .Array("bodysprite", nBodySprite, countof(nBodySprite)) + ("curbodygun", nCurBodyGunNum) + .Array("bodygunsprite", nBodyGunSprite, countof(nBodyGunSprite)) .EndObject(); } } @@ -1281,7 +1295,7 @@ void InitChunks() DExhumedActor* GrabBodyGunSprite() { - auto pActor = nBodyGunSprite[nCurBodyGunNum]; + DExhumedActor* pActor = nBodyGunSprite[nCurBodyGunNum]; spritetype* pSprite; if (pActor == nullptr) { @@ -1346,7 +1360,7 @@ DExhumedActor* GrabBody() DExhumedActor* GrabChunkSprite() { - auto pActor = nChunkSprite[nCurChunkNum]; + DExhumedActor* pActor = nChunkSprite[nCurChunkNum]; if (pActor == nullptr) { diff --git a/source/games/exhumed/src/mummy.cpp b/source/games/exhumed/src/mummy.cpp index 1efea44e5..c47049d1f 100644 --- a/source/games/exhumed/src/mummy.cpp +++ b/source/games/exhumed/src/mummy.cpp @@ -128,7 +128,9 @@ void AIMummy::Tick(RunListEvent* ev) auto pActor = ev->pObjActor; if (!pActor) return; - auto pTarget = UpdateEnemy(&pActor->pTarget); + DExhumedActor* targ = pActor->pTarget; + auto pTarget = UpdateEnemy(&targ); + pActor->pTarget = targ; auto pSprite = &pActor->s(); int nAction = pActor->nAction; diff --git a/source/games/exhumed/src/object.cpp b/source/games/exhumed/src/object.cpp index 9d8650e7d..79d208829 100644 --- a/source/games/exhumed/src/object.cpp +++ b/source/games/exhumed/src/object.cpp @@ -67,14 +67,14 @@ struct Bob struct Drip { - DExhumedActor* pActor; + TObjPtr pActor; int16_t nCount; }; // 56 bytes struct Elev { - DExhumedActor* pActor; + TObjPtr pActor; sectortype* pSector; int16_t nFlags; int16_t nChannel; @@ -110,7 +110,7 @@ struct wallFace struct slideData { - DExhumedActor* pActor; + TObjPtr pActor; int16_t nChannel; int16_t nStart; int16_t nRunRec; @@ -142,7 +142,7 @@ struct Point struct Trap { - DExhumedActor* pActor; + TObjPtr pActor; walltype* pWall1; walltype* pWall2; @@ -167,11 +167,22 @@ TArray SlideData; TArray WallFace; TArray sDrip; TArray EnergyBlocks; +TObjPtr pFinaleSpr; + +size_t MarkObjects() +{ + GC::Mark(pFinaleSpr); + for (auto& d : sDrip) GC::Mark(d.pActor); + for (auto& d : sTrap) GC::Mark(d.pActor); + for (auto& d : Elevator) GC::Mark(d.pActor); + for (auto& d : SlideData) GC::Mark(d.pActor); + GC::MarkArray(EnergyBlocks); + return 1 + sDrip.Size() + sTrap.Size() + Elevator.Size() + SlideData.Size(); +} int lFinaleStart; int nFinaleStage; -DExhumedActor* pFinaleSpr; int nDronePitch = 0; int nSmokeSparks = 0; @@ -751,7 +762,7 @@ void AIElev::Tick(RunListEvent* ev) assert(nChannel >= 0 && nChannel < kMaxChannels); auto pSector =Elevator[nElev].pSector; - auto pElevSpr = Elevator[nElev].pActor; + DExhumedActor* pElevSpr = Elevator[nElev].pActor; int ebp = 0; // initialise to *something* @@ -1274,7 +1285,8 @@ void AITrap::ProcessChannel(RunListEvent* ev) void AITrap::Tick(RunListEvent* ev) { int nTrap = RunData[ev->nRun].nObjIndex; - auto pActor = sTrap[nTrap].pActor; + DExhumedActor* pActor = sTrap[nTrap].pActor; + if (!pActor) return; auto pSprite = &pActor->s(); if (sTrap[nTrap].nState >= 0) @@ -2120,7 +2132,8 @@ void DoDrips() sDrip[i].nCount--; if (sDrip[i].nCount <= 0) { - auto pActor = sDrip[i].pActor; + DExhumedActor* pActor = sDrip[i].pActor; + if (!pActor) continue; auto pSprite = &pActor->s(); int nSeqOffset = SeqOffsets[kSeqDrips]; diff --git a/source/games/exhumed/src/player.cpp b/source/games/exhumed/src/player.cpp index 45c8964c8..7eca01de5 100644 --- a/source/games/exhumed/src/player.cpp +++ b/source/games/exhumed/src/player.cpp @@ -77,7 +77,7 @@ int nLocalPlayer = 0; Player PlayerList[kMaxPlayers]; -DExhumedActor* nNetStartSprite[kMaxPlayers] = { }; +TObjPtr nNetStartSprite[kMaxPlayers] = { }; int nStandHeight; @@ -87,6 +87,20 @@ int PlayerCount; int nNetStartSprites; int nCurStartSprite; + +size_t MarkPlayers() +{ + for (auto& p : PlayerList) + { + GC::Mark(p.pActor); + GC::Mark(p.pDoppleSprite); + GC::Mark(p.pPlayerFloorSprite); + GC::Mark(p.pPlayerGrenade); + } + GC::MarkArray(nNetStartSprite, kMaxPlayers); + return 5 * kMaxPlayers; +} + void SetSavePoint(int nPlayer, int x, int y, int z, sectortype* pSector, int nAngle) { PlayerList[nPlayer].sPlayerSave.x = x; @@ -206,7 +220,7 @@ void RestartPlayer(int nPlayer) { auto plr = &PlayerList[nPlayer]; auto pActor = plr->Actor(); - auto pDopSprite = plr->pDoppleSprite; + DExhumedActor* pDopSprite = plr->pDoppleSprite; DExhumedActor* floorsprt; @@ -220,7 +234,7 @@ void RestartPlayer(int nPlayer) plr->pActor = nullptr; - auto pFloorSprite = plr->pPlayerFloorSprite; + DExhumedActor* pFloorSprite = plr->pPlayerFloorSprite; if (pFloorSprite != nullptr) { DeleteActor(pFloorSprite); } @@ -245,7 +259,7 @@ void RestartPlayer(int nPlayer) if (nTotalPlayers > 1) { - auto nNStartSprite = nNetStartSprite[nCurStartSprite]; + DExhumedActor* nNStartSprite = nNetStartSprite[nCurStartSprite]; auto nstspr = &nNStartSprite->s(); nCurStartSprite++; @@ -548,7 +562,7 @@ int AddAmmo(int nPlayer, int nWeapon, int nAmmoAmount) void SetPlayerMummified(int nPlayer, int bIsMummified) { - auto pActor = PlayerList[nPlayer].pActor; + DExhumedActor* pActor = PlayerList[nPlayer].pActor; auto pSprite = &pActor->s(); pSprite->yvel = 0; @@ -633,13 +647,13 @@ void AIPlayer::Damage(RunListEvent* ev) auto pPlayerActor = PlayerList[nPlayer].Actor(); int nAction = PlayerList[nPlayer].nAction; auto pPlayerSprite = &pPlayerActor->s(); - auto pDopple = PlayerList[nPlayer].pDoppleSprite; + DExhumedActor* pDopple = PlayerList[nPlayer].pDoppleSprite; if (!nDamage) { return; } - DExhumedActor* pActor2 = (!ev->isRadialEvent()) ? ev->pOtherActor : ev->pRadialActor->pTarget; + DExhumedActor* pActor2 = (!ev->isRadialEvent()) ? ev->pOtherActor : ev->pRadialActor->pTarget.Get(); // ok continue case 0x80000 as normal, loc_1C57C if (!PlayerList[nPlayer].nHealth) { @@ -744,7 +758,7 @@ void AIPlayer::Tick(RunListEvent* ev) auto pPlayerActor = PlayerList[nPlayer].Actor(); auto pPlayerSprite = &pPlayerActor->s(); - auto pDopple = PlayerList[nPlayer].pDoppleSprite; + DExhumedActor* pDopple = PlayerList[nPlayer].pDoppleSprite; int nAction = PlayerList[nPlayer].nAction; int nActionB = PlayerList[nPlayer].nAction; @@ -803,7 +817,7 @@ void AIPlayer::Tick(RunListEvent* ev) if (PlayerList[nPlayer].nInvisible == 0) { pPlayerSprite->cstat &= 0x7FFF; // set visible - auto pFloorSprite = PlayerList[nPlayer].pPlayerFloorSprite; + DExhumedActor* pFloorSprite = PlayerList[nPlayer].pPlayerFloorSprite; if (pFloorSprite != nullptr) { pFloorSprite->s().cstat &= 0x7FFF; // set visible @@ -1049,7 +1063,7 @@ void AIPlayer::Tick(RunListEvent* ev) { PlayerList[nPlayer].nPlayerPushSound = 1; int nBlock = PlayerList[nPlayer].pPlayerPushSect->extra; - auto pBlockActor = sBlockInfo[nBlock].pActor; + DExhumedActor* pBlockActor = sBlockInfo[nBlock].pActor; D3PlayFX(StaticSound[kSound23], pBlockActor, 0x4000); } @@ -1274,7 +1288,7 @@ sectdone: } // loc_1B1EB - auto pFloorActor = PlayerList[nPlayer].pPlayerFloorSprite; + DExhumedActor* pFloorActor = PlayerList[nPlayer].pPlayerFloorSprite; if (nTotalPlayers > 1 && pFloorActor) { auto pFloorSprite = &pFloorActor->s(); diff --git a/source/games/exhumed/src/player.h b/source/games/exhumed/src/player.h index 52616a488..4eb110d3f 100644 --- a/source/games/exhumed/src/player.h +++ b/source/games/exhumed/src/player.h @@ -55,7 +55,7 @@ struct PlayerSave struct Player { DExhumedActor* Actor() { return pActor; } - DExhumedActor* pActor; + TObjPtr pActor; int16_t nHealth; int16_t nLives; int16_t nDouble; @@ -108,9 +108,9 @@ struct Player int ototalvel; int totalvel; int16_t eyelevel, oeyelevel; - DExhumedActor* pPlayerGrenade; - DExhumedActor* pPlayerFloorSprite; - DExhumedActor* pDoppleSprite; + TObjPtr pPlayerGrenade; + TObjPtr pPlayerFloorSprite; + TObjPtr pDoppleSprite; }; @@ -120,7 +120,7 @@ extern Player PlayerList[kMaxPlayers]; extern int obobangle, bobangle; -extern DExhumedActor* nNetStartSprite[kMaxPlayers]; +extern TObjPtr nNetStartSprite[kMaxPlayers]; extern int nNetStartSprites; extern int nCurStartSprite; diff --git a/source/games/exhumed/src/queen.cpp b/source/games/exhumed/src/queen.cpp index deffe03d4..b0de01dcb 100644 --- a/source/games/exhumed/src/queen.cpp +++ b/source/games/exhumed/src/queen.cpp @@ -70,8 +70,8 @@ static actionSeq EggSeq[] = { struct Queen { - DExhumedActor* pActor; - DExhumedActor* pTarget; + TObjPtr pActor; + TObjPtr pTarget; int16_t nHealth; int16_t nFrame; int16_t nAction; @@ -83,8 +83,8 @@ struct Queen struct Egg { - DExhumedActor* pActor; - DExhumedActor* pTarget; + TObjPtr pActor; + TObjPtr pTarget; int16_t nHealth; int16_t nFrame; int16_t nAction; @@ -94,8 +94,8 @@ struct Egg struct Head { - DExhumedActor* pActor; - DExhumedActor* pTarget; + TObjPtr pActor; + TObjPtr pTarget; int16_t nHealth; int16_t nFrame; int16_t nAction; @@ -112,7 +112,7 @@ int nQHead = 0; int nHeadVel; int nVelShift; -DExhumedActor* tailspr[kMaxTails]; +TObjPtr tailspr[kMaxTails]; Queen QueenList[kMaxQueens]; @@ -124,6 +124,21 @@ int MoveQZ[25]; sectortype* MoveQS[25]; int16_t MoveQA[25]; + +size_t MarkQueen() +{ + GC::Mark(QueenList[0].pActor); + GC::Mark(QueenList[0].pTarget); + GC::Mark(QueenHead.pActor); + GC::Mark(QueenHead.pTarget); + for (int i = 0; i < kMaxEggs; i++) + { + GC::Mark(QueenEgg[i].pActor); + GC::Mark(QueenEgg[i].pTarget); + } + return 4 + 2 * kMaxEggs; +} + FSerializer& Serialize(FSerializer& arc, const char* keyname, Queen& w, Queen* def) { if (arc.BeginObject(keyname)) @@ -229,7 +244,8 @@ void BlowChunks(DExhumedActor* pActor) void DestroyEgg(int nEgg) { - auto pActor = QueenEgg[nEgg].pActor; + DExhumedActor* pActor = QueenEgg[nEgg].pActor; + if (!pActor) return; auto pSprite = &pActor->s(); if (QueenEgg[nEgg].nAction != 4) @@ -360,7 +376,8 @@ int DestroyTailPart() return 0; } - auto pActor = tailspr[--QueenHead.nIndex2]; + DExhumedActor* pActor = tailspr[--QueenHead.nIndex2]; + if (!pActor) return 0; BlowChunks(pActor); BuildExplosion(pActor); @@ -430,7 +447,8 @@ void BuildQueenEgg(int nQueen, int nVal) return; } - auto pActor = QueenList[nQueen].pActor; + DExhumedActor* pActor = QueenList[nQueen].pActor; + if (!pActor) return; auto pSprite = &pActor->s(); int x = pSprite->x; @@ -500,7 +518,8 @@ void AIQueenEgg::Tick(RunListEvent* ev) { int nEgg = RunData[ev->nRun].nObjIndex; Egg* pEgg = &QueenEgg[nEgg]; - auto pActor = pEgg->pActor; + DExhumedActor* pActor = pEgg->pActor; + if (!pActor) return; auto pSprite = &pActor->s(); int nAction = pEgg->nAction; @@ -533,7 +552,9 @@ void AIQueenEgg::Tick(RunListEvent* ev) bVal = true; } - pTarget = UpdateEnemy(&pEgg->pActor); + DExhumedActor* enemy = pEgg->pActor; + pTarget = UpdateEnemy(&enemy); + pEgg->pActor = enemy; pEgg->pTarget = pTarget; if (pTarget && (pTarget->s().cstat & 0x101) == 0) @@ -655,7 +676,8 @@ void AIQueenEgg::RadialDamage(RunListEvent* ev) { int nEgg = RunData[ev->nRun].nObjIndex; Egg* pEgg = &QueenEgg[nEgg]; - auto pActor = pEgg->pActor; + DExhumedActor* pActor = pEgg->pActor; + if (!pActor) return; auto pSprite = &pActor->s(); auto pRadial = &ev->pRadialActor->s(); @@ -690,7 +712,8 @@ void AIQueenEgg::Draw(RunListEvent* ev) void BuildQueenHead(int nQueen) { - auto pActor = QueenList[nQueen].pActor; + DExhumedActor* pActor = QueenList[nQueen].pActor; + if (!pActor) return; auto pSprite = &pActor->s(); int x = pSprite->x; @@ -742,7 +765,8 @@ void BuildQueenHead(int nQueen) void AIQueenHead::Tick(RunListEvent* ev) { - auto pActor = QueenHead.pActor; + DExhumedActor* pActor = QueenHead.pActor; + if (!pActor) return; auto pSprite = &pActor->s(); int nAction = QueenHead.nAction; @@ -766,7 +790,7 @@ void AIQueenHead::Tick(RunListEvent* ev) var_14 = 1; } - auto pTarget = QueenHead.pTarget; + DExhumedActor* pTarget = QueenHead.pTarget; if (pTarget) { @@ -930,7 +954,7 @@ void AIQueenHead::Tick(RunListEvent* ev) } auto headSect = MoveQS[nHd]; - auto pTActor = tailspr[i]; + DExhumedActor* pTActor = tailspr[i]; if (pTActor) { auto pTSprite = &pTActor->s(); @@ -1041,7 +1065,8 @@ void AIQueenHead::RadialDamage(RunListEvent* ev) void AIQueenHead::Damage(RunListEvent* ev) { - auto pActor = QueenHead.pActor; + DExhumedActor* pActor = QueenHead.pActor; + if (!pActor) return; auto pSprite = &pActor->s(); if (QueenHead.nHealth > 0 && ev->nDamage != 0) @@ -1176,11 +1201,12 @@ void AIQueen::Tick(RunListEvent* ev) int nQueen = RunData[ev->nRun].nObjIndex; assert(nQueen >= 0 && nQueen < kMaxQueens); - auto pActor = QueenList[nQueen].pActor; + DExhumedActor* pActor = QueenList[nQueen].pActor; + if (!pActor) return; auto pSprite = &pActor->s(); int nAction = QueenList[nQueen].nAction; int si = QueenList[nQueen].nAction2; - auto pTarget = QueenList[nQueen].pTarget; + DExhumedActor* pTarget = QueenList[nQueen].pTarget; bool bVal = false; @@ -1435,7 +1461,8 @@ void AIQueen::RadialDamage(RunListEvent* ev) { int nQueen = RunData[ev->nRun].nObjIndex; assert(nQueen >= 0 && nQueen < kMaxQueens); - auto pActor = QueenList[nQueen].pActor; + DExhumedActor* pActor = QueenList[nQueen].pActor; + if (!pActor) return; auto pSprite = &pActor->s(); auto pRadial = &ev->pRadialActor->s(); @@ -1451,7 +1478,8 @@ void AIQueen::Damage(RunListEvent* ev) int nQueen = RunData[ev->nRun].nObjIndex; assert(nQueen >= 0 && nQueen < kMaxQueens); - auto pActor = QueenList[nQueen].pActor; + DExhumedActor* pActor = QueenList[nQueen].pActor; + if (!pActor) return; auto pSprite = &pActor->s(); int si = QueenList[nQueen].nAction2; diff --git a/source/games/exhumed/src/ra.cpp b/source/games/exhumed/src/ra.cpp index 4b4cbb39e..a2d14d153 100644 --- a/source/games/exhumed/src/ra.cpp +++ b/source/games/exhumed/src/ra.cpp @@ -37,6 +37,16 @@ static actionSeq RaSeq[] = { {2, 0} }; +size_t MarkRa() +{ + for (auto& r : Ra) + { + GC::Mark(r.pActor); + GC::Mark(r.pTarget); + } + return 2 * kMaxPlayers; +} + FSerializer& Serialize(FSerializer& arc, const char* keyname, RA& w, RA* def) { if (arc.BeginObject(keyname)) @@ -62,7 +72,8 @@ void SerializeRa(FSerializer& arc) void FreeRa(int nPlayer) { int nRun = Ra[nPlayer].nRun; - auto pActor = Ra[nPlayer].pActor; + DExhumedActor* pActor = Ra[nPlayer].pActor; + if (!pActor) return; auto pSprite = &pActor->s(); runlist_SubRunRec(nRun); @@ -70,6 +81,7 @@ void FreeRa(int nPlayer) runlist_FreeRun(pSprite->lotag - 1); DeleteActor(pActor); + Ra[nPlayer] = {}; } void BuildRa(int nPlayer) @@ -112,8 +124,9 @@ void InitRa() void MoveRaToEnemy(int nPlayer) { - auto pTarget = Ra[nPlayer].pTarget; - auto pActor = Ra[nPlayer].pActor; + DExhumedActor* pTarget = Ra[nPlayer].pTarget; + DExhumedActor* pActor = Ra[nPlayer].pActor; + if (!pActor) return; int nAction = Ra[nPlayer].nAction; auto pSprite = &pActor->s(); @@ -171,7 +184,8 @@ void AIRa::Tick(RunListEvent* ev) int nCurrentWeapon = PlayerList[nPlayer].nCurrentWeapon; int nSeq = SeqOffsets[kSeqEyeHit] + RaSeq[Ra[nPlayer].nAction].a; - auto pActor = Ra[nPlayer].pActor; + DExhumedActor* pActor = Ra[nPlayer].pActor; + if (!pActor) return; auto pSprite = &pActor->s(); bool bVal = false; diff --git a/source/games/exhumed/src/ramses.cpp b/source/games/exhumed/src/ramses.cpp index 65c8512c2..191f9eb30 100644 --- a/source/games/exhumed/src/ramses.cpp +++ b/source/games/exhumed/src/ramses.cpp @@ -57,7 +57,7 @@ int word_964EC = 10; int nSpiritRepeatX; int nSpiritRepeatY; -DExhumedActor* pSpiritSprite; +TObjPtr pSpiritSprite; int nPixelsToShow; int nTalkTime = 0; diff --git a/source/games/exhumed/src/rat.cpp b/source/games/exhumed/src/rat.cpp index f2de4ed35..6dcf60a3d 100644 --- a/source/games/exhumed/src/rat.cpp +++ b/source/games/exhumed/src/rat.cpp @@ -138,7 +138,7 @@ DExhumedActor* FindFood(DExhumedActor* pActor) if (nChunkTotal) { - auto pActor2 = nChunkSprite[RandomSize(7) % nChunkTotal]; + DExhumedActor* pActor2 = nChunkSprite[RandomSize(7) % nChunkTotal]; if (pActor2 != nullptr) { auto pSprite2 = &pActor2->s(); @@ -152,7 +152,7 @@ DExhumedActor* FindFood(DExhumedActor* pActor) return nullptr; } - auto pActor2 = nBodySprite[RandomSize(7) % nBodyTotal]; + DExhumedActor* pActor2 = nBodySprite[RandomSize(7) % nBodyTotal]; if (pActor2 != nullptr) { auto pSprite2 = &pActor2->s(); @@ -224,7 +224,7 @@ void AIRat::Tick(RunListEvent* ev) pActor->nFrame = 0; } - auto pTarget = pActor->pTarget; + DExhumedActor* pTarget = pActor->pTarget; Gravity(pActor); diff --git a/source/games/exhumed/src/rex.cpp b/source/games/exhumed/src/rex.cpp index 3974a5fb4..e4557d856 100644 --- a/source/games/exhumed/src/rex.cpp +++ b/source/games/exhumed/src/rex.cpp @@ -198,7 +198,7 @@ void AIRex::Tick(RunListEvent* ev) int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame]; - auto pTarget = pActor->pTarget; + DExhumedActor* pTarget = pActor->pTarget; switch (nAction) { diff --git a/source/games/exhumed/src/roach.cpp b/source/games/exhumed/src/roach.cpp index 54e220cad..e99e7310a 100644 --- a/source/games/exhumed/src/roach.cpp +++ b/source/games/exhumed/src/roach.cpp @@ -206,7 +206,7 @@ void AIRoach::Tick(RunListEvent* ev) } int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame]; - auto pTarget = pActor->pTarget; + DExhumedActor* pTarget = pActor->pTarget; if (nAction > 5) { return; diff --git a/source/games/exhumed/src/runlist.cpp b/source/games/exhumed/src/runlist.cpp index 381b7e07a..32c4d4f92 100644 --- a/source/games/exhumed/src/runlist.cpp +++ b/source/games/exhumed/src/runlist.cpp @@ -48,6 +48,16 @@ RunChannel sRunChannels[kMaxChannels]; FreeListArray RunData; +size_t MarkRunlist() +{ + for (unsigned i = 0; i < kMaxRuns; i++) // only way to catch everything. :( + { + GC::Mark(RunData[i].pObjActor); + } + return kMaxRuns; +} + + FSerializer& Serialize(FSerializer& arc, const char* keyname, RunStruct& w, RunStruct* def) { if (arc.BeginObject(keyname)) @@ -55,8 +65,8 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, RunStruct& w, RunS arc("ref", w.nAIType) ("val", w.nObjIndex) ("actor", w.pObjActor) - ("_4", w.next) - ("_6", w.prev) + ("next", w.next) + ("prev", w.prev) .EndObject(); } return arc; @@ -490,7 +500,6 @@ void runlist_ReadyChannel(int eax) void runlist_ProcessChannels() { -#if 1 int v0; int v1; int v5; @@ -542,63 +551,6 @@ void runlist_ProcessChannels() ChannelList = v1; } while (v1 != -1); -#else - int edi = -1; - int esi = edi; - - while (1) - { - int nChannel = ChannelList; - if (nChannel < 0) - { - ChannelList = esi; - if (esi != -1) - { - edi = -1; - esi = edi; - continue; - } - else { - return; - } - } - - int b = sRunChannels[nChannel].b; - int d = sRunChannels[nChannel].d; - - if (d & 2) - { - sRunChannels[nChannel].d = d ^ 2; - runlist_SignalRun(sRunChannels[nChannel].a, ChannelList, &ExhumedAI::ProcessChannel); - } - - if (d & 1) - { - sRunChannels[nChannel].d = d ^ 1; - runlist_SignalRun(sRunChannels[nChannel].a, 0, &ExhumedAI::Process); - } - - if (sRunChannels[nChannel].d == 0) - { - sRunChannels[ChannelList].b = -1; - } - else - { - if (esi == -1) - { - esi = ChannelList; - edi = esi; - } - else - { - sRunChannels[edi].b = ChannelList; - edi = ChannelList; - } - } - - ChannelList = b; - } -#endif } int runlist_FindChannel(int ax) diff --git a/source/games/exhumed/src/set.cpp b/source/games/exhumed/src/set.cpp index ed9c9582f..d682f9b0e 100644 --- a/source/games/exhumed/src/set.cpp +++ b/source/games/exhumed/src/set.cpp @@ -156,7 +156,7 @@ void AISoul::Tick(RunListEvent* ev) auto coll = movesprite(pActor, bcos(pSprite->ang) * nVel, bsin(pSprite->ang) * nVel, pSprite->zvel, 5120, 0, CLIPMASK0); if (coll.exbits & 0x10000) { - auto pSet = pActor->pTarget; + DExhumedActor* pSet = pActor->pTarget; if (!pSet) return; auto pSetSprite = &pSet->s(); @@ -267,7 +267,7 @@ void AISet::Tick(RunListEvent* ev) } int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame]; - auto pTarget = pActor->pTarget; + DExhumedActor* pTarget = pActor->pTarget; if (pTarget && nAction < 10) { diff --git a/source/games/exhumed/src/snake.cpp b/source/games/exhumed/src/snake.cpp index 1d4963c55..74af138b5 100644 --- a/source/games/exhumed/src/snake.cpp +++ b/source/games/exhumed/src/snake.cpp @@ -33,6 +33,16 @@ FreeListArray SnakeList; int16_t nPlayerSnake[kMaxPlayers]; +size_t MarkSnake() +{ + for (int i = 0; i < kMaxSnakes; i++) + { + GC::Mark(SnakeList[i].pEnemy); + GC::MarkArray(SnakeList[i].pSprites, kSnakeSprites); + } + return kMaxSnakes * (1 + kSnakeSprites); +} + FSerializer& Serialize(FSerializer& arc, const char* keyname, Snake& w, Snake* def) { if (arc.BeginObject(keyname)) @@ -74,7 +84,8 @@ void DestroySnake(int nSnake) for (int i = 0; i < kSnakeSprites; i++) { - auto pSnake = SnakeList[nSnake].pSprites[i]; + DExhumedActor* pSnake = SnakeList[nSnake].pSprites[i]; + if (!pSnake) continue; auto pSprite = &pSnake->s(); runlist_DoSubRunRec(pSprite->lotag - 1); @@ -101,7 +112,7 @@ void ExplodeSnakeSprite(DExhumedActor* pActor, int nPlayer) } // take a copy of this, to revert after call to runlist_RadialDamageEnemy() - auto nOwner = pActor->pTarget; + DExhumedActor* nOwner = pActor->pTarget; pActor->pTarget = PlayerList[nPlayer].pActor; runlist_RadialDamageEnemy(pActor, nDamage, BulletInfo[kWeaponStaff].nRadius); @@ -256,7 +267,8 @@ DExhumedActor* FindSnakeEnemy(int nSnake) int nPlayer = SnakeList[nSnake].nSnakePlayer; auto pPlayerActor = PlayerList[nPlayer].Actor(); - auto pActor = SnakeList[nSnake].pSprites[0]; // CHECKME + DExhumedActor* pActor = SnakeList[nSnake].pSprites[0]; // CHECKME + if (!pActor) return nullptr; auto pSprite = &pActor->s(); int nAngle = pSprite->ang; @@ -307,12 +319,13 @@ void AISnake::Tick(RunListEvent* ev) int nSnake = RunData[ev->nRun].nObjIndex; assert(nSnake >= 0 && nSnake < kMaxSnakes); - auto pActor = SnakeList[nSnake].pSprites[0]; + DExhumedActor* pActor = SnakeList[nSnake].pSprites[0]; + if (!pActor) return; auto pSprite = &pActor->s(); seq_MoveSequence(pActor, SeqOffsets[kSeqSnakehed], 0); - auto pEnemySprite = SnakeList[nSnake].pEnemy; + DExhumedActor* pEnemySprite = SnakeList[nSnake].pEnemy; Collision nMov; int zVal; @@ -374,7 +387,8 @@ void AISnake::Tick(RunListEvent* ev) for (int i = 7; i > 0; i--) { - auto pActor2 = SnakeList[nSnake].pSprites[i]; + DExhumedActor* pActor2 = SnakeList[nSnake].pSprites[i]; + if (!pActor2) continue; auto pSprite2 = &pActor2->s(); pSprite2->ang = nAngle; diff --git a/source/games/exhumed/src/spider.cpp b/source/games/exhumed/src/spider.cpp index 3e5a8f1cb..a94c28913 100644 --- a/source/games/exhumed/src/spider.cpp +++ b/source/games/exhumed/src/spider.cpp @@ -127,7 +127,7 @@ void AISpider::Tick(RunListEvent* ev) spp->nFrame = 0; } - auto pTarget = spp->pTarget; + DExhumedActor* pTarget = spp->pTarget; if (pTarget == nullptr || pTarget->s().cstat & 0x101) { diff --git a/source/games/exhumed/src/view.cpp b/source/games/exhumed/src/view.cpp index 7fe77dc04..f54b3316c 100644 --- a/source/games/exhumed/src/view.cpp +++ b/source/games/exhumed/src/view.cpp @@ -59,9 +59,6 @@ bool bCamera = false; int viewz; -DExhumedActor* pEnemy; - -int nEnemyPal = 0; // We cannot drag these through the entire event system... :( tspritetype* mytsprite; @@ -198,6 +195,8 @@ static TextOverlay subtitleOverlay; void DrawView(double smoothRatio, bool sceneonly) { + DExhumedActor* pEnemy = nullptr; + int nEnemyPal = -1; int playerX; int playerY; int playerZ; @@ -218,7 +217,7 @@ void DrawView(double smoothRatio, bool sceneonly) if (nSnakeCam >= 0 && !sceneonly) { - auto pActor = SnakeList[nSnakeCam].pSprites[0]; + DExhumedActor* pActor = SnakeList[nSnakeCam].pSprites[0]; auto pSprite = &pActor->s(); playerX = pSprite->x; @@ -497,8 +496,6 @@ void SerializeView(FSerializer& arc) ("camerapan", nCamerapan) ("camera", bCamera) ("viewz", viewz) - ("enemy", pEnemy) - ("enemypal", nEnemyPal) .Array("vertpan", dVertPan, countof(dVertPan)) .Array("quake", nQuake, countof(nQuake)) .EndObject(); diff --git a/source/games/exhumed/src/view.h b/source/games/exhumed/src/view.h index 1feef03dc..1b0fab0e0 100644 --- a/source/games/exhumed/src/view.h +++ b/source/games/exhumed/src/view.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_PS_NS extern bool bSubTitles; -extern DExhumedActor* bestTarget; +extern TObjPtr bestTarget; extern bool bCamera; void DrawStatusBar();