- cleaned up the run list interface.

Due to serialization concerns it still isn't optimal, though, because we cannot get rid of the index table yet.
This commit is contained in:
Christoph Oelckers 2021-10-28 18:57:50 +02:00
parent 791240786d
commit 91ecda2fcb
5 changed files with 43 additions and 396 deletions

View file

@ -49,356 +49,3 @@
// This includes the VM so it is last // This includes the VM so it is last
#include "src/d_menu.cpp" #include "src/d_menu.cpp"
// just to keep things temporarily clean.
BEGIN_PS_NS
void FuncAnim(int nObject, int nMessage, int nDamage, int nRun)
{
AIAnim ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncAnubis(int nObject, int nMessage, int nDamage, int nRun)
{
AIAnubis ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncBubble(int nObject, int nMessage, int nDamage, int nRun)
{
AIBubble ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncBullet(int nObject, int nMessage, int nDamage, int nRun)
{
AIBullet ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncFishLimb(int nObject, int nMessage, int nDamage, int nRun)
{
AIFishLimb ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncFish(int nObject, int nMessage, int nDamage, int nRun)
{
AIFish ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncGrenade(int nObject, int nMessage, int nDamage, int nRun)
{
AIGrenade ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncLavaLimb(int nObject, int nMessage, int nDamage, int nRun)
{
AILavaDudeLimb ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncLava(int nObject, int nMessage, int nDamage, int nRun)
{
AILavaDude ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncLion(int nObject, int nMessage, int nDamage, int nRun)
{
AILion ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncCreatureChunk(int nObject, int nMessage, int nDamage, int nRun)
{
AICreatureChunk ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncMummy(int nObject, int nMessage, int nDamage, int nRun)
{
AIMummy ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncElev(int nObject, int nMessage, int nDamage, int nRun)
{
AIElev ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncWallFace(int nObject, int nMessage, int nDamage, int nRun)
{
AIWallFace ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncSlide(int nObject, int nMessage, int nDamage, int nRun)
{
AISlide ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncTrap(int nObject, int nMessage, int nDamage, int nRun)
{
AITrap ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncSpark(int nObject, int nMessage, int nDamage, int nRun)
{
AISpark ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncEnergyBlock(int nObject, int nMessage, int nDamage, int nRun)
{
AIEnergyBlock ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncObject(int nObject, int nMessage, int nDamage, int nRun)
{
AIObject ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncPlayer(int nObject, int nMessage, int nDamage, int nRun)
{
AIPlayer ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncQueenEgg(int nObject, int nMessage, int nDamage, int nRun)
{
AIQueenEgg ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncQueenHead(int nObject, int nMessage, int nDamage, int nRun)
{
AIQueenHead ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncQueen(int nObject, int nMessage, int nDamage, int nRun)
{
AIQueen ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncRa(int nObject, int nMessage, int nDamage, int nRun)
{
AIRa ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncRat(int nObject, int nMessage, int nDamage, int nRun)
{
AIRat ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncRex(int nObject, int nMessage, int nDamage, int nRun)
{
AIRex ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncRoach(int nObject, int nMessage, int nDamage, int nRun)
{
AIRoach ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncScorp(int nObject, int nMessage, int nDamage, int nRun)
{
AIScorp ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncSoul(int nObject, int nMessage, int nDamage, int nRun)
{
AISoul ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncSet(int nObject, int nMessage, int nDamage, int nRun)
{
AISet ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncSnake(int nObject, int nMessage, int nDamage, int nRun)
{
AISnake ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncSpider(int nObject, int nMessage, int nDamage, int nRun)
{
AISpider ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
void FuncSwReady(int nObject, int nMessage, int, int nRun)
{
AISWReady ai;
runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun);
}
void FuncSwPause(int nObject, int nMessage, int, int nRun)
{
AISWPause ai;
runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun);
}
void FuncSwStepOn(int nObject, int nMessage, int, int nRun)
{
AISWStepOn ai;
runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun);
}
void FuncSwNotOnPause(int nObject, int nMessage, int, int nRun)
{
AISWNotOnPause ai;
runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun);
}
void FuncSwPressSector(int nObject, int nMessage, int, int nRun)
{
AISWPressSector ai;
runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun);
}
void FuncSwPressWall(int nObject, int nMessage, int, int nRun)
{
AISWPressWall ai;
runlist_DispatchEvent(&ai, nObject, nMessage, 0, nRun);
}
void FuncWasp(int nObject, int nMessage, int nDamage, int nRun)
{
AIWasp ai;
runlist_DispatchEvent(&ai, nObject, nMessage, nDamage, nRun);
}
AiFunc aiFunctions[kFuncMax] = {
FuncElev,
FuncSwReady,
FuncSwPause,
FuncSwStepOn,
FuncSwNotOnPause,
FuncSwPressSector,
FuncSwPressWall,
FuncWallFace,
FuncSlide,
FuncAnubis,
FuncPlayer,
FuncBullet,
FuncSpider,
FuncCreatureChunk,
FuncMummy,
FuncGrenade,
FuncAnim,
FuncSnake,
FuncFish,
FuncLion,
FuncBubble,
FuncLava,
FuncLavaLimb,
FuncObject,
FuncRex,
FuncSet,
FuncQueen,
FuncQueenHead,
FuncRoach,
FuncQueenEgg,
FuncWasp,
FuncTrap,
FuncFishLimb,
FuncRa,
FuncScorp,
FuncSoul,
FuncRat,
FuncEnergyBlock,
FuncSpark,
};
// This is only temporary so that the event system can be refactored in smaller steps.
void runlist_DispatchEvent(ExhumedAI* ai, int nObject, int nMessage, int nDamage, int nRun)
{
RunListEvent ev{};
ev.nMessage = (EMessageType)(nMessage >> 16);
ev.nObjIndex = RunData[nRun].nObjIndex;
ev.pObjActor = RunData[nRun].pObjActor;
ev.nParam = nObject;
ev.nDamage = nDamage;
ev.nRun = nRun;
switch (ev.nMessage)
{
case EMessageType::ProcessChannel:
ai->ProcessChannel(&ev);
break;
case EMessageType::Tick:
ai->Tick(&ev);
break;
case EMessageType::Process:
ai->Process(&ev);
break;
case EMessageType::Use:
ai->Use(&ev);
break;
case EMessageType::TouchFloor:
ai->TouchFloor(&ev);
break;
case EMessageType::LeaveSector:
ai->LeaveSector(&ev);
break;
case EMessageType::EnterSector:
ai->EnterSector(&ev);
break;
case EMessageType::Damage:
ev.pOtherActor = &exhumedActors[nObject];
ai->Damage(&ev);
break;
case EMessageType::Draw:
ev.pTSprite = &mytsprite[nObject];
ai->Draw(&ev);
break;
case EMessageType::RadialDamage:
ev.nRadialDamage = nRadialDamage;
ev.nDamageRadius = nDamageRadius;
ev.pOtherActor = nullptr; // &exhumedActors[nObject]; nObject is always 0 here, this was setting some random invalid target
ev.pRadialActor = pRadialActor;
ai->RadialDamage(&ev);
break;
}
}
END_PS_NS

View file

@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "compat.h" #include "compat.h"
#include "freelistarray.h" #include "freelistarray.h"
#include "exhumedactor.h"
BEGIN_PS_NS BEGIN_PS_NS
@ -372,23 +373,10 @@ struct RunChannel
short d; short d;
}; };
enum class EMessageType
{
ProcessChannel = 1,
Tick,
Process,
Use,
TouchFloor,
LeaveSector,
EnterSector,
Damage,
Draw,
RadialDamage
};
struct RunListEvent struct RunListEvent
{ {
EMessageType nMessage; int nMessage;
int nParam; // mostly the player, sometimes the channel list int nParam; // mostly the player, sometimes the channel list
int nObjIndex; int nObjIndex;
DExhumedActor* pObjActor; DExhumedActor* pObjActor;
@ -400,7 +388,7 @@ struct RunListEvent
int nDamageRadius; int nDamageRadius;
DExhumedActor* pRadialActor; DExhumedActor* pRadialActor;
bool isRadialEvent() const { return nMessage == EMessageType::RadialDamage; } bool isRadialEvent() const { return nMessage == 1; }
}; };
struct ExhumedAI struct ExhumedAI
@ -685,7 +673,6 @@ struct AISWPressWall : public ExhumedAI
void Use(RunListEvent* ev) override; void Use(RunListEvent* ev) override;
}; };
void runlist_DispatchEvent(ExhumedAI* ai, int nObject, int nMessage, int nDamage, int nRun);
typedef void(*AiFunc)(int, int, int, int nRun); typedef void(*AiFunc)(int, int, int, int nRun);
@ -713,7 +700,7 @@ void runlist_ProcessWallTag(int nWall, short nLotag, short nHitag);
int runlist_CheckRadialDamage(DExhumedActor* actor); int runlist_CheckRadialDamage(DExhumedActor* actor);
void runlist_RadialDamageEnemy(DExhumedActor* nSprite, short nSprite2, short nDamage); void runlist_RadialDamageEnemy(DExhumedActor* nSprite, short nSprite2, short nDamage);
void runlist_DamageEnemy(DExhumedActor* nSprite, DExhumedActor* nSprite2, short nDamage); void runlist_DamageEnemy(DExhumedActor* nSprite, DExhumedActor* nSprite2, short nDamage);
void runlist_SignalRun(int NxtPtr, int edx); void runlist_SignalRun(int NxtPtr, int edx, void(ExhumedAI::* func)(RunListEvent*), RunListEvent* ev = nullptr);
void runlist_CleanRunRecs(); void runlist_CleanRunRecs();
void runlist_ExecObjects(); void runlist_ExecObjects();

View file

@ -443,7 +443,7 @@ void StartDeathSeq(int nPlayer, int nVal)
short nLotag = sector[pSprite->sectnum].lotag; short nLotag = sector[pSprite->sectnum].lotag;
if (nLotag > 0) { if (nLotag > 0) {
runlist_SignalRun(nLotag - 1, nPlayer | 0x70000); runlist_SignalRun(nLotag - 1, nPlayer, &ExhumedAI::EnterSector);
} }
if (PlayerList[nPlayer].pPlayerGrenade) if (PlayerList[nPlayer].pPlayerGrenade)
@ -2239,7 +2239,7 @@ sectdone:
{ {
if (sector[pPlayerSprite->sectnum].lotag > 0) if (sector[pPlayerSprite->sectnum].lotag > 0)
{ {
runlist_SignalRun(sector[pPlayerSprite->sectnum].lotag - 1, nPlayer | 0x50000); runlist_SignalRun(sector[pPlayerSprite->sectnum].lotag - 1, nPlayer, &ExhumedAI::TouchFloor);
} }
} }
@ -2247,12 +2247,12 @@ sectdone:
{ {
if (sector[nSector].lotag > 0) if (sector[nSector].lotag > 0)
{ {
runlist_SignalRun(sector[nSector].lotag - 1, nPlayer | 0x70000); runlist_SignalRun(sector[nSector].lotag - 1, nPlayer, &ExhumedAI::EnterSector);
} }
if (sector[pPlayerSprite->sectnum].lotag > 0) if (sector[pPlayerSprite->sectnum].lotag > 0)
{ {
runlist_SignalRun(sector[pPlayerSprite->sectnum].lotag - 1, nPlayer | 0x60000); runlist_SignalRun(sector[pPlayerSprite->sectnum].lotag - 1, nPlayer, &ExhumedAI::LeaveSector);
} }
} }
@ -2264,12 +2264,12 @@ sectdone:
if (nearTagWall >= 0 && wall[nearTagWall].lotag > 0) if (nearTagWall >= 0 && wall[nearTagWall].lotag > 0)
{ {
runlist_SignalRun(wall[nearTagWall].lotag - 1, nPlayer | 0x40000); runlist_SignalRun(wall[nearTagWall].lotag - 1, nPlayer, &ExhumedAI::Use);
} }
if (nearTagSector >= 0 && sector[nearTagSector].lotag > 0) if (nearTagSector >= 0 && sector[nearTagSector].lotag > 0)
{ {
runlist_SignalRun(sector[nearTagSector].lotag - 1, nPlayer | 0x40000); runlist_SignalRun(sector[nearTagSector].lotag - 1, nPlayer, &ExhumedAI::Use);
} }
} }

View file

@ -164,7 +164,7 @@ ExhumedAI* ais[kFuncMax] =
&aiEnergyBlock, &aiEnergyBlock,
&aiSpark, &aiSpark,
}; };
extern AiFunc aiFunctions[kFuncMax];
int runlist_GrabRun() int runlist_GrabRun()
{ {
@ -334,24 +334,27 @@ void runlist_SubRunRec(int RunPtr)
RunData[RunPtr].nAIType = -totalmoves; RunData[RunPtr].nAIType = -totalmoves;
} }
void runlist_SendMessageToRunRec(int nRun, int nObject, int nMessage, int nDamage) void runlist_SendMessage(int nRun, int nObject, void(ExhumedAI::* func)(RunListEvent*), RunListEvent* ev)
{ {
int nFunc = RunData[nRun].nAIType >> 16; int nFunc = RunData[nRun].nAIType >> 16;
if (nFunc < 0) { if (nFunc < 0 || nFunc >= (int)countof(ais)) {
return; return;
} }
assert(nFunc >= 0 && nFunc <= kFuncMax); RunListEvent defev;
if (!ev)
if (nFunc > kFuncMax) { {
return; defev = {};
ev = &defev;
} }
ev->nObjIndex = RunData[nRun].nObjIndex;
ev->pObjActor = RunData[nRun].pObjActor;
ev->nParam = nObject;
ev->nRun = nRun;
assert(nFunc < kFuncMax); // REMOVE
// do function pointer call here. (ais[nFunc]->*func)(ev);
aiFunctions[nFunc](nObject, nMessage, nDamage, nRun);
} }
void runlist_ExplodeSignalRun() void runlist_ExplodeSignalRun()
@ -374,7 +377,12 @@ void runlist_ExplodeSignalRun()
if (RunData[runPtr].nObjIndex >= 0 || RunData[runPtr].pObjActor) if (RunData[runPtr].nObjIndex >= 0 || RunData[runPtr].pObjActor)
{ {
runlist_SendMessageToRunRec(runPtr, 0, 0xA0000, 0); RunListEvent ev{};
ev.nMessage = 1;
ev.nRadialDamage = nRadialDamage;
ev.nDamageRadius = nDamageRadius;
ev.pRadialActor = pRadialActor;
runlist_SendMessage(runPtr, 0, &ExhumedAI::RadialDamage, &ev);
} }
} }
} }
@ -399,7 +407,7 @@ int runlist_PopMoveRun()
return sRunStack[nStackCount]; return sRunStack[nStackCount];
} }
void runlist_SignalRun(int NxtPtr, int edx) void runlist_SignalRun(int NxtPtr, int edx, void(ExhumedAI::* func)(RunListEvent*), RunListEvent* ev)
{ {
if (NxtPtr == RunChain && word_966BE != 0) { if (NxtPtr == RunChain && word_966BE != 0) {
runlist_PushMoveRun(edx); runlist_PushMoveRun(edx);
@ -426,7 +434,7 @@ void runlist_SignalRun(int NxtPtr, int edx)
NxtPtr = RunData[RunPtr].next; NxtPtr = RunData[RunPtr].next;
if (RunData[RunPtr].nObjIndex >= 0 || RunData[RunPtr].pObjActor) { if (RunData[RunPtr].nObjIndex >= 0 || RunData[RunPtr].pObjActor) {
runlist_SendMessageToRunRec(RunPtr, edx & 0xffff, edx & ~0xffff, 0); runlist_SendMessage(RunPtr, edx, func, ev);
} }
} }
} }
@ -502,13 +510,13 @@ void runlist_ProcessChannels()
if (d & 2) if (d & 2)
{ {
sRunChannels[ChannelList].d = d ^ 2; sRunChannels[ChannelList].d = d ^ 2;
runlist_SignalRun(sRunChannels[ChannelList].a, ChannelList | 0x10000); runlist_SignalRun(sRunChannels[ChannelList].a, ChannelList, &ExhumedAI::ProcessChannel);
} }
if (d & 1) if (d & 1)
{ {
sRunChannels[ChannelList].d ^= 1; sRunChannels[ChannelList].d ^= 1;
runlist_SignalRun(sRunChannels[ChannelList].a, 0x30000); runlist_SignalRun(sRunChannels[ChannelList].a, 0, &ExhumedAI::Process);
} }
if (sRunChannels[ChannelList].d) if (sRunChannels[ChannelList].d)
@ -561,13 +569,13 @@ void runlist_ProcessChannels()
if (d & 2) if (d & 2)
{ {
sRunChannels[nChannel].d = d ^ 2; sRunChannels[nChannel].d = d ^ 2;
runlist_SignalRun(sRunChannels[nChannel].a, ChannelList | 0x10000); runlist_SignalRun(sRunChannels[nChannel].a, ChannelList, &ExhumedAI::ProcessChannel);
} }
if (d & 1) if (d & 1)
{ {
sRunChannels[nChannel].d = d ^ 1; sRunChannels[nChannel].d = d ^ 1;
runlist_SignalRun(sRunChannels[nChannel].a, 0x30000); runlist_SignalRun(sRunChannels[nChannel].a, 0, &ExhumedAI::Process);
} }
if (sRunChannels[nChannel].d == 0) if (sRunChannels[nChannel].d == 0)
@ -625,7 +633,7 @@ int runlist_AllocChannel(int a)
void runlist_ExecObjects() void runlist_ExecObjects()
{ {
runlist_ProcessChannels(); runlist_ProcessChannels();
runlist_SignalRun(RunChain, 0x20000); runlist_SignalRun(RunChain, 0, &ExhumedAI::Tick);
} }
void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag) void runlist_ProcessSectorTag(int nSector, int nLotag, int nHitag)
@ -1730,7 +1738,10 @@ void runlist_DamageEnemy(DExhumedActor* pActor, DExhumedActor* pActor2, short nD
short nPreCreaturesKilled = nCreaturesKilled; short nPreCreaturesKilled = nCreaturesKilled;
runlist_SendMessageToRunRec(nRun, pActor2 ? pActor2->GetSpriteIndex(): -1, 0x80000, nDamage * 4); RunListEvent ev{};
ev.pOtherActor = pActor2;
ev.nDamage = nDamage;
runlist_SendMessage(nRun, -1, &ExhumedAI::Damage, &ev);
// is there now one less creature? (has one died) // is there now one less creature? (has one died)
if (nPreCreaturesKilled < nCreaturesKilled && pActor2 != nullptr) if (nPreCreaturesKilled < nCreaturesKilled && pActor2 != nullptr)

View file

@ -130,7 +130,9 @@ static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y
if (pSprite->statnum > 0) if (pSprite->statnum > 0)
{ {
runlist_SignalRun(pSprite->lotag - 1, nTSprite | 0x90000); RunListEvent ev{};
ev.pTSprite = pTSprite;
runlist_SignalRun(pSprite->lotag - 1, nTSprite, &ExhumedAI::Draw, &ev);
if ((pSprite->statnum < 150) && (pSprite->cstat & 0x101) && (pActor != pPlayerActor)) if ((pSprite->statnum < 150) && (pSprite->cstat & 0x101) && (pActor != pPlayerActor))
{ {