- 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 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; secpic = resffloor ? *resffloor->bottom.texture : resultsec->planes[sector_t::ceiling].Texture;
} }
return tex == TexMan[secpic]; return tex == TexMan[secpic];

View file

@ -582,7 +582,7 @@ DEFINE_ACTION_FUNCTION(AActor, GetZAt)
} }
else else
{ // [MC] Handle strict 3D floors and portal toggling via the flags passed to it. { // [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 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; sector_t *sec = (!(flags & FFCF_SAMESECTOR) || tmf.thing->Sector == NULL)? P_PointInSector(tmf.pos) : tmf.sector;
F3DFloor *ffc, *fff; 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); tmf.floorz = tmf.dropoffz = sec->NextLowestFloorAt(tmf.pos.X, tmf.pos.Y, tmf.pos.Z, flags, tmf.thing->MaxStepHeight, &tmf.floorsector, &fff);
if (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; double planeheight = -FLT_MAX;
while (true) while (true)
@ -1003,7 +1002,7 @@ double sector_t::NextHighestCeilingAt(double x, double y, double bottomz, double
return ff_bottom; 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 { // Use sector's ceiling
if (resultffloor) *resultffloor = NULL; if (resultffloor) *resultffloor = NULL;
if (resultsec) *resultsec = sec; if (resultsec) *resultsec = sec;
@ -1011,10 +1010,10 @@ double sector_t::NextHighestCeilingAt(double x, double y, double bottomz, double
} }
else else
{ {
DVector2 pos = sec->GetPortalDisplacement(ceiling); DVector2 pos = sec->GetPortalDisplacement(sector_t::ceiling);
x += pos.X; x += pos.X;
y += pos.Y; y += pos.Y;
planeheight = sec->GetPortalPlaneZ(ceiling); planeheight = sec->GetPortalPlaneZ(sector_t::ceiling);
sec = P_PointInSector(x, y); sec = P_PointInSector(x, y);
} }
} }

View file

@ -973,7 +973,6 @@ public:
return floorplane.Normal() == -ceilingplane.Normal() && floorplane.D == -ceilingplane.D; 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); double NextLowestFloorAt(double x, double y, double z, int flags = 0, double steph = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL);
// Member variables // 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 *FindModelFloorSector(sector_t *sec, double floordestheight); // jff 2/04/98
sector_t *FindModelCeilingSector(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. // 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. // 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); void RemoveForceField(sector_t *sec);

View file

@ -1081,12 +1081,14 @@ ExpEmit FunctionCallEmitter::EmitCall(VMFunctionBuilder *build, TArray<ExpEmit>
} }
assert(returns.Size() < 2 || ReturnRegs != nullptr); assert(returns.Size() < 2 || ReturnRegs != nullptr);
ExpEmit retreg;
for (unsigned i = 0; i < returns.Size(); i++) for (unsigned i = 0; i < returns.Size(); i++)
{ {
ExpEmit reg(build, returns[i].first, returns[i].second); ExpEmit reg(build, returns[i].first, returns[i].second);
build->Emit(OP_RESULT, 0, EncodeRegType(reg), reg.RegNum); build->Emit(OP_RESULT, 0, EncodeRegType(reg), reg.RegNum);
if (ReturnRegs) ReturnRegs->Push(reg); 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. 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); reg.Free(build);
} }
} }
return ExpEmit(); return retreg;
} }

View file

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