- 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
#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 "freelistarray.h"
#include "exhumedactor.h"
BEGIN_PS_NS
@ -372,23 +373,10 @@ struct RunChannel
short d;
};
enum class EMessageType
{
ProcessChannel = 1,
Tick,
Process,
Use,
TouchFloor,
LeaveSector,
EnterSector,
Damage,
Draw,
RadialDamage
};
struct RunListEvent
{
EMessageType nMessage;
int nMessage;
int nParam; // mostly the player, sometimes the channel list
int nObjIndex;
DExhumedActor* pObjActor;
@ -400,7 +388,7 @@ struct RunListEvent
int nDamageRadius;
DExhumedActor* pRadialActor;
bool isRadialEvent() const { return nMessage == EMessageType::RadialDamage; }
bool isRadialEvent() const { return nMessage == 1; }
};
struct ExhumedAI
@ -685,7 +673,6 @@ struct AISWPressWall : public ExhumedAI
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);
@ -713,7 +700,7 @@ void runlist_ProcessWallTag(int nWall, short nLotag, short nHitag);
int runlist_CheckRadialDamage(DExhumedActor* actor);
void runlist_RadialDamageEnemy(DExhumedActor* nSprite, short 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_ExecObjects();

View file

@ -443,7 +443,7 @@ void StartDeathSeq(int nPlayer, int nVal)
short nLotag = sector[pSprite->sectnum].lotag;
if (nLotag > 0) {
runlist_SignalRun(nLotag - 1, nPlayer | 0x70000);
runlist_SignalRun(nLotag - 1, nPlayer, &ExhumedAI::EnterSector);
}
if (PlayerList[nPlayer].pPlayerGrenade)
@ -2239,7 +2239,7 @@ sectdone:
{
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)
{
runlist_SignalRun(sector[nSector].lotag - 1, nPlayer | 0x70000);
runlist_SignalRun(sector[nSector].lotag - 1, nPlayer, &ExhumedAI::EnterSector);
}
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)
{
runlist_SignalRun(wall[nearTagWall].lotag - 1, nPlayer | 0x40000);
runlist_SignalRun(wall[nearTagWall].lotag - 1, nPlayer, &ExhumedAI::Use);
}
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,
&aiSpark,
};
extern AiFunc aiFunctions[kFuncMax];
int runlist_GrabRun()
{
@ -334,24 +334,27 @@ void runlist_SubRunRec(int RunPtr)
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;
if (nFunc < 0) {
if (nFunc < 0 || nFunc >= (int)countof(ais)) {
return;
}
assert(nFunc >= 0 && nFunc <= kFuncMax);
if (nFunc > kFuncMax) {
return;
RunListEvent defev;
if (!ev)
{
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.
aiFunctions[nFunc](nObject, nMessage, nDamage, nRun);
(ais[nFunc]->*func)(ev);
}
void runlist_ExplodeSignalRun()
@ -374,7 +377,12 @@ void runlist_ExplodeSignalRun()
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];
}
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) {
runlist_PushMoveRun(edx);
@ -426,7 +434,7 @@ void runlist_SignalRun(int NxtPtr, int edx)
NxtPtr = RunData[RunPtr].next;
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)
{
sRunChannels[ChannelList].d = d ^ 2;
runlist_SignalRun(sRunChannels[ChannelList].a, ChannelList | 0x10000);
runlist_SignalRun(sRunChannels[ChannelList].a, ChannelList, &ExhumedAI::ProcessChannel);
}
if (d & 1)
{
sRunChannels[ChannelList].d ^= 1;
runlist_SignalRun(sRunChannels[ChannelList].a, 0x30000);
runlist_SignalRun(sRunChannels[ChannelList].a, 0, &ExhumedAI::Process);
}
if (sRunChannels[ChannelList].d)
@ -561,13 +569,13 @@ void runlist_ProcessChannels()
if (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)
{
sRunChannels[nChannel].d = d ^ 1;
runlist_SignalRun(sRunChannels[nChannel].a, 0x30000);
runlist_SignalRun(sRunChannels[nChannel].a, 0, &ExhumedAI::Process);
}
if (sRunChannels[nChannel].d == 0)
@ -625,7 +633,7 @@ int runlist_AllocChannel(int a)
void runlist_ExecObjects()
{
runlist_ProcessChannels();
runlist_SignalRun(RunChain, 0x20000);
runlist_SignalRun(RunChain, 0, &ExhumedAI::Tick);
}
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;
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)
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)
{
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))
{