diff --git a/src/actor.h b/src/actor.h index 18b128215..6718e0931 100644 --- a/src/actor.h +++ b/src/actor.h @@ -667,6 +667,8 @@ public: // Plays the actor's ActiveSound if its voice isn't already making noise. void PlayActiveSound (); + void RestoreSpecialPosition(); + // Called by PIT_CheckThing() and needed for some Hexen things. // Returns -1 for normal behavior, 0 to return false, and 1 to return true. // I'm not sure I like it this way, but it will do for now. diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index e2c5a6ea3..6f9687aea 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -174,8 +174,6 @@ struct AmmoPerAttack VMFunction *ptr; }; -DECLARE_ACTION(A_Punch) - // Default ammo use of the various weapon attacks static AmmoPerAttack AmmoPerAttacks[] = { { NAME_A_Punch, 0}, diff --git a/src/dthinker.cpp b/src/dthinker.cpp index 7c8bf1bf5..fd20a4e79 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -313,8 +313,7 @@ void DThinker::CallPostBeginPlay() { // Without the type cast this picks the 'void *' assignment... VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } else { @@ -557,8 +556,7 @@ void DThinker::CallTick() { // Without the type cast this picks the 'void *' assignment... VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } else Tick(); } diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index 237de2ce9..91b88a053 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -22,7 +22,6 @@ #include "virtual.h" #include "a_ammo.h" -static FRandom pr_restore ("RestorePos"); EXTERN_CVAR(Bool, sv_unlimited_pickup) IMPLEMENT_CLASS(PClassInventory, false, false) @@ -137,63 +136,6 @@ DEFINE_ACTION_FUNCTION(AInventory, A_RestoreSpecialDoomThing) return 0; } -//--------------------------------------------------------------------------- -// -// PROP A_RestoreSpecialPosition -// -//--------------------------------------------------------------------------- - -DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) -{ - PARAM_SELF_PROLOGUE(AActor); - - // Move item back to its original location - DVector2 sp = self->SpawnPoint; - - self->UnlinkFromWorld(); - self->SetXY(sp); - self->LinkToWorld(true); - self->SetZ(self->Sector->floorplane.ZatPoint(sp)); - P_FindFloorCeiling(self, FFCF_ONLYSPAWNPOS | FFCF_NOPORTALS); // no portal checks here so that things get spawned in this sector. - - if (self->flags & MF_SPAWNCEILING) - { - self->SetZ(self->ceilingz - self->Height - self->SpawnPoint.Z); - } - else if (self->flags2 & MF2_SPAWNFLOAT) - { - double space = self->ceilingz - self->Height - self->floorz; - if (space > 48) - { - space -= 40; - self->SetZ((space * pr_restore()) / 256. + self->floorz + 40); - } - else - { - self->SetZ(self->floorz); - } - } - else - { - self->SetZ(self->SpawnPoint.Z + self->floorz); - } - // Redo floor/ceiling check, in case of 3D floors and portals - P_FindFloorCeiling(self, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); - if (self->Z() < self->floorz) - { // Do not reappear under the floor, even if that's where we were for the - // initial spawn. - self->SetZ(self->floorz); - } - if ((self->flags & MF_SOLID) && (self->Top() > self->ceilingz)) - { // Do the same for the ceiling. - self->SetZ(self->ceilingz - self->Height); - } - // Do not interpolate from the position the actor was at when it was - // picked up, in case that is different from where it is now. - self->ClearInterpolation(); - return 0; -} - int AInventory::StaticLastMessageTic; FString AInventory::StaticLastMessage; @@ -322,10 +264,9 @@ bool AInventory::CallSpecialDropAction(AActor *dropper) { VMValue params[2] = { (DObject*)this, (DObject*)dropper }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); return !!retval; } return SpecialDropAction(dropper); @@ -412,7 +353,7 @@ void AInventory::CallDoEffect() { VMValue params[1] = { (DObject*)this }; VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } else DoEffect(); } @@ -495,10 +436,9 @@ bool AInventory::CallHandlePickup(AInventory *item) // Without the type cast this picks the 'void *' assignment... VMValue params[2] = { (DObject*)self, (DObject*)item }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); if (retval) return true; } else if (self->HandlePickup(item)) return true; @@ -604,10 +544,9 @@ AInventory *AInventory::CallCreateCopy(AActor *other) { VMValue params[2] = { (DObject*)this, (DObject*)other }; VMReturn ret; - VMFrameStack stack; AInventory *retval; ret.PointerAt((void**)&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); return retval; } else return CreateCopy(other); @@ -670,10 +609,9 @@ AInventory *AInventory::CallCreateTossable() { VMValue params[1] = { (DObject*)this }; VMReturn ret; - VMFrameStack stack; AInventory *retval; ret.PointerAt((void**)&retval); - stack.Call(func, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr); return retval; } else return CreateTossable(); @@ -805,10 +743,9 @@ double AInventory::GetSpeedFactor() { VMValue params[2] = { (DObject*)self }; VMReturn ret; - VMFrameStack stack; double retval; ret.FloatAt(&retval); - stack.Call(func, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr); factor *= retval; } self = self->Inventory; @@ -831,10 +768,9 @@ bool AInventory::GetNoTeleportFreeze () { VMValue params[2] = { (DObject*)self }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr); if (retval) return true; } self = self->Inventory; @@ -884,10 +820,9 @@ bool AInventory::CallUse(bool pickup) { VMValue params[2] = { (DObject*)this, pickup }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); return !!retval; } @@ -1090,10 +1025,9 @@ FString AInventory::GetPickupMessage() { VMValue params[1] = { (DObject*)this }; VMReturn ret; - VMFrameStack stack; FString retval; ret.StringAt(&retval); - stack.Call(func, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr); return retval; } else return PickupMessage(); @@ -1150,8 +1084,7 @@ void AInventory::CallPlayPickupSound(AActor *other) IFVIRTUAL(AInventory, PlayPickupSound) { VMValue params[2] = { (DObject*)this, (DObject*)other }; - VMFrameStack stack; - stack.Call(func, params, 2, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr); } else PlayPickupSound(other); } @@ -1182,10 +1115,9 @@ bool AInventory::CallShouldStay() { VMValue params[1] = { (DObject*)this }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr); return !!retval; } else return ShouldStay(); @@ -1264,10 +1196,9 @@ PalEntry AInventory::CallGetBlend() { VMValue params[1] = { (DObject*)this }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr); return retval; } else return GetBlend(); @@ -1521,10 +1452,9 @@ bool AInventory::CallTryPickup (AActor *toucher, AActor **toucher_return) { VMValue params[2] = { (DObject*)this, (void*)&toucher }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); res = !!retval; } else res = TryPickup(toucher); @@ -1536,10 +1466,9 @@ bool AInventory::CallTryPickup (AActor *toucher, AActor **toucher_return) { VMValue params[2] = { (DObject*)this, (void*)&toucher }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); res = !!retval; } else res = TryPickupRestricted(toucher); @@ -1687,8 +1616,7 @@ void AInventory::CallAttachToOwner(AActor *other) IFVIRTUAL(AInventory, AttachToOwner) { VMValue params[2] = { (DObject*)this, (DObject*)other }; - VMFrameStack stack; - stack.Call(func, params, 2, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr); } else AttachToOwner(other); } @@ -1719,8 +1647,7 @@ void AInventory::CallDetachFromOwner() IFVIRTUAL(AInventory, DetachFromOwner) { VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } else DetachFromOwner(); } diff --git a/src/g_inventory/a_weapons.cpp b/src/g_inventory/a_weapons.cpp index 3fd4bc939..19a30dcd8 100644 --- a/src/g_inventory/a_weapons.cpp +++ b/src/g_inventory/a_weapons.cpp @@ -845,8 +845,7 @@ void AWeapon::CallEndPowerup() { // Without the type cast this picks the 'void *' assignment... VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } else EndPowerup(); } @@ -864,10 +863,9 @@ FState *AWeapon::GetUpState () { VMValue params[1] = { (DObject*)this }; VMReturn ret; - VMFrameStack stack; FState *retval; ret.PointerAt((void**)&retval); - stack.Call(func, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr); return retval; } return nullptr; @@ -885,10 +883,9 @@ FState *AWeapon::GetDownState () { VMValue params[1] = { (DObject*)this }; VMReturn ret; - VMFrameStack stack; FState *retval; ret.PointerAt((void**)&retval); - stack.Call(func, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr); return retval; } return nullptr; @@ -906,10 +903,9 @@ FState *AWeapon::GetReadyState () { VMValue params[1] = { (DObject*)this }; VMReturn ret; - VMFrameStack stack; FState *retval; ret.PointerAt((void**)&retval); - stack.Call(func, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr); return retval; } return nullptr; @@ -927,10 +923,9 @@ FState *AWeapon::GetAtkState (bool hold) { VMValue params[2] = { (DObject*)this, hold }; VMReturn ret; - VMFrameStack stack; FState *retval; ret.PointerAt((void**)&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); return retval; } return nullptr; @@ -948,10 +943,9 @@ FState *AWeapon::GetAltAtkState (bool hold) { VMValue params[2] = { (DObject*)this, hold }; VMReturn ret; - VMFrameStack stack; FState *retval; ret.PointerAt((void**)&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); return retval; } return nullptr; diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index afe188019..2e4597617 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -121,35 +121,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath) return 0; } -//========================================================================== -// -// A_GenericFreezeDeath -// -//========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_GenericFreezeDeath) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->Translation = TRANSLATION(TRANSLATION_Standard, 7); - CALL_ACTION(A_FreezeDeath, self); - return 0; -} - //============================================================================ // // A_IceSetTics // //============================================================================ -DEFINE_ACTION_FUNCTION(AActor, A_IceSetTics) +void IceSetTics(AActor *self) { - PARAM_SELF_PROLOGUE(AActor); int floor; - self->tics = 70+(pr_icesettics()&63); - floor = P_GetThingFloorType (self); + self->tics = 70 + (pr_icesettics() & 63); + floor = P_GetThingFloorType(self); if (Terrains[floor].DamageMOD == NAME_Fire) { self->tics >>= 2; @@ -158,6 +142,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceSetTics) { self->tics <<= 1; } +} + +DEFINE_ACTION_FUNCTION(AActor, A_IceSetTics) +{ + PARAM_SELF_PROLOGUE(AActor); + IceSetTics(self); return 0; } @@ -203,7 +193,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) mo->Vel.X = pr_freeze.Random2() / 128.; mo->Vel.Y = pr_freeze.Random2() / 128.; mo->Vel.Z = (mo->Z() - self->Z()) / self->Height * 4; - CALL_ACTION(A_IceSetTics, mo); // set a random tic wait + IceSetTics(mo); // set a random tic wait mo->RenderStyle = self->RenderStyle; mo->Alpha = self->Alpha; } diff --git a/src/g_shared/a_bridge.cpp b/src/g_shared/a_bridge.cpp index 556767f37..138210061 100644 --- a/src/g_shared/a_bridge.cpp +++ b/src/g_shared/a_bridge.cpp @@ -89,24 +89,22 @@ void ACustomBridge::Destroy() // target pointer to center mobj // angle angle of ball -DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit) +static void BridgeOrbit(AActor *self) { - PARAM_SELF_PROLOGUE(AActor); - if (self->target == NULL) { // Don't crash if somebody spawned this into the world // independantly of a Bridge actor. - return 0; + return; } // Set default values // Every five tics, Hexen moved the ball 3/256th of a revolution. - DAngle rotationspeed = 45./32*3/5; + DAngle rotationspeed = 45. / 32 * 3 / 5; double rotationradius = ORBIT_RADIUS; // If the bridge is custom, set non-default values if any. // Set angular speed; 1--128: counterclockwise rotation ~=1--180°; 129--255: clockwise rotation ~= 180--1° - if (self->target->args[3] > 128) rotationspeed = 45./32 * (self->target->args[3]-256) / TICRATE; - else if (self->target->args[3] > 0) rotationspeed = 45./32 * (self->target->args[3]) / TICRATE; + if (self->target->args[3] > 128) rotationspeed = 45. / 32 * (self->target->args[3] - 256) / TICRATE; + else if (self->target->args[3] > 0) rotationspeed = 45. / 32 * (self->target->args[3]) / TICRATE; // Set rotation radius if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->radius) / 100); @@ -114,6 +112,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit) self->SetOrigin(self->target->Vec3Angle(rotationradius, self->Angles.Yaw, 0), true); self->floorz = self->target->floorz; self->ceilingz = self->target->ceilingz; +} + +DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit) +{ + PARAM_SELF_PROLOGUE(AActor); + BridgeOrbit(self); return 0; } @@ -140,7 +144,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeInit) ball = Spawn(balltype, self->Pos(), ALLOW_REPLACE); ball->Angles.Yaw = startangle + (45./32) * (256/ballcount) * i; ball->target = self; - CALL_ACTION(A_BridgeOrbit, ball); + BridgeOrbit(ball); } return 0; } diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index c68fa800c..fb0faef0f 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -139,8 +139,7 @@ void AFastProjectile::Tick () { // Without the type cast this picks the 'void *' assignment... VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } } } diff --git a/src/info.cpp b/src/info.cpp index 69605d454..b8bf3acde 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -75,7 +75,6 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, { ActionCycles.Clock(); - VMFrameStack stack; VMValue params[3] = { self, stateowner, VMValue(info, ATAG_GENERIC) }; // If the function returns a state, store it at *stateret. // If it doesn't return a state but stateret is non-NULL, we need @@ -92,13 +91,13 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, } if (stateret == NULL) { - stack.Call(ActionFunc, params, ActionFunc->ImplicitArgs, NULL, 0, NULL); + GlobalVMStack.Call(ActionFunc, params, ActionFunc->ImplicitArgs, NULL, 0, NULL); } else { VMReturn ret; ret.PointerAt((void **)stateret); - stack.Call(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1, NULL); + GlobalVMStack.Call(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1, NULL); } ActionCycles.Unclock(); return true; diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 53405017a..53ae789c6 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -489,11 +489,10 @@ void cht_DoCheat (player_t *player, int cheat) if (gsp) { VMValue params[1] = { player->mo }; - VMFrameStack stack; VMReturn ret; int oldpieces = 1; ret.IntAt(&oldpieces); - stack.Call(gsp, params, 1, &ret, 1, nullptr); + GlobalVMStack.Call(gsp, params, 1, &ret, 1, nullptr); item = player->mo->FindInventory(PClass::FindActor(NAME_Sigil)); if (item != NULL) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index ba086da3a..6a7c9d10c 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6116,8 +6116,7 @@ static void SetMarineWeapon(AActor *marine, int weapon) if (smw) { VMValue params[2] = { marine, weapon }; - VMFrameStack stack; - stack.Call(smw, params, 2, nullptr, 0, nullptr); + GlobalVMStack.Call(smw, params, 2, nullptr, 0, nullptr); } } @@ -6128,8 +6127,7 @@ static void SetMarineSprite(AActor *marine, PClassActor *source) if (sms) { VMValue params[2] = { marine, source }; - VMFrameStack stack; - stack.Call(sms, params, 2, nullptr, 0, nullptr); + GlobalVMStack.Call(sms, params, 2, nullptr, 0, nullptr); } } diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index bc217f4ae..477ed37f2 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -148,7 +148,6 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState *state) state->ActionFunc = nullptr; } - VMFrameStack stack; PPrototype *proto = state->ActionFunc->Proto; VMReturn *wantret; FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON }; @@ -184,7 +183,7 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState *state) numret = 2; } } - stack.Call(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret); + GlobalVMStack.Call(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret); // As long as even one state succeeds, the whole chain succeeds unless aborted below. // A state that wants to jump does not count as "succeeded". if (nextstate == NULL) @@ -3802,8 +3801,6 @@ static void CheckStopped(AActor *self) // //=========================================================================== -DECLARE_ACTION(A_RestoreSpecialPosition) - enum RS_Flags { RSF_FOG=1, @@ -3822,7 +3819,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Respawn) self->flags |= MF_SOLID; self->Height = self->GetDefault()->Height; self->radius = self->GetDefault()->radius; - CALL_ACTION(A_RestoreSpecialPosition, self); + self->RestoreSpecialPosition(); if (flags & RSF_TELEFRAG) { diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 29128c8b7..751f92a30 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2285,12 +2285,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_Wander) return 0; } -// [MC] I had to move this out from within A_Wander in order to allow flags to -// pass into it. That meant replacing the CALL_ACTION(A_Wander) functions with -// just straight up defining A_Wander in order to compile. Looking around though, -// actors from the games themselves just do a straight A_Chase call itself so -// I saw no harm in it. - void A_Wander(AActor *self, int flags) { // [RH] Strife probably clears this flag somewhere, but I couldn't find where. @@ -2403,7 +2397,7 @@ nosee: //============================================================================= #define CLASS_BOSS_STRAFE_RANGE 64*10 -void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove, int flags) +void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove, int flags) { if (actor->flags5 & MF5_INCONVERSATION) @@ -2533,7 +2527,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele { if (actor->flags & MF_FRIENDLY) { - //CALL_ACTION(A_Look, actor); + //A_Look(actor); if (actor->target == NULL) { if (!dontmove) A_Wander(actor); @@ -2931,12 +2925,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_Chase) if ((flags & CHF_RESURRECT) && P_CheckForResurrection(self, false)) return 0; - A_DoChase(stack, self, !!(flags&CHF_FASTCHASE), melee, missile, !(flags&CHF_NOPLAYACTIVE), + A_DoChase(self, !!(flags&CHF_FASTCHASE), melee, missile, !(flags&CHF_NOPLAYACTIVE), !!(flags&CHF_NIGHTMAREFAST), !!(flags&CHF_DONTMOVE), flags); } else // this is the old default A_Chase { - A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, flags); + A_DoChase(self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, flags); } return 0; } @@ -2944,7 +2938,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Chase) DEFINE_ACTION_FUNCTION(AActor, A_FastChase) { PARAM_SELF_PROLOGUE(AActor); - A_DoChase(stack, self, true, self->MeleeState, self->MissileState, true, true, false, 0); + A_DoChase(self, true, self->MeleeState, self->MissileState, true, true, false, 0); return 0; } @@ -2953,7 +2947,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_VileChase) PARAM_SELF_PROLOGUE(AActor); if (!P_CheckForResurrection(self, true)) { - A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0); + A_DoChase(self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0); } return 0; } @@ -2967,16 +2961,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_ExtChase) PARAM_BOOL_DEF (nightmarefast); // Now that A_Chase can handle state label parameters, this function has become rather useless... - A_DoChase(stack, self, false, + A_DoChase(self, false, domelee ? self->MeleeState : NULL, domissile ? self->MissileState : NULL, playactive, nightmarefast, false, 0); return 0; } // for internal use -void A_Chase(VMFrameStack *stack, AActor *self) +void A_Chase(AActor *self) { - A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0); + A_DoChase(self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false, 0); } //============================================================================= diff --git a/src/p_enemy.h b/src/p_enemy.h index a9aa40dc2..a0e829c71 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -60,18 +60,10 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params); void A_Weave(AActor *self, int xyspeed, int zspeed, double xydist, double zdist); void A_Unblock(AActor *self, bool drop); -DECLARE_ACTION(A_Look) -DECLARE_ACTION(A_BossDeath) -DECLARE_ACTION(A_Pain) -DECLARE_ACTION(A_MonsterRail) -DECLARE_ACTION(A_NoBlocking) -DECLARE_ACTION(A_Scream) -DECLARE_ACTION(A_FreezeDeath) -DECLARE_ACTION(A_FreezeDeathChunks) void A_BossDeath(AActor *self); void A_Wander(AActor *self, int flags = 0); -void A_Chase(VMFrameStack *stack, AActor *self); +void A_Chase(AActor *self); void A_FaceTarget(AActor *actor); void A_Face(AActor *self, AActor *other, DAngle max_turn = 0., DAngle max_pitch = 270., DAngle ang_offset = 0., DAngle pitch_offset = 0., int flags = 0, double z_add = 0); diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index eae7edb00..e6729096c 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -777,8 +777,7 @@ void AActor::CallDie(AActor *source, AActor *inflictor, int dmgflags) IFVIRTUAL(AActor, Die) { VMValue params[4] = { (DObject*)this, source, inflictor, dmgflags }; - VMFrameStack stack; - stack.Call(func, params, 4, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 4, nullptr, 0, nullptr); } else return Die(source, inflictor, dmgflags); } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 572c7656f..f1f33425a 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1494,8 +1494,7 @@ void AActor::CallTouch(AActor *toucher) IFVIRTUAL(AActor, Touch) { VMValue params[2] = { (DObject*)this, toucher }; - VMFrameStack stack; - stack.Call(func, params, 2, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr); } else Touch(toucher); } @@ -3360,7 +3359,6 @@ int AActor::GetMissileDamage (int mask, int add) assert(false && "No damage function found"); return 0; } - VMFrameStack stack; VMValue param = this; VMReturn result; @@ -3368,7 +3366,7 @@ int AActor::GetMissileDamage (int mask, int add) result.IntAt(&amount); - if (stack.Call(DamageFunc, ¶m, 1, &result, 1) < 1) + if (GlobalVMStack.Call(DamageFunc, ¶m, 1, &result, 1) < 1) { // No results return 0; } @@ -3431,10 +3429,9 @@ bool AActor::CallSlam(AActor *thing) { VMValue params[2] = { (DObject*)this, thing }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); return !!retval; } @@ -3451,9 +3448,8 @@ int AActor::SpecialMissileHit (AActor *victim) VMValue params[2] = { (DObject*)this, victim }; VMReturn ret; int retval; - VMFrameStack stack; ret.IntAt(&retval); - stack.Call(func, params, 2, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); return retval; } else return -1; @@ -4777,8 +4773,7 @@ void AActor::CallBeginPlay() { // Without the type cast this picks the 'void *' assignment... VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } else BeginPlay(); } @@ -4859,8 +4854,7 @@ void AActor::CallActivate(AActor *activator) { // Without the type cast this picks the 'void *' assignment... VMValue params[2] = { (DObject*)this, (DObject*)activator }; - VMFrameStack stack; - stack.Call(func, params, 2, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr); } else Activate(activator); } @@ -4906,8 +4900,7 @@ void AActor::CallDeactivate(AActor *activator) { // Without the type cast this picks the 'void *' assignment... VMValue params[2] = { (DObject*)this, (DObject*)activator }; - VMFrameStack stack; - stack.Call(func, params, 2, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr); } else Deactivate(activator); } @@ -7076,10 +7069,9 @@ int AActor::CallDoSpecialDamage(AActor *target, int damage, FName damagetype) // Without the type cast this picks the 'void *' assignment... VMValue params[4] = { (DObject*)this, (DObject*)target, damage, damagetype.GetIndex() }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 4, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 4, &ret, 1, nullptr); return retval; } else return DoSpecialDamage(target, damage, damagetype); @@ -7142,10 +7134,9 @@ int AActor::CallTakeSpecialDamage(AActor *inflictor, AActor *source, int damage, { VMValue params[5] = { (DObject*)this, inflictor, source, damage, damagetype.GetIndex() }; VMReturn ret; - VMFrameStack stack; int retval; ret.IntAt(&retval); - stack.Call(func, params, 5, &ret, 1, nullptr); + GlobalVMStack.Call(func, params, 5, &ret, 1, nullptr); return retval; } else return TakeSpecialDamage(inflictor, source, damage, damagetype); @@ -7468,6 +7459,70 @@ void AActor::SetTranslation(FName trname) // silently ignore if the name does not exist, this would create some insane message spam otherwise. } +//--------------------------------------------------------------------------- +// +// PROP A_RestoreSpecialPosition +// +//--------------------------------------------------------------------------- +static FRandom pr_restore("RestorePos"); + +void AActor::RestoreSpecialPosition() +{ + // Move item back to its original location + DVector2 sp = SpawnPoint; + + UnlinkFromWorld(); + SetXY(sp); + LinkToWorld(true); + SetZ(Sector->floorplane.ZatPoint(sp)); + P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS | FFCF_NOPORTALS); // no portal checks here so that things get spawned in this sector. + + if (flags & MF_SPAWNCEILING) + { + SetZ(ceilingz - Height - SpawnPoint.Z); + } + else if (flags2 & MF2_SPAWNFLOAT) + { + double space = ceilingz - Height - floorz; + if (space > 48) + { + space -= 40; + SetZ((space * pr_restore()) / 256. + floorz + 40); + } + else + { + SetZ(floorz); + } + } + else + { + SetZ(SpawnPoint.Z + floorz); + } + // Redo floor/ceiling check, in case of 3D floors and portals + P_FindFloorCeiling(this, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); + if (Z() < floorz) + { // Do not reappear under the floor, even if that's where we were for the + // initial spawn. + SetZ(floorz); + } + if ((flags & MF_SOLID) && (Top() > ceilingz)) + { // Do the same for the ceiling. + SetZ(ceilingz - Height); + } + // Do not interpolate from the position the actor was at when it was + // picked up, in case that is different from where it is now. + ClearInterpolation(); +} + +DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) +{ + PARAM_SELF_PROLOGUE(AActor); + self->RestoreSpecialPosition(); + return 0; +} + + + class DActorIterator : public DObject, public NActorIterator { diff --git a/src/p_user.cpp b/src/p_user.cpp index 11857631a..74b07e0ca 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1305,8 +1305,7 @@ void APlayerPawn::PlayIdle () IFVIRTUAL(APlayerPawn, PlayIdle) { VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } } @@ -1315,8 +1314,7 @@ void APlayerPawn::PlayRunning () IFVIRTUAL(APlayerPawn, PlayRunning) { VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } } @@ -1325,8 +1323,7 @@ void APlayerPawn::PlayAttacking () IFVIRTUAL(APlayerPawn, PlayAttacking) { VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } } @@ -1335,8 +1332,7 @@ void APlayerPawn::PlayAttacking2 () IFVIRTUAL(APlayerPawn, PlayAttacking2) { VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } } @@ -1426,8 +1422,7 @@ void APlayerPawn::MorphPlayerThink () IFVIRTUAL(APlayerPawn, MorphPlayerThink) { VMValue params[1] = { (DObject*)this }; - VMFrameStack stack; - stack.Call(func, params, 1, nullptr, 0, nullptr); + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } } diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index eaeca6e9d..28b20e289 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -4228,7 +4228,7 @@ PPrototype *FxTypeCheck::ReturnProto() // //========================================================================== -int BuiltinTypeCheck(VMFrameStack *stack, VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) +int BuiltinTypeCheck(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) { assert(numparam == 2); PARAM_POINTER_AT(0, obj, DObject); @@ -5030,7 +5030,7 @@ FxExpression *FxRandom::Resolve(FCompileContext &ctx) // //========================================================================== -int BuiltinRandom(VMFrameStack *stack, VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) +int BuiltinRandom(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) { assert(numparam >= 1 && numparam <= 3); FRandom *rng = reinterpret_cast(param[0].a); @@ -5284,7 +5284,7 @@ FxFRandom::FxFRandom(FRandom *r, FxExpression *mi, FxExpression *ma, const FScri // //========================================================================== -int BuiltinFRandom(VMFrameStack *stack, VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) +int BuiltinFRandom(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) { assert(numparam == 1 || numparam == 3); FRandom *rng = reinterpret_cast(param[0].a); @@ -7558,7 +7558,7 @@ FxExpression *FxActionSpecialCall::Resolve(FCompileContext& ctx) // //========================================================================== -int BuiltinCallLineSpecial(VMFrameStack *stack, VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) +int BuiltinCallLineSpecial(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) { assert(numparam > 2 && numparam < 8); assert(param[0].Type == REGT_INT); @@ -9518,7 +9518,7 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx) // //========================================================================== -int BuiltinNameToClass(VMFrameStack *stack, VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) +int BuiltinNameToClass(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) { assert(numparam == 2); assert(numret == 1); @@ -9650,7 +9650,7 @@ FxExpression *FxClassPtrCast::Resolve(FCompileContext &ctx) // //========================================================================== -int BuiltinClassCast(VMFrameStack *stack, VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) +int BuiltinClassCast(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret) { PARAM_PROLOGUE; PARAM_CLASS(from, DObject); diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index fdee430e1..9bd0a4bc9 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -867,7 +867,7 @@ class VMNativeFunction : public VMFunction { DECLARE_CLASS(VMNativeFunction, VMFunction); public: - typedef int (*NativeCallType)(VMFrameStack *stack, VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret); + typedef int (*NativeCallType)(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret); VMNativeFunction() : NativeCall(NULL) { Native = true; } VMNativeFunction(NativeCallType call) : NativeCall(call) { Native = true; } @@ -930,6 +930,9 @@ enum EVMEngine VMEngine_Checked }; +extern thread_local VMFrameStack GlobalVMStack; + + void VMSelectEngine(EVMEngine engine); extern int (*VMExec)(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret); void VMFillParams(VMValue *params, VMFrame *callee, int numparam); @@ -938,8 +941,8 @@ void VMDumpConstants(FILE *out, const VMScriptFunction *func); void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction *func); // Use this in the prototype for a native function. -#define VM_ARGS VMFrameStack *stack, VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret -#define VM_ARGS_NAMES stack, param, defaultparam, numparam, ret, numret +#define VM_ARGS VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret +#define VM_ARGS_NAMES param, defaultparam, numparam, ret, numret // Use these to collect the parameters in a native function. // variable name at position

