- 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)
{
#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);
}

View file

@ -198,7 +198,7 @@ void FuncLion(int, int, int, int);
// 16 bytes
struct BlockInfo
{
DExhumedActor* pActor;
TObjPtr<DExhumedActor*> 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<DExhumedActor*> nChunkSprite[];
extern TObjPtr<DExhumedActor*> 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<DExhumedActor*> pFinaleSpr;
void InitObjects();
void InitElev();
@ -305,8 +305,8 @@ void FuncQueen(int, int, int, int);
struct RA
{
DExhumedActor* pActor;
DExhumedActor* pTarget;
TObjPtr<DExhumedActor*> pActor;
TObjPtr<DExhumedActor*> 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<DExhumedActor*> 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<DExhumedActor*> pEnemy; // nRun
TObjPtr<DExhumedActor*> pSprites[kSnakeSprites];
int16_t nCountdown;
int16_t nRun;

View file

@ -28,7 +28,6 @@ BEGIN_PS_NS
int nMagicSeq = -1;
int nPreMagicSeq = -1;
int nSavePointSeq = -1;
//FreeListArray<Anim, kMaxAnims> 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)
{

View file

@ -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];

View file

@ -34,8 +34,8 @@ enum { kMaxBullets = 500 };
// 32 bytes
struct Bullet
{
DExhumedActor* pActor;
DExhumedActor* pEnemy;
TObjPtr<DExhumedActor*> pActor;
TObjPtr<DExhumedActor*> pEnemy;
int16_t nSeq;
int16_t nFrame;
@ -56,6 +56,16 @@ FreeListArray<Bullet, kMaxBullets> 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];

View file

@ -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

View file

@ -52,11 +52,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS
TObjPtr<DExhumedActor*> 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;

View file

@ -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<DExhumedActor*> pSpiritSprite;
extern bool bInDemo;

View file

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

View file

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

View file

@ -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();

View file

@ -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());

View file

@ -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();
}

View file

@ -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;

View file

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

View file

@ -98,9 +98,15 @@ AnimInfo nItemAnimInfo[] = {
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;
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)
{

View file

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

View file

@ -42,7 +42,7 @@ struct Flash
{
walltype* pWall;
sectortype* pSector;
DExhumedActor* pActor;
TObjPtr<DExhumedActor*> 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;

View file

@ -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);

View file

@ -35,21 +35,33 @@ int nPushBlocks;
// TODO - moveme?
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;
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)
{

View file

@ -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;

View file

@ -67,14 +67,14 @@ struct Bob
struct Drip
{
DExhumedActor* pActor;
TObjPtr<DExhumedActor*> pActor;
int16_t nCount;
};
// 56 bytes
struct Elev
{
DExhumedActor* pActor;
TObjPtr<DExhumedActor*> pActor;
sectortype* pSector;
int16_t nFlags;
int16_t nChannel;
@ -110,7 +110,7 @@ struct wallFace
struct slideData
{
DExhumedActor* pActor;
TObjPtr<DExhumedActor*> pActor;
int16_t nChannel;
int16_t nStart;
int16_t nRunRec;
@ -142,7 +142,7 @@ struct Point
struct Trap
{
DExhumedActor* pActor;
TObjPtr<DExhumedActor*> pActor;
walltype* pWall1;
walltype* pWall2;
@ -167,11 +167,22 @@ TArray<slideData> SlideData;
TArray<wallFace> WallFace;
TArray<Drip> sDrip;
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 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];

View file

@ -77,7 +77,7 @@ int nLocalPlayer = 0;
Player PlayerList[kMaxPlayers];
DExhumedActor* nNetStartSprite[kMaxPlayers] = { };
TObjPtr<DExhumedActor*> 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();

View file

@ -55,7 +55,7 @@ struct PlayerSave
struct Player
{
DExhumedActor* Actor() { return pActor; }
DExhumedActor* pActor;
TObjPtr<DExhumedActor*> 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<DExhumedActor*> pPlayerGrenade;
TObjPtr<DExhumedActor*> pPlayerFloorSprite;
TObjPtr<DExhumedActor*> pDoppleSprite;
};
@ -120,7 +120,7 @@ extern Player PlayerList[kMaxPlayers];
extern int obobangle, bobangle;
extern DExhumedActor* nNetStartSprite[kMaxPlayers];
extern TObjPtr<DExhumedActor*> nNetStartSprite[kMaxPlayers];
extern int nNetStartSprites;
extern int nCurStartSprite;

View file

@ -70,8 +70,8 @@ static actionSeq EggSeq[] = {
struct Queen
{
DExhumedActor* pActor;
DExhumedActor* pTarget;
TObjPtr<DExhumedActor*> pActor;
TObjPtr<DExhumedActor*> pTarget;
int16_t nHealth;
int16_t nFrame;
int16_t nAction;
@ -83,8 +83,8 @@ struct Queen
struct Egg
{
DExhumedActor* pActor;
DExhumedActor* pTarget;
TObjPtr<DExhumedActor*> pActor;
TObjPtr<DExhumedActor*> pTarget;
int16_t nHealth;
int16_t nFrame;
int16_t nAction;
@ -94,8 +94,8 @@ struct Egg
struct Head
{
DExhumedActor* pActor;
DExhumedActor* pTarget;
TObjPtr<DExhumedActor*> pActor;
TObjPtr<DExhumedActor*> 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<DExhumedActor*> 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;

View file

@ -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;

View file

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

View file

@ -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);

View file

@ -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)
{

View file

@ -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;

View file

@ -48,6 +48,16 @@ RunChannel sRunChannels[kMaxChannels];
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)
{
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)

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);
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)
{

View file

@ -33,6 +33,16 @@ FreeListArray<Snake, kMaxSnakes> 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;

View file

@ -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)
{

View file

@ -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();

View file

@ -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<DExhumedActor*> bestTarget;
extern bool bCamera;
void DrawStatusBar();