mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-21 11:31:41 +00:00
- removed obsolete code from a_bossbrain.cpp.
- fixed: divisions wasted one register for each operation due to a double allocation. - changed math operations to use less registers. There was a well-intended change to allocate the destination first, but the better approach is to first allocate the operands and free then before allocating the destination register.
This commit is contained in:
parent
8305005125
commit
995f01f8aa
2 changed files with 6 additions and 156 deletions
|
@ -78,153 +78,3 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SpawnFly(AActor *self, PClassActor *spawntype, FSoundID sound)
|
|
||||||
{
|
|
||||||
AActor *newmobj;
|
|
||||||
AActor *fog;
|
|
||||||
AActor *eye = self->master; // The eye is the spawnshot's master, not the target!
|
|
||||||
AActor *targ = self->target; // Unlike other projectiles, the target is the intended destination.
|
|
||||||
int r;
|
|
||||||
|
|
||||||
// [GZ] Should be more viable than a countdown...
|
|
||||||
if (self->special2 != 0)
|
|
||||||
{
|
|
||||||
if (self->special2 > level.maptime)
|
|
||||||
return; // still flying
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (self->reactiontime == 0 || --self->reactiontime != 0)
|
|
||||||
return; // still flying
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spawntype != NULL)
|
|
||||||
{
|
|
||||||
fog = Spawn (spawntype, targ->Pos(), ALLOW_REPLACE);
|
|
||||||
if (fog != NULL) S_Sound (fog, CHAN_BODY, sound, 1, ATTN_NORM);
|
|
||||||
}
|
|
||||||
|
|
||||||
FName SpawnName;
|
|
||||||
|
|
||||||
DDropItem *di; // di will be our drop item list iterator
|
|
||||||
DDropItem *drop; // while drop stays as the reference point.
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
// First see if this cube has its own actor list
|
|
||||||
drop = self->GetDropItems();
|
|
||||||
|
|
||||||
// If not, then default back to its master's list
|
|
||||||
if (drop == NULL && eye != NULL)
|
|
||||||
drop = eye->GetDropItems();
|
|
||||||
|
|
||||||
if (drop != NULL)
|
|
||||||
{
|
|
||||||
for (di = drop; di != NULL; di = di->Next)
|
|
||||||
{
|
|
||||||
if (di->Name != NAME_None)
|
|
||||||
{
|
|
||||||
if (di->Amount < 0)
|
|
||||||
{
|
|
||||||
di->Amount = 1; // default value is -1, we need a positive value.
|
|
||||||
}
|
|
||||||
n += di->Amount; // this is how we can weight the list.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
di = drop;
|
|
||||||
n = pr_spawnfly(n);
|
|
||||||
while (n >= 0)
|
|
||||||
{
|
|
||||||
if (di->Name != NAME_None)
|
|
||||||
{
|
|
||||||
n -= di->Amount; // logically, none of the -1 values have survived by now.
|
|
||||||
}
|
|
||||||
if ((di->Next != NULL) && (n >= 0))
|
|
||||||
{
|
|
||||||
di = di->Next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
n = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SpawnName = di->Name;
|
|
||||||
}
|
|
||||||
if (SpawnName == NAME_None)
|
|
||||||
{
|
|
||||||
// Randomly select monster to spawn.
|
|
||||||
r = pr_spawnfly ();
|
|
||||||
|
|
||||||
// Probability distribution (kind of :),
|
|
||||||
// decreasing likelihood.
|
|
||||||
if (r < 50) SpawnName = "DoomImp";
|
|
||||||
else if (r < 90) SpawnName = "Demon";
|
|
||||||
else if (r < 120) SpawnName = "Spectre";
|
|
||||||
else if (r < 130) SpawnName = "PainElemental";
|
|
||||||
else if (r < 160) SpawnName = "Cacodemon";
|
|
||||||
else if (r < 162) SpawnName = "Archvile";
|
|
||||||
else if (r < 172) SpawnName = "Revenant";
|
|
||||||
else if (r < 192) SpawnName = "Arachnotron";
|
|
||||||
else if (r < 222) SpawnName = "Fatso";
|
|
||||||
else if (r < 246) SpawnName = "HellKnight";
|
|
||||||
else SpawnName = "BaronOfHell";
|
|
||||||
}
|
|
||||||
spawntype = PClass::FindActor(SpawnName);
|
|
||||||
if (spawntype != NULL)
|
|
||||||
{
|
|
||||||
newmobj = Spawn (spawntype, targ->Pos(), ALLOW_REPLACE);
|
|
||||||
if (newmobj != NULL)
|
|
||||||
{
|
|
||||||
// Make the new monster hate what the boss eye hates
|
|
||||||
if (eye != NULL)
|
|
||||||
{
|
|
||||||
newmobj->CopyFriendliness (eye, false);
|
|
||||||
}
|
|
||||||
// Make it act as if it was around when the player first made noise
|
|
||||||
// (if the player has made noise).
|
|
||||||
newmobj->LastHeard = newmobj->Sector->SoundTarget;
|
|
||||||
|
|
||||||
if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true, NULL))
|
|
||||||
{
|
|
||||||
newmobj->SetState (newmobj->SeeState);
|
|
||||||
}
|
|
||||||
if (!(newmobj->ObjectFlags & OF_EuthanizeMe))
|
|
||||||
{
|
|
||||||
// telefrag anything in this spot
|
|
||||||
P_TeleportMove (newmobj, newmobj->Pos(), true);
|
|
||||||
}
|
|
||||||
newmobj->flags4 |= MF4_BOSSSPAWNED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove self (i.e., cube).
|
|
||||||
self->Destroy ();
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnFly)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
PARAM_CLASS_DEF(spawntype, AActor);
|
|
||||||
|
|
||||||
FSoundID sound;
|
|
||||||
|
|
||||||
if (spawntype != NULL)
|
|
||||||
{
|
|
||||||
sound = GetDefaultByType(spawntype)->SeeSound;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spawntype = PClass::FindActor("SpawnFire");
|
|
||||||
sound = "brain/spawn";
|
|
||||||
}
|
|
||||||
SpawnFly(self, spawntype, sound);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// travelling cube sound
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_SpawnSound)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
S_Sound (self, CHAN_BODY, "brain/cube", 1, ATTN_IDLE);
|
|
||||||
SpawnFly(self, PClass::FindActor("SpawnFire"), "brain/spawn");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -2563,8 +2563,6 @@ FxExpression *FxAddSub::Resolve(FCompileContext& ctx)
|
||||||
ExpEmit FxAddSub::Emit(VMFunctionBuilder *build)
|
ExpEmit FxAddSub::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
assert(Operator == '+' || Operator == '-');
|
assert(Operator == '+' || Operator == '-');
|
||||||
// allocate the result first so that the operation does not leave gaps in the register set.
|
|
||||||
ExpEmit to(build, ValueType->GetRegType(), ValueType->GetRegCount());
|
|
||||||
ExpEmit op1 = left->Emit(build);
|
ExpEmit op1 = left->Emit(build);
|
||||||
ExpEmit op2 = right->Emit(build);
|
ExpEmit op2 = right->Emit(build);
|
||||||
if (Operator == '+')
|
if (Operator == '+')
|
||||||
|
@ -2577,6 +2575,7 @@ ExpEmit FxAddSub::Emit(VMFunctionBuilder *build)
|
||||||
assert(!op1.Konst);
|
assert(!op1.Konst);
|
||||||
op1.Free(build);
|
op1.Free(build);
|
||||||
op2.Free(build);
|
op2.Free(build);
|
||||||
|
ExpEmit to(build, ValueType->GetRegType(), ValueType->GetRegCount());
|
||||||
if (IsVector())
|
if (IsVector())
|
||||||
{
|
{
|
||||||
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
|
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
|
||||||
|
@ -2608,6 +2607,7 @@ ExpEmit FxAddSub::Emit(VMFunctionBuilder *build)
|
||||||
assert(!op1.Konst || !op2.Konst);
|
assert(!op1.Konst || !op2.Konst);
|
||||||
op1.Free(build);
|
op1.Free(build);
|
||||||
op2.Free(build);
|
op2.Free(build);
|
||||||
|
ExpEmit to(build, ValueType->GetRegType(), ValueType->GetRegCount());
|
||||||
if (IsVector())
|
if (IsVector())
|
||||||
{
|
{
|
||||||
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
|
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
|
||||||
|
@ -2720,7 +2720,6 @@ FxExpression *FxMulDiv::Resolve(FCompileContext& ctx)
|
||||||
ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
|
ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
// allocate the result first so that the operation does not leave gaps in the register set.
|
// allocate the result first so that the operation does not leave gaps in the register set.
|
||||||
ExpEmit to(build, ValueType->GetRegType(), ValueType->GetRegCount());
|
|
||||||
ExpEmit op1 = left->Emit(build);
|
ExpEmit op1 = left->Emit(build);
|
||||||
ExpEmit op2 = right->Emit(build);
|
ExpEmit op2 = right->Emit(build);
|
||||||
|
|
||||||
|
@ -2740,9 +2739,10 @@ ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
op = Operator == '*' ? (ValueType == TypeVector2 ? OP_MULVF2_RR : OP_MULVF3_RR) : (ValueType == TypeVector2 ? OP_DIVVF2_RR : OP_DIVVF3_RR);
|
op = Operator == '*' ? (ValueType == TypeVector2 ? OP_MULVF2_RR : OP_MULVF3_RR) : (ValueType == TypeVector2 ? OP_DIVVF2_RR : OP_DIVVF3_RR);
|
||||||
}
|
}
|
||||||
build->Emit(op, to.RegNum, op1.RegNum, op2.RegNum);
|
|
||||||
op1.Free(build);
|
op1.Free(build);
|
||||||
op2.Free(build);
|
op2.Free(build);
|
||||||
|
ExpEmit to(build, ValueType->GetRegType(), ValueType->GetRegCount());
|
||||||
|
build->Emit(op, to.RegNum, op1.RegNum, op2.RegNum);
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2756,6 +2756,7 @@ ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
|
||||||
assert(!op1.Konst);
|
assert(!op1.Konst);
|
||||||
op1.Free(build);
|
op1.Free(build);
|
||||||
op2.Free(build);
|
op2.Free(build);
|
||||||
|
ExpEmit to(build, ValueType->GetRegType());
|
||||||
if (ValueType->GetRegType() == REGT_FLOAT)
|
if (ValueType->GetRegType() == REGT_FLOAT)
|
||||||
{
|
{
|
||||||
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
|
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
|
||||||
|
@ -2777,10 +2778,10 @@ ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
|
||||||
assert(Operator == '%' || Operator == '/');
|
assert(Operator == '%' || Operator == '/');
|
||||||
op1.Free(build);
|
op1.Free(build);
|
||||||
op2.Free(build);
|
op2.Free(build);
|
||||||
|
ExpEmit to(build, ValueType->GetRegType());
|
||||||
if (ValueType->GetRegType() == REGT_FLOAT)
|
if (ValueType->GetRegType() == REGT_FLOAT)
|
||||||
{
|
{
|
||||||
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
|
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
|
||||||
ExpEmit to(build, REGT_FLOAT);
|
|
||||||
build->Emit(Operator == '/' ? (op1.Konst ? OP_DIVF_KR : op2.Konst ? OP_DIVF_RK : OP_DIVF_RR)
|
build->Emit(Operator == '/' ? (op1.Konst ? OP_DIVF_KR : op2.Konst ? OP_DIVF_RK : OP_DIVF_RR)
|
||||||
: (op1.Konst ? OP_MODF_KR : op2.Konst ? OP_MODF_RK : OP_MODF_RR),
|
: (op1.Konst ? OP_MODF_KR : op2.Konst ? OP_MODF_RK : OP_MODF_RR),
|
||||||
to.RegNum, op1.RegNum, op2.RegNum);
|
to.RegNum, op1.RegNum, op2.RegNum);
|
||||||
|
@ -2790,7 +2791,6 @@ ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
assert(ValueType->GetRegType() == REGT_INT);
|
assert(ValueType->GetRegType() == REGT_INT);
|
||||||
assert(op1.RegType == REGT_INT && op2.RegType == REGT_INT);
|
assert(op1.RegType == REGT_INT && op2.RegType == REGT_INT);
|
||||||
ExpEmit to(build, REGT_INT);
|
|
||||||
build->Emit(Operator == '/' ? (op1.Konst ? OP_DIV_KR : op2.Konst ? OP_DIV_RK : OP_DIV_RR)
|
build->Emit(Operator == '/' ? (op1.Konst ? OP_DIV_KR : op2.Konst ? OP_DIV_RK : OP_DIV_RR)
|
||||||
: (op1.Konst ? OP_MOD_KR : op2.Konst ? OP_MOD_RK : OP_MOD_RR),
|
: (op1.Konst ? OP_MOD_KR : op2.Konst ? OP_MOD_RK : OP_MOD_RR),
|
||||||
to.RegNum, op1.RegNum, op2.RegNum);
|
to.RegNum, op1.RegNum, op2.RegNum);
|
||||||
|
|
Loading…
Reference in a new issue