- Added GC support to Exhumed

This commit is contained in:
Christoph Oelckers 2021-12-07 18:53:02 +01:00
parent 138690d34e
commit 8dde6a3074
36 changed files with 308 additions and 196 deletions

View file

@ -65,6 +65,7 @@ TArray<DCoreActor*> checked;
static bool ValidateStatList(int statnum) static bool ValidateStatList(int statnum)
{ {
#if 0
checked.Clear(); checked.Clear();
for (auto entry = statList[statnum].firstEntry; entry; entry = entry->nextStat) 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->prevStat == nullptr || entry->prevStat->nextStat == entry);
assert(entry->nextStat == nullptr || entry->nextStat->prevStat == entry); assert(entry->nextStat == nullptr || entry->nextStat->prevStat == entry);
} }
#endif
return true; return true;
} }
@ -197,6 +199,7 @@ int ChangeActorStat(DCoreActor* actor, int statnum, bool tail)
static bool ValidateSectList(sectortype* sect, DCoreActor *checkme = nullptr) static bool ValidateSectList(sectortype* sect, DCoreActor *checkme = nullptr)
{ {
#if 0
assert(sect); assert(sect);
checked.Clear(); checked.Clear();
assert(sect->firstEntry == nullptr || sect->firstEntry->prevSect == nullptr); 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->prevSect == nullptr || entry->prevSect->nextSect == entry);
assert(entry->nextSect == nullptr || entry->nextSect->prevSect == entry); assert(entry->nextSect == nullptr || entry->nextSect->prevSect == entry);
} }
#endif
return true; return true;
} }
@ -330,8 +334,6 @@ static void InsertActorSect(DCoreActor* actor, sectortype* sector, bool tail)
void ChangeActorSect(DCoreActor* actor, sectortype* sect, bool tail) void ChangeActorSect(DCoreActor* actor, sectortype* sect, bool tail)
{ {
if (sect == nullptr) return; if (sect == nullptr) return;
auto old_sect = actor->link_sector;
assert(actor->s().insector());
RemoveActorSect(actor); RemoveActorSect(actor);
InsertActorSect(actor, sect, tail); InsertActorSect(actor, sect, tail);
} }

View file