@@ -1012,7 +1015,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_OBJECT_DEF(x,type) ++paramnum; PARAM_OBJECT_DEF_AT(paramnum,x,type) #define PARAM_CLASS_DEF(x,base) ++paramnum; PARAM_CLASS_DEF_AT(paramnum,x,base) -typedef int(*actionf_p)(VMFrameStack *stack, VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret);/*(VM_ARGS)*/ +typedef int(*actionf_p)(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret);/*(VM_ARGS)*/ struct FieldDesc { @@ -1048,7 +1051,6 @@ struct AFuncDesc // Macros to handle action functions. These are here so that I don't have to // change every single use in case the parameters change. -#define DECLARE_ACTION(name) extern VMNativeFunction *AActor_##name##_VMPtr; #define DEFINE_ACTION_FUNCTION(cls, name) \ static int AF_##cls##_##name(VM_ARGS); \ @@ -1090,8 +1092,6 @@ struct AFuncDesc MSVC_FSEG FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr GCC_FSEG = &VMField_##cls##_##scriptname; class AActor; -void CallAction(VMFrameStack *stack, VMFunction *vmfunc, AActor *self); -#define CALL_ACTION(name, self) CallAction(stack, AActor_##name##_VMPtr, self); #define ACTION_RETURN_STATE(v) do { FState *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state, ATAG_STATE); return 1; } return 0; } while(0) diff --git a/src/scripting/vm/vmexec.cpp b/src/scripting/vm/vmexec.cpp index 750c384e0..f51038f36 100644 --- a/src/scripting/vm/vmexec.cpp +++ b/src/scripting/vm/vmexec.cpp @@ -146,6 +146,12 @@ VMExec_Checked::Exec #endif ; +// Note: If the VM is being used in multiple threads, this should be declared as thread_local. +// ZDoom doesn't need this at the moment so this is disabled. + +thread_local VMFrameStack GlobalVMStack; + + //=========================================================================== // // VMSelectEngine diff --git a/src/scripting/vm/vmframe.cpp b/src/scripting/vm/vmframe.cpp index 428266d0f..d3ce5d5f9 100644 --- a/src/scripting/vm/vmframe.cpp +++ b/src/scripting/vm/vmframe.cpp @@ -422,12 +422,13 @@ VMFrame *VMFrameStack::PopFrame() int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults, VMException **trap) { + assert(this == VMGlobalStack); // why would anyone even want to create a local stack? bool allocated = false; try { if (func->Native) { - return static_cast(func)->NativeCall(this, params, func->DefaultArgs, numparams, results, numresults); + return static_cast(func)->NativeCall(params, func->DefaultArgs, numparams, results, numresults); } else { @@ -503,11 +504,3 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur throw; } } - -class AActor; -void CallAction(VMFrameStack *stack, VMFunction *vmfunc, AActor *self) -{ - // Without the type cast this picks the 'void *' assignment... - VMValue params[3] = { (DObject*)self, (DObject*)self, VMValue(nullptr, ATAG_GENERIC) }; - stack->Call(vmfunc, params, vmfunc->ImplicitArgs, nullptr, 0, nullptr); -} diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index ae666a2f7..2b86e58e1 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -2362,7 +2362,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool { if (vindex != -1) { - Error(p, "Function %s attempts to override parent function without 'override' qualifier", FName(f->Name).GetChars()); + Error(f, "Function %s attempts to override parent function without 'override' qualifier", FName(f->Name).GetChars()); } sym->Variants[0].Implementation->VirtualIndex = clstype->Virtuals.Push(sym->Variants[0].Implementation); } @@ -3267,3 +3267,7 @@ FArgumentList &ZCCCompiler::ConvertNodeList(FArgumentList &args, ZCC_TreeNode *h } return args; } + +void func() +{ +} \ No newline at end of file diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index abcd58b50..bd00ffc98 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -666,7 +666,11 @@ class Actor : Thinker native native void A_FastChase(); native void A_FreezeDeath(); native void A_FreezeDeathChunks(); - native void A_GenericFreezeDeath(); + void A_GenericFreezeDeath() + { + A_SetTranslation('Ice'); + A_FreezeDeath(); + } native void A_PlayerScream(); native void A_SkullPop(class skulltype = "BloodySkull"); native void A_CheckPlayerDone();