mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-18 15:42:34 +00:00
- allow the VM to run on one global stack per thread.
It is utterly pointless to require every function that wants to make a VM call to allocate a new stack first. The allocation overhead doubles the time to set up the call. With one stack, previously allocated memory can be reused. The only important thing is, if this ever gets used in a multithreaded environment to have the stack being declared as thread_local, although for ZDoom this is of no consequence. - eliminated all cases where native code was calling other native code through the VM interface. After scriptifying the game code, only 5 places were left which were quickly eliminated. This was mostly to ensure that the native VM function parameters do not need to be propagated further than absolutely necessary.
This commit is contained in:
parent
47884f8a71
commit
86544086df
23 changed files with 176 additions and 229 deletions
|
@ -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.
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4228,7 +4228,7 @@ PPrototype *FxTypeCheck::ReturnProto()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int BuiltinTypeCheck(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||
int BuiltinTypeCheck(VMValue *param, TArray<VMValue> &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<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||
int BuiltinRandom(VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||
{
|
||||
assert(numparam >= 1 && numparam <= 3);
|
||||
FRandom *rng = reinterpret_cast<FRandom *>(param[0].a);
|
||||
|
@ -5284,7 +5284,7 @@ FxFRandom::FxFRandom(FRandom *r, FxExpression *mi, FxExpression *ma, const FScri
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int BuiltinFRandom(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||
int BuiltinFRandom(VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||
{
|
||||
assert(numparam == 1 || numparam == 3);
|
||||
FRandom *rng = reinterpret_cast<FRandom *>(param[0].a);
|
||||
|
@ -7558,7 +7558,7 @@ FxExpression *FxActionSpecialCall::Resolve(FCompileContext& ctx)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int BuiltinCallLineSpecial(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||
int BuiltinCallLineSpecial(VMValue *param, TArray<VMValue> &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<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||
int BuiltinNameToClass(VMValue *param, TArray<VMValue> &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<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||
int BuiltinClassCast(VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_CLASS(from, DObject);
|
||||
|
|
|
@ -867,7 +867,7 @@ class VMNativeFunction : public VMFunction
|
|||
{
|
||||
DECLARE_CLASS(VMNativeFunction, VMFunction);
|
||||
public:
|
||||
typedef int (*NativeCallType)(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret);
|
||||
typedef int (*NativeCallType)(VMValue *param, TArray<VMValue> &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<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret
|
||||
#define VM_ARGS_NAMES stack, param, defaultparam, numparam, ret, numret
|
||||
#define VM_ARGS VMValue *param, TArray<VMValue> &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 <x> at position <p>
|
||||
|
@ -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<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret);/*(VM_ARGS)*/
|
||||
typedef int(*actionf_p)(VMValue *param, TArray<VMValue> &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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<VMNativeFunction *>(func)->NativeCall(this, params, func->DefaultArgs, numparams, results, numresults);
|
||||
return static_cast<VMNativeFunction *>(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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
}
|
|
@ -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<PlayerChunk> skulltype = "BloodySkull");
|
||||
native void A_CheckPlayerDone();
|
||||
|
|
Loading…
Reference in a new issue