- added a direct native function for NextHighestCeilingAt to test multiple return values.

This commit is contained in:
Christoph Oelckers 2018-11-28 21:40:25 +01:00
parent 5ae456d059
commit d3ff657231
7 changed files with 21 additions and 39 deletions

View file

@ -4704,7 +4704,7 @@ bool DLevelScript::DoCheckActorTexture(int tid, AActor *activator, int string, b
}
else
{
actor->Sector->NextHighestCeilingAt(actor->X(), actor->Y(), actor->Z(), actor->Top(), 0, &resultsec, &resffloor);
NextHighestCeilingAt(actor->Sector, actor->X(), actor->Y(), actor->Z(), actor->Top(), 0, &resultsec, &resffloor);
secpic = resffloor ? *resffloor->bottom.texture : resultsec->planes[sector_t::ceiling].Texture;
}
return tex == TexMan[secpic];

View file

@ -582,7 +582,7 @@ DEFINE_ACTION_FUNCTION(AActor, GetZAt)
}
else
{ // [MC] Handle strict 3D floors and portal toggling via the flags passed to it.
z = sec->NextHighestCeilingAt(pos.X, pos.Y, mobj->Z(), mobj->Top(), pflags);
z = NextHighestCeilingAt(sec, pos.X, pos.Y, mobj->Z(), mobj->Top(), pflags);
}
}
else

View file

@ -322,7 +322,7 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags)
sector_t *sec = (!(flags & FFCF_SAMESECTOR) || tmf.thing->Sector == NULL)? P_PointInSector(tmf.pos) : tmf.sector;
F3DFloor *ffc, *fff;
tmf.ceilingz = sec->NextHighestCeilingAt(tmf.pos.X, tmf.pos.Y, tmf.pos.Z, tmf.pos.Z + tmf.thing->Height, flags, &tmf.ceilingsector, &ffc);
tmf.ceilingz = NextHighestCeilingAt(sec, tmf.pos.X, tmf.pos.Y, tmf.pos.Z, tmf.pos.Z + tmf.thing->Height, flags, &tmf.ceilingsector, &ffc);
tmf.floorz = tmf.dropoffz = sec->NextLowestFloorAt(tmf.pos.X, tmf.pos.Y, tmf.pos.Z, flags, tmf.thing->MaxStepHeight, &tmf.floorsector, &fff);
if (fff)

View file

@ -976,9 +976,8 @@ double sector_t::LowestFloorAt(const DVector2 &p, sector_t **resultsec)
//
//=====================================================================================
double sector_t::NextHighestCeilingAt(double x, double y, double bottomz, double topz, int flags, sector_t **resultsec, F3DFloor **resultffloor)
double NextHighestCeilingAt(sector_t *sec, double x, double y, double bottomz, double topz, int flags, sector_t **resultsec, F3DFloor **resultffloor)
{
sector_t *sec = this;
double planeheight = -FLT_MAX;
while (true)
@ -1003,7 +1002,7 @@ double sector_t::NextHighestCeilingAt(double x, double y, double bottomz, double
return ff_bottom;
}
}
if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(ceiling) || planeheight >= sec->GetPortalPlaneZ(ceiling))
if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(sector_t::ceiling) || planeheight >= sec->GetPortalPlaneZ(sector_t::ceiling))
{ // Use sector's ceiling
if (resultffloor) *resultffloor = NULL;
if (resultsec) *resultsec = sec;
@ -1011,10 +1010,10 @@ double sector_t::NextHighestCeilingAt(double x, double y, double bottomz, double
}
else
{
DVector2 pos = sec->GetPortalDisplacement(ceiling);
DVector2 pos = sec->GetPortalDisplacement(sector_t::ceiling);
x += pos.X;
y += pos.Y;
planeheight = sec->GetPortalPlaneZ(ceiling);
planeheight = sec->GetPortalPlaneZ(sector_t::ceiling);
sec = P_PointInSector(x, y);
}
}