@ -198,7 +198,7 @@ void FuncLion(int, int, int, int);
// 16 bytes // 16 bytes
struct BlockInfo struct BlockInfo
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
int x; int x;
int y; int y;
int field_8; int field_8;
@ -206,8 +206,8 @@ struct BlockInfo
extern BlockInfo sBlockInfo[]; extern BlockInfo sBlockInfo[];
extern Collision hiHit; extern Collision hiHit;
extern DExhumedActor* nChunkSprite[]; extern TObjPtr<DExhumedActor*> nChunkSprite[];
extern DExhumedActor* nBodySprite[]; extern TObjPtr<DExhumedActor*> nBodySprite[];
signed int lsqrt(int a1); signed int lsqrt(int a1);
void MoveThings(); void MoveThings();
@ -259,7 +259,7 @@ extern int bTorch;
extern int nSmokeSparks; extern int nSmokeSparks;
extern int nDronePitch; extern int nDronePitch;
extern int lFinaleStart; extern int lFinaleStart;
extern DExhumedActor* pFinaleSpr; extern TObjPtr<DExhumedActor*> pFinaleSpr;
void InitObjects(); void InitObjects();
void InitElev(); void InitElev();
@ -305,8 +305,8 @@ void FuncQueen(int, int, int, int);
struct RA struct RA
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
DExhumedActor* pTarget; TObjPtr<DExhumedActor*> pTarget;
int16_t nAction; int16_t nAction;
int16_t nFrame; int16_t nFrame;
@ -352,7 +352,7 @@ struct RunStruct
{ {
int nAIType; // todo later: replace this with an AI pointer int nAIType; // todo later: replace this with an AI pointer
int nObjIndex; // If object is a non-actor / not refactored yet. int nObjIndex; // If object is a non-actor / not refactored yet.
DExhumedActor* pObjActor; // If object is an actor TObjPtr<DExhumedActor*> pObjActor; // If object is an actor
int next; int next;
int prev; int prev;
}; };
@ -715,8 +715,8 @@ enum { kSnakeSprites = 8 }; // or rename to kSnakeParts?
// 32bytes // 32bytes
struct Snake struct Snake
{ {
DExhumedActor* pEnemy; // nRun TObjPtr<DExhumedActor*> pEnemy; // nRun
DExhumedActor* pSprites[kSnakeSprites]; TObjPtr<DExhumedActor*> pSprites[kSnakeSprites];
int16_t nCountdown; int16_t nCountdown;
int16_t nRun; int16_t nRun;

View file

@ -28,7 +28,6 @@ BEGIN_PS_NS
int nMagicSeq = -1; int nMagicSeq = -1;
int nPreMagicSeq = -1; int nPreMagicSeq = -1;
int nSavePointSeq = -1; int nSavePointSeq = -1;
//FreeListArray<Anim, kMaxAnims> AnimList;
void SerializeAnim(FSerializer& arc) void SerializeAnim(FSerializer& arc)
@ -138,7 +137,7 @@ void AIAnim::Tick(RunListEvent* ev)
if (pSprite->statnum == kStatIgnited) if (pSprite->statnum == kStatIgnited)
{ {
auto pIgniter = pActor->pTarget; DExhumedActor* pIgniter = pActor->pTarget;
if (pIgniter) if (pIgniter)
{ {

View file

@ -136,7 +136,7 @@ void AIAnubis::Tick(RunListEvent* ev)
bVal = true; bVal = true;
} }
auto pTarget = ap->pTarget; DExhumedActor* pTarget = ap->pTarget;
int nFrame = SeqBase[nSeq] + ap->nFrame; int nFrame = SeqBase[nSeq] + ap->nFrame;
int nFlag = FrameFlag[nFrame]; int nFlag = FrameFlag[nFrame];

View file

@ -34,8 +34,8 @@ enum { kMaxBullets = 500 };
// 32 bytes // 32 bytes
struct Bullet struct Bullet
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
DExhumedActor* pEnemy; TObjPtr<DExhumedActor*> pEnemy;
int16_t nSeq; int16_t nSeq;
int16_t nFrame; int16_t nFrame;
@ -56,6 +56,16 @@ FreeListArray<Bullet, kMaxBullets> BulletList;
int lasthitz, lasthitx, lasthity; int lasthitz, lasthitx, lasthity;
sectortype* lasthitsect; 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; int nRadialBullet = 0;
FSerializer& Serialize(FSerializer& arc, const char* keyname, Bullet& w, Bullet* def) FSerializer& Serialize(FSerializer& arc, const char* keyname, Bullet& w, Bullet* def)
@ -138,7 +148,7 @@ int GrabBullet()
void DestroyBullet(int nBullet) void DestroyBullet(int nBullet)
{ {
auto pActor = BulletList[nBullet].pActor; DExhumedActor* pActor = BulletList[nBullet].pActor;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
runlist_DoSubRunRec(BulletList[nBullet].nRunRec); runlist_DoSubRunRec(BulletList[nBullet].nRunRec);
@ -223,7 +233,7 @@ void BulletHitsSprite(Bullet *pBullet, DExhumedActor* pBulletActor, DExhumedActo
break; break;
} }
auto pActor = pBullet->pActor; DExhumedActor* pActor = pBullet->pActor;
spritetype *pSprite = &pActor->s(); spritetype *pSprite = &pActor->s();
if (nStat == kStatAnubisDrum) if (nStat == kStatAnubisDrum)
@ -307,7 +317,7 @@ int MoveBullet(int nBullet)
int nType = pBullet->nType; int nType = pBullet->nType;
bulletInfo *pBulletInfo = &BulletInfo[nType]; bulletInfo *pBulletInfo = &BulletInfo[nType];
auto pActor = BulletList[nBullet].pActor; DExhumedActor* pActor = BulletList[nBullet].pActor;
spritetype *pSprite = &pActor->s(); spritetype *pSprite = &pActor->s();
int x = pSprite->x; int x = pSprite->x;
@ -322,7 +332,7 @@ int MoveBullet(int nBullet)
if (pBullet->field_10 < 30000) if (pBullet->field_10 < 30000)
{ {
auto pEnemyActor = BulletList[nBullet].pEnemy; DExhumedActor* pEnemyActor = BulletList[nBullet].pEnemy;
if (pEnemyActor) if (pEnemyActor)
{ {
if (!(pEnemyActor->s().cstat & 0x101)) if (!(pEnemyActor->s().cstat & 0x101))
@ -494,7 +504,8 @@ HITSPRITE:
nDamage *= 2; 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); assert(nBullet >= 0 && nBullet < kMaxBullets);
int nSeq = SeqOffsets[BulletList[nBullet].nSeq]; int nSeq = SeqOffsets[BulletList[nBullet].nSeq];
auto pActor = BulletList[nBullet].pActor; DExhumedActor* pActor = BulletList[nBullet].pActor;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
int nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].nFrame]; int nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].nFrame];

View file

@ -60,10 +60,8 @@ extern int16_t inita;
extern sectortype* initsectp; extern sectortype* initsectp;
extern int nCurChunkNum; extern int nCurChunkNum;
extern DExhumedActor* nBodyGunSprite[50];
extern int movefifoend; extern int movefifoend;
extern int movefifopos; extern int movefifopos;
extern int nCurBodyGunNum;
// all static counters combined in an array for easier maintenance. // all static counters combined in an array for easier maintenance.
enum ECounter enum ECounter

View file

@ -52,11 +52,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS BEGIN_PS_NS
TObjPtr<DExhumedActor*> bestTarget;
IMPLEMENT_CLASS(DExhumedActor, false, true) IMPLEMENT_CLASS(DExhumedActor, false, true)
IMPLEMENT_POINTERS_START(DExhumedActor) IMPLEMENT_POINTERS_START(DExhumedActor)
IMPLEMENT_POINTER(pTarget) IMPLEMENT_POINTER(pTarget)
IMPLEMENT_POINTERS_END 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; static MapRecord* NextMap;
void uploadCinemaPalettes(); void uploadCinemaPalettes();
@ -138,7 +174,6 @@ bool bInDemo = false;
bool bSlipMode = false; bool bSlipMode = false;
bool bDoFlashes = true; bool bDoFlashes = true;
DExhumedActor* bestTarget;
int nStartLevel; int nStartLevel;
int nTimeLimit; int nTimeLimit;
@ -468,6 +503,8 @@ static void SetTileNames()
void GameInterface::app_init() void GameInterface::app_init()
{ {
SetupActors(RUNTIME_CLASS(DExhumedActor)); SetupActors(RUNTIME_CLASS(DExhumedActor));
GC::AddMarkerFunc(markgcroots);
#if 0 #if 0
help_disabled = true; help_disabled = true;

View file

@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gamestruct.h" #include "gamestruct.h"
#include "names.h" #include "names.h"
#include "exhumedactor.h" #include "exhumedactor.h"
#include "serialize_obj.h"
BEGIN_PS_NS BEGIN_PS_NS
@ -111,7 +112,7 @@ extern int nEnergyTowers;
extern int nEnergyChan; extern int nEnergyChan;
extern DExhumedActor* pSpiritSprite; extern TObjPtr<DExhumedActor*> pSpiritSprite;
extern bool bInDemo; extern bool bInDemo;

View file

@ -19,7 +19,7 @@ class DExhumedActor : public DCoreActor
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
DExhumedActor* pTarget; TObjPtr<DExhumedActor*> pTarget;
int16_t nPhase; int16_t nPhase;

View file

@ -342,7 +342,7 @@ void AIFish::Tick(RunListEvent* ev)
pActor->nFrame = 0; pActor->nFrame = 0;
} }
auto pTargetActor = pActor->pTarget; DExhumedActor* pTargetActor = pActor->pTarget;
switch (nAction) switch (nAction)
{ {

View file

@ -52,7 +52,7 @@ void ThrowGrenade(int nPlayer, int, int, int ecx, int push1)
if (PlayerList[nPlayer].pPlayerGrenade == nullptr) if (PlayerList[nPlayer].pPlayerGrenade == nullptr)
return; return;
auto pActor = PlayerList[nPlayer].pPlayerGrenade; DExhumedActor* pActor = PlayerList[nPlayer].pPlayerGrenade;
auto pGrenadeSprite = &pActor->s(); auto pGrenadeSprite = &pActor->s();
auto pPlayerActor = PlayerList[nPlayer].Actor(); auto pPlayerActor = PlayerList[nPlayer].Actor();
auto pPlayerSprite = &pPlayerActor->s(); auto pPlayerSprite = &pPlayerActor->s();

View file

@ -807,7 +807,7 @@ loc_flag:
DExhumedActor* target = nullptr; DExhumedActor* target = nullptr;
if (sPlayerInput[nPlayer].pTarget != nullptr && Autoaim(nPlayer)) 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. // only autoaim if target is in front of the player.
auto pTargetSprite = &t->s(); auto pTargetSprite = &t->s();
assert(pTargetSprite->sector()); assert(pTargetSprite->sector());

View file

@ -45,12 +45,9 @@ sectortype* initsectp;
int nCurChunkNum = 0; int nCurChunkNum = 0;
DExhumedActor* nBodyGunSprite[50];
int movefifoend; int movefifoend;
int movefifopos; int movefifopos;
int nCurBodyGunNum;
int Counters[kNumCounters]; int Counters[kNumCounters];
@ -846,8 +843,6 @@ void SerializeInit(FSerializer& arc)
("inita", inita) ("inita", inita)
("initsect", initsectp) ("initsect", initsectp)
("curchunk", nCurChunkNum) ("curchunk", nCurChunkNum)
.Array("bodygunsprite", nBodyGunSprite, countof(nBodyGunSprite))
("curbodygun", nCurBodyGunNum)
.Array("counters", Counters, kNumCounters) .Array("counters", Counters, kNumCounters)
.EndObject(); .EndObject();
} }

View file

@ -27,6 +27,15 @@ BEGIN_PS_NS
PlayerInput sPlayerInput[kMaxPlayers]; PlayerInput sPlayerInput[kMaxPlayers];
size_t MarkInput()
{
for (auto& p : sPlayerInput)
{
GC::Mark(p.pTarget);
}
return kMaxPlayers;
}
void ClearSpaceBar(int nPlayer) void ClearSpaceBar(int nPlayer)
{ {
sPlayerInput[nPlayer].actions &= SB_OPEN; sPlayerInput[nPlayer].actions &= SB_OPEN;

View file

@ -32,7 +32,7 @@ enum {
// 32 bytes // 32 bytes
struct PlayerInput struct PlayerInput
{ {
DExhumedActor* pTarget; TObjPtr<DExhumedActor*> pTarget;
int xVel; int xVel;
int yVel; int yVel;
uint16_t buttons; uint16_t buttons;

View file

@ -98,9 +98,15 @@ AnimInfo nItemAnimInfo[] = {
const int16_t nItemMagic[] = { 500, 1000, 100, 500, 400, 200, 700, 0 }; const int16_t nItemMagic[] = { 500, 1000, 100, 500, 400, 200, 700, 0 };
TArray<DExhumedActor*> Regenerates; TArray<DExhumedActor*> Regenerates; // must handle read barriers manually!
int nMagicCount; int nMagicCount;
size_t MarkItems()
{
GC::MarkArray(Regenerates);
return Regenerates.Size();
}
void SerializeItems(FSerializer& arc) void SerializeItems(FSerializer& arc)
{ {
if (arc.BeginObject("items")) if (arc.BeginObject("items"))
@ -395,7 +401,7 @@ void DoRegenerates()
{ {
for(unsigned i = 0; i < Regenerates.Size(); i++) for(unsigned i = 0; i < Regenerates.Size(); i++)
{ {
auto pActor = Regenerates[i]; DExhumedActor* pActor = GC::ReadBarrier(Regenerates[i]);
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
if (pSprite->extra > 0) if (pSprite->extra > 0)
{ {

View file

@ -255,7 +255,7 @@ void AILavaDude::Tick(RunListEvent* ev)
} }
} }
auto pTarget = pActor->pTarget; DExhumedActor* pTarget = pActor->pTarget;
if (pTarget && nAction < 4) if (pTarget && nAction < 4)
{ {

View file

@ -42,7 +42,7 @@ struct Flash
{ {
walltype* pWall; walltype* pWall;
sectortype* pSector; sectortype* pSector;
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
}; };
int next; int next;
int8_t nType; int8_t nType;
@ -100,6 +100,15 @@ int nGlowCount;
int bDoFlicks = 0; int bDoFlicks = 0;
int bDoGlows = 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) FSerializer& Serialize(FSerializer& arc, const char* keyname, Flash& w, Flash* def)
{ {
@ -442,12 +451,10 @@ void UndoFlashes()
case 3: case 3:
{ {
auto ac = pFlash->pActor; DExhumedActor* ac = pFlash->pActor;
if (!ac) continue; if (ac && ac->spr.pal >= 7)
auto sp = &ac->s();
if (sp->pal >= 7)
{ {
pShade = &sp->shade; pShade = &ac->spr.shade;
} }
else { else {
goto loc_1868A; goto loc_1868A;
@ -505,12 +512,11 @@ void UndoFlashes()
case 3: case 3:
{ {
auto ac = pFlash->pActor; DExhumedActor* ac = pFlash->pActor;
auto sp = &ac->s(); if (ac && ac->spr.pal >= 7)
if (sp->pal >= 7)
{ {
sp->pal -= 7; ac->spr.pal -= 7;
sp->shade = pFlash->shade; ac->spr.shade = pFlash->shade;
} }
break; break;

View file

@ -222,7 +222,7 @@ void AILion::Tick(RunListEvent* ev)
} }
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame]; int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
auto pTarget = pActor->pTarget; DExhumedActor* pTarget = pActor->pTarget;
auto nMov = MoveCreatureWithCaution(pActor); auto nMov = MoveCreatureWithCaution(pActor);

View file

@ -35,21 +35,33 @@ int nPushBlocks;
// TODO - moveme? // TODO - moveme?
sectortype* overridesect; sectortype* overridesect;
DExhumedActor* nBodySprite[50]; enum
{
kMaxPushBlocks = 100,
kMaxMoveChunks = 75
};
TObjPtr<DExhumedActor*> nBodySprite[50];
TObjPtr<DExhumedActor*> nChunkSprite[kMaxMoveChunks];
BlockInfo sBlockInfo[kMaxPushBlocks];
TObjPtr<DExhumedActor*> nBodyGunSprite[50];
int nCurBodyGunNum;
int sprceiling, sprfloor; int sprceiling, sprfloor;
Collision loHit, hiHit; Collision loHit, hiHit;
enum
{
kMaxPushBlocks = 100,
kMaxMoveChunks = 75
};
// think this belongs in init.c? // 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) FSerializer& Serialize(FSerializer& arc, const char* keyname, BlockInfo& w, BlockInfo* def)
{ {
@ -73,7 +85,9 @@ void SerializeMove(FSerializer& arc)
("chunkcount", nCurChunkNum) ("chunkcount", nCurChunkNum)
.Array("chunks", nChunkSprite, kMaxMoveChunks) .Array("chunks", nChunkSprite, kMaxMoveChunks)
("overridesect", overridesect) ("overridesect", overridesect)
.Array("bodysprite", nBodySprite, 50) .Array("bodysprite", nBodySprite, countof(nBodySprite))
("curbodygun", nCurBodyGunNum)
.Array("bodygunsprite", nBodyGunSprite, countof(nBodyGunSprite))
.EndObject(); .EndObject();
} }
} }
@ -1281,7 +1295,7 @@ void InitChunks()
DExhumedActor* GrabBodyGunSprite() DExhumedActor* GrabBodyGunSprite()
{ {
auto pActor = nBodyGunSprite[nCurBodyGunNum]; DExhumedActor* pActor = nBodyGunSprite[nCurBodyGunNum];
spritetype* pSprite; spritetype* pSprite;
if (pActor == nullptr) if (pActor == nullptr)
{ {
@ -1346,7 +1360,7 @@ DExhumedActor* GrabBody()
DExhumedActor* GrabChunkSprite() DExhumedActor* GrabChunkSprite()
{ {
auto pActor = nChunkSprite[nCurChunkNum]; DExhumedActor* pActor = nChunkSprite[nCurChunkNum];
if (pActor == nullptr) if (pActor == nullptr)
{ {

View file

@ -128,7 +128,9 @@ void AIMummy::Tick(RunListEvent* ev)
auto pActor = ev->pObjActor; auto pActor = ev->pObjActor;
if (!pActor) return; if (!pActor) return;
auto pTarget = UpdateEnemy(&pActor->pTarget); DExhumedActor* targ = pActor->pTarget;
auto pTarget = UpdateEnemy(&targ);
pActor->pTarget = targ;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
int nAction = pActor->nAction; int nAction = pActor->nAction;

View file

@ -67,14 +67,14 @@ struct Bob
struct Drip struct Drip
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
int16_t nCount; int16_t nCount;
}; };
// 56 bytes // 56 bytes
struct Elev struct Elev
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
sectortype* pSector; sectortype* pSector;
int16_t nFlags; int16_t nFlags;
int16_t nChannel; int16_t nChannel;
@ -110,7 +110,7 @@ struct wallFace
struct slideData struct slideData
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
int16_t nChannel; int16_t nChannel;
int16_t nStart; int16_t nStart;
int16_t nRunRec; int16_t nRunRec;
@ -142,7 +142,7 @@ struct Point
struct Trap struct Trap
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
walltype* pWall1; walltype* pWall1;
walltype* pWall2; walltype* pWall2;
@ -167,11 +167,22 @@ TArray<slideData> SlideData;
TArray<wallFace> WallFace; TArray<wallFace> WallFace;
TArray<Drip> sDrip; TArray<Drip> sDrip;
TArray<DExhumedActor*> EnergyBlocks; TArray<DExhumedActor*> EnergyBlocks;
TObjPtr<DExhumedActor*> 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 lFinaleStart;
int nFinaleStage; int nFinaleStage;
DExhumedActor* pFinaleSpr;
int nDronePitch = 0; int nDronePitch = 0;
int nSmokeSparks = 0; int nSmokeSparks = 0;
@ -751,7 +762,7 @@ void AIElev::Tick(RunListEvent* ev)
assert(nChannel >= 0 && nChannel < kMaxChannels); assert(nChannel >= 0 && nChannel < kMaxChannels);
auto pSector =Elevator[nElev].pSector; auto pSector =Elevator[nElev].pSector;
auto pElevSpr = Elevator[nElev].pActor; DExhumedActor* pElevSpr = Elevator[nElev].pActor;
int ebp = 0; // initialise to *something* int ebp = 0; // initialise to *something*
@ -1274,7 +1285,8 @@ void AITrap::ProcessChannel(RunListEvent* ev)
void AITrap::Tick(RunListEvent* ev) void AITrap::Tick(RunListEvent* ev)
{ {
int nTrap = RunData[ev->nRun].nObjIndex; int nTrap = RunData[ev->nRun].nObjIndex;
auto pActor = sTrap[nTrap].pActor; DExhumedActor* pActor = sTrap[nTrap].pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
if (sTrap[nTrap].nState >= 0) if (sTrap[nTrap].nState >= 0)
@ -2120,7 +2132,8 @@ void DoDrips()
sDrip[i].nCount--; sDrip[i].nCount--;
if (sDrip[i].nCount <= 0) if (sDrip[i].nCount <= 0)
{ {
auto pActor = sDrip[i].pActor; DExhumedActor* pActor = sDrip[i].pActor;
if (!pActor) continue;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
int nSeqOffset = SeqOffsets[kSeqDrips]; int nSeqOffset = SeqOffsets[kSeqDrips];

View file

@ -77,7 +77,7 @@ int nLocalPlayer = 0;
Player PlayerList[kMaxPlayers]; Player PlayerList[kMaxPlayers];
DExhumedActor* nNetStartSprite[kMaxPlayers] = { }; TObjPtr<DExhumedActor*> nNetStartSprite[kMaxPlayers] = { };
int nStandHeight; int nStandHeight;
@ -87,6 +87,20 @@ int PlayerCount;
int nNetStartSprites; int nNetStartSprites;
int nCurStartSprite; 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) void SetSavePoint(int nPlayer, int x, int y, int z, sectortype* pSector, int nAngle)
{ {
PlayerList[nPlayer].sPlayerSave.x = x; PlayerList[nPlayer].sPlayerSave.x = x;
@ -206,7 +220,7 @@ void RestartPlayer(int nPlayer)
{ {
auto plr = &PlayerList[nPlayer]; auto plr = &PlayerList[nPlayer];
auto pActor = plr->Actor(); auto pActor = plr->Actor();
auto pDopSprite = plr->pDoppleSprite; DExhumedActor* pDopSprite = plr->pDoppleSprite;
DExhumedActor* floorsprt; DExhumedActor* floorsprt;
@ -220,7 +234,7 @@ void RestartPlayer(int nPlayer)
plr->pActor = nullptr; plr->pActor = nullptr;
auto pFloorSprite = plr->pPlayerFloorSprite; DExhumedActor* pFloorSprite = plr->pPlayerFloorSprite;
if (pFloorSprite != nullptr) { if (pFloorSprite != nullptr) {
DeleteActor(pFloorSprite); DeleteActor(pFloorSprite);
} }
@ -245,7 +259,7 @@ void RestartPlayer(int nPlayer)
if (nTotalPlayers > 1) if (nTotalPlayers > 1)
{ {
auto nNStartSprite = nNetStartSprite[nCurStartSprite]; DExhumedActor* nNStartSprite = nNetStartSprite[nCurStartSprite];
auto nstspr = &nNStartSprite->s(); auto nstspr = &nNStartSprite->s();
nCurStartSprite++; nCurStartSprite++;
@ -548,7 +562,7 @@ int AddAmmo(int nPlayer, int nWeapon, int nAmmoAmount)
void SetPlayerMummified(int nPlayer, int bIsMummified) void SetPlayerMummified(int nPlayer, int bIsMummified)
{ {
auto pActor = PlayerList[nPlayer].pActor; DExhumedActor* pActor = PlayerList[nPlayer].pActor;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
pSprite->yvel = 0; pSprite->yvel = 0;
@ -633,13 +647,13 @@ void AIPlayer::Damage(RunListEvent* ev)
auto pPlayerActor = PlayerList[nPlayer].Actor(); auto pPlayerActor = PlayerList[nPlayer].Actor();
int nAction = PlayerList[nPlayer].nAction; int nAction = PlayerList[nPlayer].nAction;
auto pPlayerSprite = &pPlayerActor->s(); auto pPlayerSprite = &pPlayerActor->s();
auto pDopple = PlayerList[nPlayer].pDoppleSprite; DExhumedActor* pDopple = PlayerList[nPlayer].pDoppleSprite;
if (!nDamage) { if (!nDamage) {
return; 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 // ok continue case 0x80000 as normal, loc_1C57C
if (!PlayerList[nPlayer].nHealth) { if (!PlayerList[nPlayer].nHealth) {
@ -744,7 +758,7 @@ void AIPlayer::Tick(RunListEvent* ev)
auto pPlayerActor = PlayerList[nPlayer].Actor(); auto pPlayerActor = PlayerList[nPlayer].Actor();
auto pPlayerSprite = &pPlayerActor->s(); auto pPlayerSprite = &pPlayerActor->s();
auto pDopple = PlayerList[nPlayer].pDoppleSprite; DExhumedActor* pDopple = PlayerList[nPlayer].pDoppleSprite;
int nAction = PlayerList[nPlayer].nAction; int nAction = PlayerList[nPlayer].nAction;
int nActionB = PlayerList[nPlayer].nAction; int nActionB = PlayerList[nPlayer].nAction;
@ -803,7 +817,7 @@ void AIPlayer::Tick(RunListEvent* ev)
if (PlayerList[nPlayer].nInvisible == 0) if (PlayerList[nPlayer].nInvisible == 0)
{ {
pPlayerSprite->cstat &= 0x7FFF; // set visible pPlayerSprite->cstat &= 0x7FFF; // set visible
auto pFloorSprite = PlayerList[nPlayer].pPlayerFloorSprite; DExhumedActor* pFloorSprite = PlayerList[nPlayer].pPlayerFloorSprite;
if (pFloorSprite != nullptr) { if (pFloorSprite != nullptr) {
pFloorSprite->s().cstat &= 0x7FFF; // set visible pFloorSprite->s().cstat &= 0x7FFF; // set visible
@ -1049,7 +1063,7 @@ void AIPlayer::Tick(RunListEvent* ev)
{ {
PlayerList[nPlayer].nPlayerPushSound = 1; PlayerList[nPlayer].nPlayerPushSound = 1;
int nBlock = PlayerList[nPlayer].pPlayerPushSect->extra; int nBlock = PlayerList[nPlayer].pPlayerPushSect->extra;
auto pBlockActor = sBlockInfo[nBlock].pActor; DExhumedActor* pBlockActor = sBlockInfo[nBlock].pActor;
D3PlayFX(StaticSound[kSound23], pBlockActor, 0x4000); D3PlayFX(StaticSound[kSound23], pBlockActor, 0x4000);
} }
@ -1274,7 +1288,7 @@ sectdone:
} }
// loc_1B1EB // loc_1B1EB
auto pFloorActor = PlayerList[nPlayer].pPlayerFloorSprite; DExhumedActor* pFloorActor = PlayerList[nPlayer].pPlayerFloorSprite;
if (nTotalPlayers > 1 && pFloorActor) if (nTotalPlayers > 1 && pFloorActor)
{ {
auto pFloorSprite = &pFloorActor->s(); auto pFloorSprite = &pFloorActor->s();

View file

@ -55,7 +55,7 @@ struct PlayerSave
struct Player struct Player
{ {
DExhumedActor* Actor() { return pActor; } DExhumedActor* Actor() { return pActor; }
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
int16_t nHealth; int16_t nHealth;
int16_t nLives; int16_t nLives;
int16_t nDouble; int16_t nDouble;
@ -108,9 +108,9 @@ struct Player
int ototalvel; int ototalvel;
int totalvel; int totalvel;
int16_t eyelevel, oeyelevel; int16_t eyelevel, oeyelevel;
DExhumedActor* pPlayerGrenade; TObjPtr<DExhumedActor*> pPlayerGrenade;
DExhumedActor* pPlayerFloorSprite; TObjPtr<DExhumedActor*> pPlayerFloorSprite;
DExhumedActor* pDoppleSprite; TObjPtr<DExhumedActor*> pDoppleSprite;
}; };
@ -120,7 +120,7 @@ extern Player PlayerList[kMaxPlayers];
extern int obobangle, bobangle; extern int obobangle, bobangle;
extern DExhumedActor* nNetStartSprite[kMaxPlayers]; extern TObjPtr<DExhumedActor*> nNetStartSprite[kMaxPlayers];
extern int nNetStartSprites; extern int nNetStartSprites;
extern int nCurStartSprite; extern int nCurStartSprite;

View file

@ -70,8 +70,8 @@ static actionSeq EggSeq[] = {
struct Queen struct Queen
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
DExhumedActor* pTarget; TObjPtr<DExhumedActor*> pTarget;
int16_t nHealth; int16_t nHealth;
int16_t nFrame; int16_t nFrame;
int16_t nAction; int16_t nAction;
@ -83,8 +83,8 @@ struct Queen
struct Egg struct Egg
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
DExhumedActor* pTarget; TObjPtr<DExhumedActor*> pTarget;
int16_t nHealth; int16_t nHealth;
int16_t nFrame; int16_t nFrame;
int16_t nAction; int16_t nAction;
@ -94,8 +94,8 @@ struct Egg
struct Head struct Head
{ {
DExhumedActor* pActor; TObjPtr<DExhumedActor*> pActor;
DExhumedActor* pTarget; TObjPtr<DExhumedActor*> pTarget;
int16_t nHealth; int16_t nHealth;
int16_t nFrame; int16_t nFrame;
int16_t nAction; int16_t nAction;
@ -112,7 +112,7 @@ int nQHead = 0;
int nHeadVel; int nHeadVel;
int nVelShift; int nVelShift;
DExhumedActor* tailspr[kMaxTails]; TObjPtr<DExhumedActor*> tailspr[kMaxTails];
Queen QueenList[kMaxQueens]; Queen QueenList[kMaxQueens];
@ -124,6 +124,21 @@ int MoveQZ[25];
sectortype* MoveQS[25]; sectortype* MoveQS[25];
int16_t MoveQA[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) FSerializer& Serialize(FSerializer& arc, const char* keyname, Queen& w, Queen* def)
{ {
if (arc.BeginObject(keyname)) if (arc.BeginObject(keyname))
@ -229,7 +244,8 @@ void BlowChunks(DExhumedActor* pActor)
void DestroyEgg(int nEgg) void DestroyEgg(int nEgg)
{ {
auto pActor = QueenEgg[nEgg].pActor; DExhumedActor* pActor = QueenEgg[nEgg].pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
if (QueenEgg[nEgg].nAction != 4) if (QueenEgg[nEgg].nAction != 4)
@ -360,7 +376,8 @@ int DestroyTailPart()
return 0; return 0;
} }
auto pActor = tailspr[--QueenHead.nIndex2]; DExhumedActor* pActor = tailspr[--QueenHead.nIndex2];
if (!pActor) return 0;
BlowChunks(pActor); BlowChunks(pActor);
BuildExplosion(pActor); BuildExplosion(pActor);
@ -430,7 +447,8 @@ void BuildQueenEgg(int nQueen, int nVal)
return; return;
} }
auto pActor = QueenList[nQueen].pActor; DExhumedActor* pActor = QueenList[nQueen].pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
int x = pSprite->x; int x = pSprite->x;
@ -500,7 +518,8 @@ void AIQueenEgg::Tick(RunListEvent* ev)
{ {
int nEgg = RunData[ev->nRun].nObjIndex; int nEgg = RunData[ev->nRun].nObjIndex;
Egg* pEgg = &QueenEgg[nEgg]; Egg* pEgg = &QueenEgg[nEgg];
auto pActor = pEgg->pActor; DExhumedActor* pActor = pEgg->pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
int nAction = pEgg->nAction; int nAction = pEgg->nAction;
@ -533,7 +552,9 @@ void AIQueenEgg::Tick(RunListEvent* ev)
bVal = true; bVal = true;
} }
pTarget = UpdateEnemy(&pEgg->pActor); DExhumedActor* enemy = pEgg->pActor;
pTarget = UpdateEnemy(&enemy);
pEgg->pActor = enemy;
pEgg->pTarget = pTarget; pEgg->pTarget = pTarget;
if (pTarget && (pTarget->s().cstat & 0x101) == 0) if (pTarget && (pTarget->s().cstat & 0x101) == 0)
@ -655,7 +676,8 @@ void AIQueenEgg::RadialDamage(RunListEvent* ev)
{ {
int nEgg = RunData[ev->nRun].nObjIndex; int nEgg = RunData[ev->nRun].nObjIndex;
Egg* pEgg = &QueenEgg[nEgg]; Egg* pEgg = &QueenEgg[nEgg];
auto pActor = pEgg->pActor; DExhumedActor* pActor = pEgg->pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
auto pRadial = &ev->pRadialActor->s(); auto pRadial = &ev->pRadialActor->s();
@ -690,7 +712,8 @@ void AIQueenEgg::Draw(RunListEvent* ev)
void BuildQueenHead(int nQueen) void BuildQueenHead(int nQueen)
{ {
auto pActor = QueenList[nQueen].pActor; DExhumedActor* pActor = QueenList[nQueen].pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
int x = pSprite->x; int x = pSprite->x;
@ -742,7 +765,8 @@ void BuildQueenHead(int nQueen)
void AIQueenHead::Tick(RunListEvent* ev) void AIQueenHead::Tick(RunListEvent* ev)
{ {
auto pActor = QueenHead.pActor; DExhumedActor* pActor = QueenHead.pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
int nAction = QueenHead.nAction; int nAction = QueenHead.nAction;
@ -766,7 +790,7 @@ void AIQueenHead::Tick(RunListEvent* ev)
var_14 = 1; var_14 = 1;
} }
auto pTarget = QueenHead.pTarget; DExhumedActor* pTarget = QueenHead.pTarget;
if (pTarget) if (pTarget)
{ {
@ -930,7 +954,7 @@ void AIQueenHead::Tick(RunListEvent* ev)
} }
auto headSect = MoveQS[nHd]; auto headSect = MoveQS[nHd];
auto pTActor = tailspr[i]; DExhumedActor* pTActor = tailspr[i];
if (pTActor) if (pTActor)
{ {
auto pTSprite = &pTActor->s(); auto pTSprite = &pTActor->s();
@ -1041,7 +1065,8 @@ void AIQueenHead::RadialDamage(RunListEvent* ev)
void AIQueenHead::Damage(RunListEvent* ev) void AIQueenHead::Damage(RunListEvent* ev)
{ {
auto pActor = QueenHead.pActor; DExhumedActor* pActor = QueenHead.pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
if (QueenHead.nHealth > 0 && ev->nDamage != 0) if (QueenHead.nHealth > 0 && ev->nDamage != 0)
@ -1176,11 +1201,12 @@ void AIQueen::Tick(RunListEvent* ev)
int nQueen = RunData[ev->nRun].nObjIndex; int nQueen = RunData[ev->nRun].nObjIndex;
assert(nQueen >= 0 && nQueen < kMaxQueens); assert(nQueen >= 0 && nQueen < kMaxQueens);
auto pActor = QueenList[nQueen].pActor; DExhumedActor* pActor = QueenList[nQueen].pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
int nAction = QueenList[nQueen].nAction; int nAction = QueenList[nQueen].nAction;
int si = QueenList[nQueen].nAction2; int si = QueenList[nQueen].nAction2;
auto pTarget = QueenList[nQueen].pTarget; DExhumedActor* pTarget = QueenList[nQueen].pTarget;
bool bVal = false; bool bVal = false;
@ -1435,7 +1461,8 @@ void AIQueen::RadialDamage(RunListEvent* ev)
{ {
int nQueen = RunData[ev->nRun].nObjIndex; int nQueen = RunData[ev->nRun].nObjIndex;
assert(nQueen >= 0 && nQueen < kMaxQueens); assert(nQueen >= 0 && nQueen < kMaxQueens);
auto pActor = QueenList[nQueen].pActor; DExhumedActor* pActor = QueenList[nQueen].pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
auto pRadial = &ev->pRadialActor->s(); auto pRadial = &ev->pRadialActor->s();
@ -1451,7 +1478,8 @@ void AIQueen::Damage(RunListEvent* ev)
int nQueen = RunData[ev->nRun].nObjIndex; int nQueen = RunData[ev->nRun].nObjIndex;
assert(nQueen >= 0 && nQueen < kMaxQueens); assert(nQueen >= 0 && nQueen < kMaxQueens);
auto pActor = QueenList[nQueen].pActor; DExhumedActor* pActor = QueenList[nQueen].pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
int si = QueenList[nQueen].nAction2; int si = QueenList[nQueen].nAction2;

View file

@ -37,6 +37,16 @@ static actionSeq RaSeq[] = {
{2, 0} {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) FSerializer& Serialize(FSerializer& arc, const char* keyname, RA& w, RA* def)
{ {
if (arc.BeginObject(keyname)) if (arc.BeginObject(keyname))
@ -62,7 +72,8 @@ void SerializeRa(FSerializer& arc)
void FreeRa(int nPlayer) void FreeRa(int nPlayer)
{ {
int nRun = Ra[nPlayer].nRun; int nRun = Ra[nPlayer].nRun;
auto pActor = Ra[nPlayer].pActor; DExhumedActor* pActor = Ra[nPlayer].pActor;
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
runlist_SubRunRec(nRun); runlist_SubRunRec(nRun);
@ -70,6 +81,7 @@ void FreeRa(int nPlayer)
runlist_FreeRun(pSprite->lotag - 1); runlist_FreeRun(pSprite->lotag - 1);
DeleteActor(pActor); DeleteActor(pActor);
Ra[nPlayer] = {};
} }
void BuildRa(int nPlayer) void BuildRa(int nPlayer)
@ -112,8 +124,9 @@ void InitRa()
void MoveRaToEnemy(int nPlayer) void MoveRaToEnemy(int nPlayer)
{ {
auto pTarget = Ra[nPlayer].pTarget; DExhumedActor* pTarget = Ra[nPlayer].pTarget;
auto pActor = Ra[nPlayer].pActor; DExhumedActor* pActor = Ra[nPlayer].pActor;
if (!pActor) return;
int nAction = Ra[nPlayer].nAction; int nAction = Ra[nPlayer].nAction;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
@ -171,7 +184,8 @@ void AIRa::Tick(RunListEvent* ev)
int nCurrentWeapon = PlayerList[nPlayer].nCurrentWeapon; int nCurrentWeapon = PlayerList[nPlayer].nCurrentWeapon;
int nSeq = SeqOffsets[kSeqEyeHit] + RaSeq[Ra[nPlayer].nAction].a; 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(); auto pSprite = &pActor->s();
bool bVal = false; bool bVal = false;

View file

@ -57,7 +57,7 @@ int word_964EC = 10;
int nSpiritRepeatX; int nSpiritRepeatX;
int nSpiritRepeatY; int nSpiritRepeatY;
DExhumedActor* pSpiritSprite; TObjPtr<DExhumedActor*> pSpiritSprite;
int nPixelsToShow; int nPixelsToShow;
int nTalkTime = 0; int nTalkTime = 0;

View file

@ -138,7 +138,7 @@ DExhumedActor* FindFood(DExhumedActor* pActor)
if (nChunkTotal) if (nChunkTotal)
{ {
auto pActor2 = nChunkSprite[RandomSize(7) % nChunkTotal]; DExhumedActor* pActor2 = nChunkSprite[RandomSize(7) % nChunkTotal];
if (pActor2 != nullptr) if (pActor2 != nullptr)
{ {
auto pSprite2 = &pActor2->s(); auto pSprite2 = &pActor2->s();
@ -152,7 +152,7 @@ DExhumedActor* FindFood(DExhumedActor* pActor)
return nullptr; return nullptr;
} }
auto pActor2 = nBodySprite[RandomSize(7) % nBodyTotal]; DExhumedActor* pActor2 = nBodySprite[RandomSize(7) % nBodyTotal];
if (pActor2 != nullptr) if (pActor2 != nullptr)
{ {
auto pSprite2 = &pActor2->s(); auto pSprite2 = &pActor2->s();
@ -224,7 +224,7 @@ void AIRat::Tick(RunListEvent* ev)
pActor->nFrame = 0; pActor->nFrame = 0;
} }
auto pTarget = pActor->pTarget; DExhumedActor* pTarget = pActor->pTarget;
Gravity(pActor); Gravity(pActor);

View file

@ -198,7 +198,7 @@ void AIRex::Tick(RunListEvent* ev)
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame]; int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
auto pTarget = pActor->pTarget; DExhumedActor* pTarget = pActor->pTarget;
switch (nAction) switch (nAction)
{ {

View file

@ -206,7 +206,7 @@ void AIRoach::Tick(RunListEvent* ev)
} }
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame]; int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
auto pTarget = pActor->pTarget; DExhumedActor* pTarget = pActor->pTarget;
if (nAction > 5) { if (nAction > 5) {
return; return;

View file

@ -48,6 +48,16 @@ RunChannel sRunChannels[kMaxChannels];
FreeListArray<RunStruct, kMaxRuns> RunData; FreeListArray<RunStruct, kMaxRuns> 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) FSerializer& Serialize(FSerializer& arc, const char* keyname, RunStruct& w, RunStruct* def)
{ {
if (arc.BeginObject(keyname)) if (arc.BeginObject(keyname))
@ -55,8 +65,8 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, RunStruct& w, RunS
arc("ref", w.nAIType) arc("ref", w.nAIType)
("val", w.nObjIndex) ("val", w.nObjIndex)
("actor", w.pObjActor) ("actor", w.pObjActor)
("_4", w.next) ("next", w.next)
("_6", w.prev) ("prev", w.prev)
.EndObject(); .EndObject();
} }
return arc; return arc;
@ -490,7 +500,6 @@ void runlist_ReadyChannel(int eax)
void runlist_ProcessChannels() void runlist_ProcessChannels()
{ {
#if 1
int v0; int v0;
int v1; int v1;
int v5; int v5;
@ -542,63 +551,6 @@ void runlist_ProcessChannels()
ChannelList = v1; ChannelList = v1;
} while (v1 != -1); } 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) int runlist_FindChannel(int ax)

View file

@ -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); auto coll = movesprite(pActor, bcos(pSprite->ang) * nVel, bsin(pSprite->ang) * nVel, pSprite->zvel, 5120, 0, CLIPMASK0);
if (coll.exbits & 0x10000) if (coll.exbits & 0x10000)
{ {
auto pSet = pActor->pTarget; DExhumedActor* pSet = pActor->pTarget;
if (!pSet) return; if (!pSet) return;
auto pSetSprite = &pSet->s(); auto pSetSprite = &pSet->s();
@ -267,7 +267,7 @@ void AISet::Tick(RunListEvent* ev)
} }
int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame]; int nFlag = FrameFlag[SeqBase[nSeq] + pActor->nFrame];
auto pTarget = pActor->pTarget; DExhumedActor* pTarget = pActor->pTarget;
if (pTarget && nAction < 10) if (pTarget && nAction < 10)
{ {

View file

@ -33,6 +33,16 @@ FreeListArray<Snake, kMaxSnakes> SnakeList;
int16_t nPlayerSnake[kMaxPlayers]; 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) FSerializer& Serialize(FSerializer& arc, const char* keyname, Snake& w, Snake* def)
{ {
if (arc.BeginObject(keyname)) if (arc.BeginObject(keyname))
@ -74,7 +84,8 @@ void DestroySnake(int nSnake)
for (int i = 0; i < kSnakeSprites; i++) 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(); auto pSprite = &pSnake->s();
runlist_DoSubRunRec(pSprite->lotag - 1); 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() // 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; pActor->pTarget = PlayerList[nPlayer].pActor;
runlist_RadialDamageEnemy(pActor, nDamage, BulletInfo[kWeaponStaff].nRadius); runlist_RadialDamageEnemy(pActor, nDamage, BulletInfo[kWeaponStaff].nRadius);
@ -256,7 +267,8 @@ DExhumedActor* FindSnakeEnemy(int nSnake)
int nPlayer = SnakeList[nSnake].nSnakePlayer; int nPlayer = SnakeList[nSnake].nSnakePlayer;
auto pPlayerActor = PlayerList[nPlayer].Actor(); 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(); auto pSprite = &pActor->s();
int nAngle = pSprite->ang; int nAngle = pSprite->ang;
@ -307,12 +319,13 @@ void AISnake::Tick(RunListEvent* ev)
int nSnake = RunData[ev->nRun].nObjIndex; int nSnake = RunData[ev->nRun].nObjIndex;
assert(nSnake >= 0 && nSnake < kMaxSnakes); assert(nSnake >= 0 && nSnake < kMaxSnakes);
auto pActor = SnakeList[nSnake].pSprites[0]; DExhumedActor* pActor = SnakeList[nSnake].pSprites[0];
if (!pActor) return;
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
seq_MoveSequence(pActor, SeqOffsets[kSeqSnakehed], 0); seq_MoveSequence(pActor, SeqOffsets[kSeqSnakehed], 0);
auto pEnemySprite = SnakeList[nSnake].pEnemy; DExhumedActor* pEnemySprite = SnakeList[nSnake].pEnemy;
Collision nMov; Collision nMov;
int zVal; int zVal;
@ -374,7 +387,8 @@ void AISnake::Tick(RunListEvent* ev)
for (int i = 7; i > 0; i--) 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(); auto pSprite2 = &pActor2->s();
pSprite2->ang = nAngle; pSprite2->ang = nAngle;

View file

@ -127,7 +127,7 @@ void AISpider::Tick(RunListEvent* ev)
spp->nFrame = 0; spp->nFrame = 0;
} }
auto pTarget = spp->pTarget; DExhumedActor* pTarget = spp->pTarget;
if (pTarget == nullptr || pTarget->s().cstat & 0x101) if (pTarget == nullptr || pTarget->s().cstat & 0x101)
{ {

View file

@ -59,9 +59,6 @@ bool bCamera = false;
int viewz; int viewz;
DExhumedActor* pEnemy;
int nEnemyPal = 0;
// We cannot drag these through the entire event system... :( // We cannot drag these through the entire event system... :(
tspritetype* mytsprite; tspritetype* mytsprite;
@ -198,6 +195,8 @@ static TextOverlay subtitleOverlay;
void DrawView(double smoothRatio, bool sceneonly) void DrawView(double smoothRatio, bool sceneonly)
{ {
DExhumedActor* pEnemy = nullptr;
int nEnemyPal = -1;
int playerX; int playerX;
int playerY; int playerY;
int playerZ; int playerZ;
@ -218,7 +217,7 @@ void DrawView(double smoothRatio, bool sceneonly)
if (nSnakeCam >= 0 && !sceneonly) if (nSnakeCam >= 0 && !sceneonly)
{ {
auto pActor = SnakeList[nSnakeCam].pSprites[0]; DExhumedActor* pActor = SnakeList[nSnakeCam].pSprites[0];
auto pSprite = &pActor->s(); auto pSprite = &pActor->s();
playerX = pSprite->x; playerX = pSprite->x;
@ -497,8 +496,6 @@ void SerializeView(FSerializer& arc)
("camerapan", nCamerapan) ("camerapan", nCamerapan)
("camera", bCamera) ("camera", bCamera)
("viewz", viewz) ("viewz", viewz)
("enemy", pEnemy)
("enemypal", nEnemyPal)
.Array("vertpan", dVertPan, countof(dVertPan)) .Array("vertpan", dVertPan, countof(dVertPan))
.Array("quake", nQuake, countof(nQuake)) .Array("quake", nQuake, countof(nQuake))
.EndObject(); .EndObject();

View file

@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS BEGIN_PS_NS
extern bool bSubTitles; extern bool bSubTitles;
extern DExhumedActor* bestTarget; extern TObjPtr<DExhumedActor*> bestTarget;
extern bool bCamera; extern bool bCamera;
void DrawStatusBar(); void DrawStatusBar();