From ddfb4854243572068d2a287e7c49053f083a326d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 28 May 2023 09:50:16 +0200 Subject: [PATCH] - added a serializer for VMFunction pointers. --- source/common/cutscenes/screenjob.cpp | 4 +- source/common/engine/serializer.cpp | 30 ++ source/common/engine/serializer.h | 1 + source/common/scripting/backend/vmbuilder.cpp | 2 +- source/common/scripting/core/imports.cpp | 1 + source/common/scripting/vm/vm.h | 3 +- source/games/sw/src/save.cpp | 2 +- wadsrc/static/zscript/games/sw/swactor.zs | 291 ++++++++++++++++++ 8 files changed, 329 insertions(+), 5 deletions(-) diff --git a/source/common/cutscenes/screenjob.cpp b/source/common/cutscenes/screenjob.cpp index 97bc76862..c22745956 100644 --- a/source/common/cutscenes/screenjob.cpp +++ b/source/common/cutscenes/screenjob.cpp @@ -87,8 +87,8 @@ VMFunction* LookupFunction(const char* qname, bool validate) size_t p = strcspn(qname, "."); if (p == 0) I_Error("Call to undefined function %s", qname); - FString clsname(qname, p); - FString funcname = qname + p + 1; + FName clsname(qname, p, true); + FName funcname(qname + p + 1, true); auto func = PClass::FindFunction(clsname, funcname); if (func == nullptr) diff --git a/source/common/engine/serializer.cpp b/source/common/engine/serializer.cpp index 8c68b5a3b..ec84a5fee 100644 --- a/source/common/engine/serializer.cpp +++ b/source/common/engine/serializer.cpp @@ -55,6 +55,7 @@ #include "textures.h" #include "texturemanager.h" #include "base64.h" +#include "vm.h" extern DObject *WP_NOCHANGE; bool save_full = false; // for testing. Should be removed afterward. @@ -1565,6 +1566,35 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary } } +template<> FSerializer& Serialize(FSerializer& arc, const char* key, VMFunction*& func, VMFunction**) +{ + if (arc.isWriting()) + { + arc.WriteKey(key); + if (func) arc.w->String(func->QualifiedName); + else arc.w->Null(); + } + else + { + func = nullptr; + + auto val = arc.r->FindKey(key); + if (val != nullptr && val->IsString()) + { + auto qname = val->GetString(); + size_t p = strcspn(qname, "."); + if (p != 0) + { + FName clsname(qname, p, true); + FName funcname(qname + p + 1, true); + func = PClass::FindFunction(clsname, funcname); + } + } + + } + return arc; +} + //========================================================================== // // Handler to retrieve a numeric value of any kind. diff --git a/source/common/engine/serializer.h b/source/common/engine/serializer.h index 63bfb3529..b337cd832 100644 --- a/source/common/engine/serializer.h +++ b/source/common/engine/serializer.h @@ -310,6 +310,7 @@ inline FSerializer& Serialize(FSerializer& arc, const char* key, BitArray& value template<> FSerializer& Serialize(FSerializer& arc, const char* key, PClass*& clst, PClass** def); template<> FSerializer& Serialize(FSerializer& arc, const char* key, FFont*& font, FFont** def); template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary *&dict, Dictionary **def); +template<> FSerializer& Serialize(FSerializer& arc, const char* key, VMFunction*& dict, VMFunction** def); inline FSerializer &Serialize(FSerializer &arc, const char *key, DVector3 &p, DVector3 *def) { diff --git a/source/common/scripting/backend/vmbuilder.cpp b/source/common/scripting/backend/vmbuilder.cpp index 35bf88e86..ae34ea4c5 100644 --- a/source/common/scripting/backend/vmbuilder.cpp +++ b/source/common/scripting/backend/vmbuilder.cpp @@ -790,7 +790,7 @@ VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo it.PrintableName = name; it.Function = new VMScriptFunction; it.Function->Name = functype->SymbolName; - it.Function->PrintableName = ClassDataAllocator.Strdup(name); + it.Function->QualifiedName = it.Function->PrintableName = ClassDataAllocator.Strdup(name); it.Function->ImplicitArgs = functype->GetImplicitArgs(); it.Proto = nullptr; it.FromDecorate = fromdecorate; diff --git a/source/common/scripting/core/imports.cpp b/source/common/scripting/core/imports.cpp index cc50d22e5..3006462cd 100644 --- a/source/common/scripting/core/imports.cpp +++ b/source/common/scripting/core/imports.cpp @@ -198,6 +198,7 @@ void InitImports() { assert(afunc->VMPointer != NULL); *(afunc->VMPointer) = new VMNativeFunction(afunc->Function, afunc->FuncName); + (*(afunc->VMPointer))->QualifiedName = ClassDataAllocator.Strdup(FStringf("%s.%s", afunc->ClassName + 1, afunc->FuncName)); (*(afunc->VMPointer))->PrintableName = ClassDataAllocator.Strdup(FStringf("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName)); (*(afunc->VMPointer))->DirectNativeCall = afunc->DirectNative; AFTable.Push(*afunc); diff --git a/source/common/scripting/vm/vm.h b/source/common/scripting/vm/vm.h index 2c42bd1f7..db2e305da 100644 --- a/source/common/scripting/vm/vm.h +++ b/source/common/scripting/vm/vm.h @@ -450,7 +450,8 @@ public: FName Name; const uint8_t *RegTypes = nullptr; TArray DefaultArgs; - const char * PrintableName = nullptr; // so that the VM can print meaningful info if something in this function goes wrong. (allocated from the memory arena) + const char* QualifiedName = nullptr; + const char* PrintableName = nullptr; // same as QualifiedName, but can have additional annotations. class PPrototype *Proto; TArray ArgFlags; // Should be the same length as Proto->ArgumentTypes diff --git a/source/games/sw/src/save.cpp b/source/games/sw/src/save.cpp index 800431a4f..801965ac3 100644 --- a/source/games/sw/src/save.cpp +++ b/source/games/sw/src/save.cpp @@ -828,9 +828,9 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, USER& w, USER* def ("filler", w.filler, def->filler) ("wallshade", w.WallShade) ("rotator", w.rotator) + ("actoractionfunc", w.__legacyState.ActorActionFunc) ("oz", w.oz, def->oz); - SerializeCodePtr(arc, "ActorActionFunc", (void**)&w.__legacyState.ActorActionFunc); arc.EndObject(); if (arc.isReading()) diff --git a/wadsrc/static/zscript/games/sw/swactor.zs b/wadsrc/static/zscript/games/sw/swactor.zs index 49a1f34c3..2a962fcda 100644 --- a/wadsrc/static/zscript/games/sw/swactor.zs +++ b/wadsrc/static/zscript/games/sw/swactor.zs @@ -1,3 +1,294 @@ class SWActor : CoreActor native { + // all ANIMATORs. + native int DoBunnyMove(); + native int DoBunnyGrowUp(); + native int DoBunnyEat(); + native int DoBunnyScrew(); + native int NullBunny(); + native int InitBunnySlash(); + native int DoBunnyStandKill(); + native int DoBunnyPain(); + native int DoBunnyMoveJump(); + native int DoBunnyBeginJumpAttack(); + native int BunnySpew(); + + native int DoCoolgMove(); + native int NullCoolg(); + native int InitCoolgBash(); + native int InitCoolgFire(); + native int DoCoolgPain(); + native int DoCoolgDeath(); + native int DoCoolgBirth(); + + native int DoCoolieMove(); + native int CooliePain(); + native int NullCoolie(); + native int SpawnCoolieExp(); + native int DoCoolieWaitBirth(); + native int SpawnCoolg(); + + native int DoEelMove(); + native int InitEelFire(); + native int NullEel(); + native int DoEelDeath(); + + native int NullGirlNinja(); + native int DoGirlNinjaMove(); + native int DoGirlNinjaPain(); + native int DoGirlNinjaSpecial(); + + native int InitEnemyMine(); + native int InitEnemyCrossbow(); + + native int DoGoroMove(); + native int NullGoro(); + native int InitGoroChop(); + native int DoGoroPain(); + native int InitEnemyFireball(); + + native int DoHornetMove(); + native int DoHornetDeath(); + + native int BloodSprayFall(); + native int DoSuicide(); + native int DoRadiationCloud(); + native int DoChemBomb(); + native int DoCaltrops(); + native int DoCaltropsStick(); + native int DoCarryFlag(); + native int DoCarryFlagNoDet(); + native int DoFlag(); + native int DoPhosphorus(); + native int DoBloodSpray(); + native int DoWallBloodDrip(); + + native int DoLavaMove(); + native int NullLava(); + native int InitLavaThrow(); + native int InitLavaFlame(); + + native int DoActorDeathMove(); + native int QueueFloorBlood(); + native int DoActorDebris(); + native int InitActorDecide(); + + native int DoToiletGirl(); + native int ToiletGirlPain(); + native int ToiletGirlUzi(); + native int InitEnemyUzi(); + native int DoWashGirl(); + native int WashGirlUzi(); + native int DoTrashCan(); + native int TrashCanPain(); + native int PachinkoLightOperate(); + native int Pachinko1Operate(); + native int PachinkoCheckWin(); + native int DoCarGirl(); + native int CarGirlPain(); + native int CarGirlUzi(); + native int DoMechanicGirl(); + native int MechanicGirlPain(); + native int MechanicGirlDrill(); + native int DoSailorGirl(); + native int SailorGirlPain(); + native int SailorGirlThrow(); + native int DoPruneGirl(); + native int PruneGirlPain(); + native int WashGirlPain(); + + native int DoNinjaMove(); + native int NullNinja(); + native int DoNinjaCeiling(); + native int DoNinjaPain(); + native int InitEnemyStar(); + native int InitEnemyMirv(); + native int InitEnemyNapalm(); + native int InitEnemyRocket(); + native int InitSpriteGrenade(); + native int InitFlashBomb(); + native int CheckFire(); + native int DoNinjaSpecial(); + native int DoNinjaGrabThroat(); + native int DoNinjaHariKari(); + + native int DoRipperMove(); + native int NullRipper(); + native int InitRipperSlash(); + native int DoRipperStandHeart(); + native int DoRipperHang(); + native int DoRipperPain(); + native int DoRipperMoveJump(); + native int DoRipperBeginJumpAttack(); + native int DoRipperHangJF(); + + native int DoRipper2Move(); + native int NullRipper2(); + native int DoRipper2Hang(); + native int DoRipper2Pain(); + native int DoRipper2MoveJump(); + native int DoRipper2BeginJumpAttack(); + native int DoRipper2HangJF(); + native int DoRipper2StandHeart(); + native int ChestRipper2(); + + native int DoSerpMove(); + native int NullSerp(); + native int InitSerpSlash(); + native int InitSerpRing(); + native int InitSerpSpell(); + native int InitSerpMonstSpell(); + native int DoDeathSpecial(); + + native int DoSkelMove(); + native int NullSkel(); + native int InitSkelSlash(); + native int InitSkelSpell(); + native int DoSkelPain(); + native int DoSkelInitTeleport(); + native int DoSkelTeleport(); + native int DoSkelTermTeleport(); + + native int DoSkullWait(); + native int DoSerpRing(); + native int DoSkullJump(); + native int DoDamageTest(); + native int DoSkullSpawnShrap(); + native int DoBettyWait(); + native int DoBettyJump(); + + native int DoSumoMove(); + native int NullSumo(); + native int InitSumoFart(); + native int InitSumoClap(); + native int InitSumoStomp(); + native int DoSumoDeathMelt(); + + native int DoDefaultStat(); + native int DoPuff(); + native int DoRailPuff(); + native int DoTracer(); + native int DoEMP(); + native int DoEMPBurst(); + native int DoFastShrapJumpFall(); + + native int DoTankShell(); + native int DoVehicleSmoke(); + native int DoWaterSmoke(); + native int DoUziSmoke(); + native int DoShotgunSmoke(); + native int DoUziBullet(); + native int DoBubble(); + native int DoCrossBolt(); + native int DoStar(); + native int DoLavaBoulder(); + native int DoShrapDamage(); + native int DoVulcanBoulder(); + native int DoGrenade(); + native int DoMineStuck(); + native int DoMine(); + native int DoMineSpark(); + native int DoMeteor(); + native int DoMirvMissile(); + native int DoSerpMeteor(); + native int DoSpear(); + native int DoRocket(); + native int DoRail(); + native int DoLaser(); + native int DoMicro(); + native int DoMicroMini(); + native int DoBoltThinMan(); + native int DoBoltSeeker(); + native int DoBoltFatMan(); + native int DoBoltShrapnel(); + native int DoCoolgFire(); + native int DoCoolgDrip(); + native int DoPlasma(); + native int DoShrapJumpFall(); + + native int DoTracerShrap(); + native int DoVomitSplash(); + native int DoVomit(); + native int DoMirv(); + native int DoBloodWorm(); + native int DoNapalm(); + native int DoRing(); + native int DoFireball(); + native int DoBreakFlames(); + native int DoFireballFlames(); + native int DoSectorExp(); + native int SpawnShrapX(); + native int DoExpDamageTest(); + native int DoMineExpMine(); + native int DoMineExp(); + native int SpawnGrenadeSmallExp(); + native int DoElectro(); + native int DoTeleRipper(); + native int DoPlasmaDone(); + native int DoPlasmaFountain(); + native int DoFootPrints(); + native int DoPlayerSpriteReset(); + + native int DoFloorBlood(); + native int DoWallBlood(); + + native int DoGet(); + native int DoCoin(); + native int DoFireFly(); + + native int DoZillaMove(); + native int DoZillaStomp(); + native int NullZilla(); + native int InitZillaRail(); + native int InitZillaRocket(); + native int DoZillaDeathMelt(); + + native int DoZombieMove(); + native int NullZombie(); + native int DoZombiePain(); + native int InitEnemyNuke(); + native int InitEnemyRail(); + + native int InitActorRunAway(); + native int InitActorAttack(); + native int InitActorDuck(); + native int InitActorEvade(); + native int InitActorFindPlayer(); + native int InitActorMoveCloser(); + native int InitActorReposition(); + native int InitActorWanderAround(); + native int InitCoolgCircle(); + native int InitCoolieCharge(); + native int InitHornetCircle(); + native int InitHornetSting(); + native int InitRipper2Charge(); + native int InitRipper2Hang(); + native int InitRipperHang(); + native int InitActorRunToward(); + native int InitActorSetDecide(); + native int DoActorDecide(); + native int DoActorMoveJump(); + native int DoActorDuck(); + native int NinjaJumpActionFunc(); + native int DoActorMoveCloser(); + native int DoActorAttack(); + native int DoActorReposition(); + native int DoCoolgCircle(); + native int DoHornetCircle(); + native int GenerateDrips(); + native int DoSpawnSpot(); + native int DoGrating(); + native int DoVator(); + native int DoVatorAuto(); + native int DoRotator(); + native int DoActorPause(); + native int DoSlidor(); + native int DoSpike(); + native int DoSpikeAuto(); + native int DoLavaErupt(); + native int SpawnVehicleSmoke(); + native int DoLaserStart(); + native int DoTracerStart(); + native int DoRailStart(); + }