View file

@ -973,7 +973,6 @@ public:
return floorplane.Normal() == -ceilingplane.Normal() && floorplane.D == -ceilingplane.D;
}
double NextHighestCeilingAt(double x, double y, double bottomz, double topz, int flags = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL);
double NextLowestFloorAt(double x, double y, double z, int flags = 0, double steph = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL);
// Member variables
@ -1611,6 +1610,8 @@ double FindShortestUpperAround(sector_t *sector); // jff 2/04/98
sector_t *FindModelFloorSector(sector_t *sec, double floordestheight); // jff 2/04/98
sector_t *FindModelCeilingSector(sector_t *sec, double floordestheight); // jff 2/04/98
double NextHighestCeilingAt(sector_t *sec, double x, double y, double bottomz, double topz, int flags = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL);
// This setup is to allow the VM call directily into the implementation.
// With a member function this may be subject to OS implementation details, e.g. on Windows 32 bit members use a different calling convention than regular functions.
void RemoveForceField(sector_t *sec);

View file

@ -1081,12 +1081,14 @@ ExpEmit FunctionCallEmitter::EmitCall(VMFunctionBuilder *build, TArray<ExpEmit>
}
assert(returns.Size() < 2 || ReturnRegs != nullptr);
ExpEmit retreg;
for (unsigned i = 0; i < returns.Size(); i++)
{
ExpEmit reg(build, returns[i].first, returns[i].second);
build->Emit(OP_RESULT, 0, EncodeRegType(reg), reg.RegNum);
if (ReturnRegs) ReturnRegs->Push(reg);
else return reg;
else retreg = reg;
}
if (vm_jit) // The JIT compiler needs this, but the VM interpreter does not.
{
@ -1097,6 +1099,6 @@ ExpEmit FunctionCallEmitter::EmitCall(VMFunctionBuilder *build, TArray<ExpEmit>
reg.Free(build);
}
}
return ExpEmit();
return retreg;
}

View file

@ -160,7 +160,7 @@ DEFINE_ACTION_FUNCTION(_Sector, LowestFloorAt)
return numret;
}
DEFINE_ACTION_FUNCTION(_Sector, NextHighestCeilingAt)
DEFINE_ACTION_FUNCTION_NATIVE(_Sector, NextHighestCeilingAt, NextHighestCeilingAt)
{
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
PARAM_FLOAT(x);
@ -170,21 +170,11 @@ DEFINE_ACTION_FUNCTION(_Sector, NextHighestCeilingAt)
PARAM_INT(flags);
sector_t *resultsec;
F3DFloor *resultff;
double resultheight = self->NextHighestCeilingAt(x, y, bottomz, topz, flags, &resultsec, &resultff);
double resultheight = NextHighestCeilingAt(self, x, y, bottomz, topz, flags, &resultsec, &resultff);
if (numret > 2)
{
ret[2].SetPointer(resultff);
numret = 3;
}
if (numret > 1)
{
ret[1].SetPointer(resultsec);
}
if (numret > 0)
{
ret[0].SetFloat(resultheight);
}
if (numret > 2) ret[2].SetPointer(resultff);
if (numret > 1) ret[1].SetPointer(resultsec);
if (numret > 0) ret[0].SetFloat(resultheight);
return numret;
}
DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt)
@ -199,19 +189,9 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt)
F3DFloor *resultff;
double resultheight = self->NextLowestFloorAt(x, y, z, flags, steph, &resultsec, &resultff);
if (numret > 2)
{
ret[2].SetPointer(resultff);
numret = 3;
}
if (numret > 1)
{
ret[1].SetPointer(resultsec);
}
if (numret > 0)
{
ret[0].SetFloat(resultheight);
}
if (numret > 2) ret[2].SetPointer(resultff);
if (numret > 1) ret[1].SetPointer(resultsec);
if (numret > 0) ret[0].SetFloat(resultheight);
return numret;
}