diff --git a/src/actor.h b/src/actor.h index aa4b8cbff8..3f2577a592 100644 --- a/src/actor.h +++ b/src/actor.h @@ -561,11 +561,7 @@ public: int Amount; }; -fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); // since we cannot include p_local here... -angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); // same reason here with r_defs.h - -const double MinVel = 1. / 65536; -const double Z_Epsilon = 1. / 65536.; +const double MinVel = EQUAL_EPSILON; // Map Object definition. class AActor : public DThinker @@ -752,17 +748,6 @@ public: return BobSin(FloatBobPhase + level.maptime + ticfrac); } - - - fixed_t _f_GetBobOffset(fixed_t ticfrac=0) const - { - if (!(flags2 & MF2_FLOATBOB)) - { - return 0; - } - return finesine[MulScale22(((FloatBobPhase + level.maptime) << FRACBITS) + ticfrac, FINEANGLES) & FINEMASK] * 8; - } - // Enter the crash state void Crash(); @@ -850,8 +835,6 @@ public: return VecToAngle(otherpos - Pos().XY()); } - DAngle AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const = delete; - DAngle AngleTo(AActor *other, double oxofs, double oyofs, bool absolute = false) const { DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); @@ -906,21 +889,6 @@ public: } } - fixedvec3 Vec3Offset(fixed_t dx, fixed_t dy, fixed_t dz, bool absolute = false) - { - if (absolute) - { - fixedvec3 ret = { _f_X() + dx, _f_Y() + dy, _f_Z() + dz }; - return ret; - } - else - { - fixedvec2 op = P_GetOffsetPosition(_f_X(), _f_Y(), dx, dy); - fixedvec3 pos = { op.x, op.y, _f_Z() + dz }; - return pos; - } - } - DVector3 Vec3Offset(double dx, double dy, double dz, bool absolute = false) { if (absolute) @@ -959,22 +927,14 @@ public: void ClearInterpolation(); - void SetOrigin(const fixedvec3 & npos, bool moving) - { - SetOrigin(npos.x, npos.y, npos.z, moving); - } - void Move(const DVector3 &vel) { SetOrigin(Pos() + vel, true); } - void SetOrigin(double x, double y, double z, bool moving) - { - SetOrigin(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(z), moving); - } + virtual void SetOrigin(double x, double y, double z, bool moving); void SetOrigin(const DVector3 & npos, bool moving) { - SetOrigin(FLOAT2FIXED(npos.X), FLOAT2FIXED(npos.Y), FLOAT2FIXED(npos.Z), moving); + SetOrigin(npos.X, npos.Y, npos.Z, moving); } inline void SetFriendPlayer(player_t *player); @@ -1021,11 +981,6 @@ public: double floorz, ceilingz; // closest together of contacted secs double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors. - inline fixed_t _f_floorz() - { - return FLOAT2FIXED(floorz); - } - struct sector_t *floorsector; FTextureID floorpic; // contacted sec floorpic int floorterrain; @@ -1033,15 +988,6 @@ public: FTextureID ceilingpic; // contacted sec ceilingpic double radius, Height; // for movement checking - inline fixed_t _f_radius() const - { - return FLOAT2FIXED(radius); - } - inline fixed_t _f_height() const - { - return FLOAT2FIXED(Height); - } - double projectilepassheight; // height for clipping projectile movement against this actor SDWORD tics; // state tic counter @@ -1092,10 +1038,6 @@ public: TObjPtr tracer; // Thing being chased/attacked for tracers TObjPtr master; // Thing which spawned this one (prevents mutual attacks) double Floorclip; // value to use for floor clipping - fixed_t _f_floorclip() - { - return FLOAT2FIXED(Floorclip); - } int tid; // thing identifier int special; // special @@ -1222,7 +1164,6 @@ public: void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL); void UnlinkFromWorld (); void AdjustFloorClip (); - virtual void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false); bool InStateSequence(FState * newstate, FState * basestate); int GetTics(FState * newstate); bool SetState (FState *newstate, bool nofunction=false); @@ -1260,14 +1201,6 @@ public: { return FLOAT2FIXED(__Pos.Y); } - fixed_t _f_Z() const - { - return FLOAT2FIXED(__Pos.Z); - } - fixedvec3 _f_Pos() const - { - return{ _f_X(), _f_Y(), _f_Z() }; - } double X() const { @@ -1289,15 +1222,15 @@ public: // Comparing with floorz is ok because those values come from the same calculations. bool isAbove(double checkz) const { - return Z() > checkz + Z_Epsilon; + return Z() > checkz + EQUAL_EPSILON; } bool isBelow(double checkz) const { - return Z() < checkz - Z_Epsilon; + return Z() < checkz - EQUAL_EPSILON; } bool isAtZ(double checkz) const { - return fabs(Z() - checkz) < Z_Epsilon; + return fabs(Z() - checkz) < EQUAL_EPSILON; } DVector3 PosRelative(int grp) const; @@ -1307,18 +1240,14 @@ public: FVector3 SoundPos() const { + // the sound system switches y and z axes so this function must, too. // fixme: This still needs portal handling - return{ float(X()), float(Y()), float(Z()) }; + return{ float(X()), float(Z()), float(Y()) }; } DVector3 InterpolatedPosition(double ticFrac) const { return Prev + (ticFrac * (Pos() - Prev)); } - fixedvec3 PosPlusZ(fixed_t zadd) const - { - fixedvec3 ret = { _f_X(), _f_Y(), _f_Z() + zadd }; - return ret; - } DVector3 PosPlusZ(double zadd) const { return { X(), Y(), Z() + zadd }; @@ -1327,18 +1256,6 @@ public: { return{ X(), Y(), zadd }; } - fixed_t _f_Top() const - { - return _f_Z() + FLOAT2FIXED(Height); - } - void _f_SetZ(fixed_t newz, bool moving = true) - { - __Pos.Z = FIXED2DBL(newz); - } - void _f_AddZ(fixed_t newz, bool moving = true) - { - __Pos.Z += FIXED2DBL(newz); - } double Top() const { return Z() + Height; @@ -1363,11 +1280,6 @@ public: __Pos.X = FIXED2DBL(xx); __Pos.Y = FIXED2DBL(yy); } - void SetXY(const fixedvec2 &npos) - { - __Pos.X = FIXED2DBL(npos.x); - __Pos.Y = FIXED2DBL(npos.y); - } void SetXY(const DVector2 &npos) { __Pos.X = npos.X; @@ -1383,12 +1295,6 @@ public: { __Pos = { xx,yy,zz }; } - void SetXYZ(const fixedvec3 &npos) - { - __Pos.X = FIXED2DBL(npos.x); - __Pos.Y = FIXED2DBL(npos.y); - __Pos.Z = FIXED2DBL(npos.z); - } void SetXYZ(const DVector3 &npos) { __Pos = npos; @@ -1578,13 +1484,6 @@ template inline T *Spawn() // for inventory items we do not need coordi return static_cast(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), DVector3(0, 0, 0), NO_REPLACE)); } -inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle) -{ - fixedvec2 ret = { FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), - FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) }; - return ret; -} - void PrintMiscActorInfo(AActor * query); AActor *P_LinePickActor(AActor *t1, DAngle angle, double distance, DAngle pitch, ActorFlags actorMask, DWORD wallMask); diff --git a/src/b_func.cpp b/src/b_func.cpp index ca9c0d7b27..acd3077e6f 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -55,7 +55,7 @@ bool DBot::Reachable (AActor *rtarget) double dist; sector_t *s; - frac = in->Frac - 4 /MAX_TRAVERSE_DIST; + frac = in->frac - 4 /MAX_TRAVERSE_DIST; dist = frac * MAX_TRAVERSE_DIST; hitx = it.Trace().x + player->mo->Vel.X * frac; diff --git a/src/basictypes.h b/src/basictypes.h index e06e49494c..7816fa557d 100644 --- a/src/basictypes.h +++ b/src/basictypes.h @@ -66,89 +66,6 @@ union QWORD_UNION typedef SDWORD fixed_t; typedef DWORD dsfixed_t; // fixedpt used by span drawer -struct fixedvec2 -{ - fixed_t x, y; - - fixedvec2 &operator +=(const fixedvec2 &other) - { - x += other.x; - y += other.y; - return *this; - } -}; - -struct fixedvec3 -{ - fixed_t x, y, z; - - fixedvec3 &operator +=(const fixedvec3 &other) - { - x += other.x; - y += other.y; - z += other.z; - return *this; - } - - fixedvec3 &operator +=(const fixedvec2 &other) - { - x += other.x; - y += other.y; - return *this; - } - - fixedvec3 &operator -=(const fixedvec2 &other) - { - x -= other.x; - y -= other.y; - return *this; - } - - fixedvec3 &operator -=(const fixedvec3 &other) - { - x -= other.x; - y -= other.y; - z -= other.z; - return *this; - } - - operator fixedvec2() - { - return { x, y }; - } - -}; - -inline fixedvec2 operator +(const fixedvec2 &v1, const fixedvec2 &v2) -{ - return { v1.x + v2.x, v1.y + v2.y }; -} - -inline fixedvec2 operator -(const fixedvec2 &v1, const fixedvec2 &v2) -{ - return { v1.x - v2.x, v1.y - v2.y }; -} - -inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec3 &v2) -{ - return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; -} - -inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec2 &v2) -{ - return { v1.x + v2.x, v1.y + v2.y, v1.z }; -} - -inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec2 &v2) -{ - return{ v1.x - v2.x, v1.y - v2.y, v1.z }; -} - -inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec3 &v2) -{ - return{ v1.x - v2.x, v1.y - v2.y, v1.z - v2.z }; -} - #define FIXED_MAX (signed)(0x7fffffff) #define FIXED_MIN (signed)(0x80000000) diff --git a/src/doomdef.h b/src/doomdef.h index 89d7ba673b..56b69fe7c7 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -340,7 +340,7 @@ enum : unsigned int COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW. COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom. COMPATF2_SOUNDCUTOFF = 1 << 2, // Cut off sounds when an actor vanishes instead of making it owner-less - COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSide() + COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSideCompat() COMPATF2_MULTIEXIT = 1 << 4, // Level exit can be triggered multiple times (required by Daedalus's travel tubes, thanks to a faulty script) }; diff --git a/src/g_hexen/a_magestaff.cpp b/src/g_hexen/a_magestaff.cpp index 92724016cf..1bd20715dd 100644 --- a/src/g_hexen/a_magestaff.cpp +++ b/src/g_hexen/a_magestaff.cpp @@ -213,7 +213,7 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *) { if (link->Me != mo) { - if (P_PointOnDivlineSidePrecise(link->Me->X(), link->Me->Y(), &BlockCheckLine) == 0 && + if (P_PointOnDivlineSide(link->Me->X(), link->Me->Y(), &BlockCheckLine) == 0 && mo->IsOkayToAttack (link->Me)) { return link->Me; diff --git a/src/m_bbox.cpp b/src/m_bbox.cpp index be6721209f..143f54d47a 100644 --- a/src/m_bbox.cpp +++ b/src/m_bbox.cpp @@ -34,32 +34,17 @@ // //========================================================================== -void FBoundingBox::setBox(fixed_t x, fixed_t y, fixed_t radius) +void FBoundingBox::AddToBox (const DVector2 &pos) { - m_Box[BOXTOP] = (fixed_t)MIN((SQWORD)y + radius, FIXED_MAX); - m_Box[BOXLEFT] = (fixed_t)MAX((SQWORD)x - radius, FIXED_MIN); - m_Box[BOXRIGHT] = (fixed_t)MIN((SQWORD)x + radius, FIXED_MAX); - m_Box[BOXBOTTOM] = (fixed_t)MAX((SQWORD)y - radius, FIXED_MIN); -} + if (pos.X < m_Box[BOXLEFT]) + m_Box[BOXLEFT] = pos.X; + if (pos.X > m_Box[BOXRIGHT]) + m_Box[BOXRIGHT] = pos.X; - -//========================================================================== -// -// -// -//========================================================================== - -void FBoundingBox::AddToBox (fixed_t x, fixed_t y) -{ - if (x < m_Box[BOXLEFT]) - m_Box[BOXLEFT] = x; - if (x > m_Box[BOXRIGHT]) - m_Box[BOXRIGHT] = x; - - if (y < m_Box[BOXBOTTOM]) - m_Box[BOXBOTTOM] = y; - if (y > m_Box[BOXTOP]) - m_Box[BOXTOP] = y; + if (pos.Y < m_Box[BOXBOTTOM]) + m_Box[BOXBOTTOM] = pos.Y; + if (pos.Y > m_Box[BOXTOP]) + m_Box[BOXTOP] = pos.Y; } //========================================================================== @@ -78,8 +63,8 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const if (ld->Delta().X == 0) { // ST_VERTICAL - p1 = m_Box[BOXRIGHT] < ld->v1->fixX(); - p2 = m_Box[BOXLEFT] < ld->v1->fixX(); + p1 = m_Box[BOXRIGHT] < ld->v1->fX(); + p2 = m_Box[BOXLEFT] < ld->v1->fX(); if (ld->Delta().Y < 0) { p1 ^= 1; @@ -88,8 +73,8 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const } else if (ld->Delta().Y == 0) { // ST_HORIZONTAL: - p1 = m_Box[BOXTOP] > ld->v1->fixY(); - p2 = m_Box[BOXBOTTOM] > ld->v1->fixY(); + p1 = m_Box[BOXTOP] > ld->v1->fY(); + p2 = m_Box[BOXBOTTOM] > ld->v1->fY(); if (ld->Delta().X < 0) { p1 ^= 1; diff --git a/src/m_bbox.h b/src/m_bbox.h index fe73432da2..71728b8510 100644 --- a/src/m_bbox.h +++ b/src/m_bbox.h @@ -22,7 +22,8 @@ #ifndef __M_BBOX_H__ #define __M_BBOX_H__ -#include "doomtype.h" +#include +#include "vectors.h" #include "m_fixed.h" struct line_t; @@ -36,7 +37,7 @@ public: ClearBox(); } - FBoundingBox(fixed_t left, fixed_t bottom, fixed_t right, fixed_t top) + FBoundingBox(double left, double bottom, double right, double top) { m_Box[BOXTOP] = top; m_Box[BOXLEFT] = left; @@ -44,35 +45,24 @@ public: m_Box[BOXBOTTOM] = bottom; } - FBoundingBox(double left, double bottom, double right, double top) - { - m_Box[BOXTOP] = FLOAT2FIXED(top); - m_Box[BOXLEFT] = FLOAT2FIXED(left); - m_Box[BOXRIGHT] = FLOAT2FIXED(right); - m_Box[BOXBOTTOM] = FLOAT2FIXED(bottom); - } - - FBoundingBox(fixed_t x, fixed_t y, fixed_t radius) - { - setBox(x, y, radius); - } - FBoundingBox(double x, double y, double radius) { setBox(x, y, radius); } - void setBox(fixed_t x, fixed_t y, fixed_t radius); void setBox(double x, double y, double radius) { - setBox(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(radius)); + m_Box[BOXTOP] = y + radius; + m_Box[BOXLEFT] = x - radius; + m_Box[BOXRIGHT] = x + radius; + m_Box[BOXBOTTOM] = y - radius; } void ClearBox () { - m_Box[BOXTOP] = m_Box[BOXRIGHT] = FIXED_MIN; - m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FIXED_MAX; + m_Box[BOXTOP] = m_Box[BOXRIGHT] = -FLT_MAX; + m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FLT_MAX; } // Returns a bounding box that encloses both bounding boxes @@ -84,21 +74,21 @@ public: m_Box[BOXTOP] > box2.m_Box[BOXTOP] ? m_Box[BOXTOP] : box2.m_Box[BOXTOP]); } - void AddToBox (fixed_t x, fixed_t y); + void AddToBox(const DVector2 &pos); - inline fixed_t Top () const { return m_Box[BOXTOP]; } - inline fixed_t Bottom () const { return m_Box[BOXBOTTOM]; } - inline fixed_t Left () const { return m_Box[BOXLEFT]; } - inline fixed_t Right () const { return m_Box[BOXRIGHT]; } + inline double Top () const { return m_Box[BOXTOP]; } + inline double Bottom () const { return m_Box[BOXBOTTOM]; } + inline double Left () const { return m_Box[BOXLEFT]; } + inline double Right () const { return m_Box[BOXRIGHT]; } bool inRange(const line_t *ld) const; int BoxOnLineSide (const line_t *ld) const; - void Set(int index, fixed_t value) {m_Box[index] = value;} + void Set(int index, double value) {m_Box[index] = value;} protected: - fixed_t m_Box[4]; + double m_Box[4]; }; diff --git a/src/math/cmath.h b/src/math/cmath.h index 311555951c..9fd0b570d1 100644 --- a/src/math/cmath.h +++ b/src/math/cmath.h @@ -48,6 +48,7 @@ public: extern FFastTrig fasttrig; +// This must use xs_Float to guarantee proper integer wraparound. #define DEG2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x40000000/90.))) #define RAD2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x80000000/3.14159265358979323846))) diff --git a/src/p_effect.cpp b/src/p_effect.cpp index 3bbf165021..e84cf8e3cb 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -279,9 +279,9 @@ void P_ThinkParticles () continue; } - fixedvec2 newxy = P_GetOffsetPosition(particle->x, particle->y, particle->vel.x, particle->vel.y); - particle->x = newxy.x; - particle->y = newxy.y; + DVector2 newxy = P_GetOffsetPosition(FIXED2DBL(particle->x), FIXED2DBL(particle->y), FIXED2DBL(particle->vel.x), FIXED2DBL(particle->vel.y)); + particle->x = FLOAT2FIXED(newxy.X); + particle->y = FLOAT2FIXED(newxy.Y); //particle->x += particle->vel.x; //particle->y += particle->vel.y; particle->z += particle->vel.z; @@ -408,14 +408,14 @@ static void MakeFountain (AActor *actor, int color1, int color2) if (particle) { - angle_t an = M_Random()<<(24-ANGLETOFINESHIFT); - fixed_t out = FixedMul (actor->_f_radius(), M_Random()<<8); + DAngle an = M_Random() * (360. / 256); + double out = actor->radius * M_Random() / 256.; - fixedvec3 pos = actor->Vec3Offset(FixedMul(out, finecosine[an]), FixedMul(out, finesine[an]), actor->_f_height() + FRACUNIT); - particle->x = pos.x; - particle->y = pos.y; - particle->z = pos.z; - if (out < actor->_f_radius()/8) + DVector3 pos = actor->Vec3Angle(out, an, actor->Height + 1); + particle->x = FLOAT2FIXED(pos.X); + particle->y = FLOAT2FIXED(pos.Y); + particle->z = FLOAT2FIXED(pos.Z); + if (out < actor->radius/8) particle->vel.z += FRACUNIT*10/3; else particle->vel.z += FRACUNIT*3; @@ -449,14 +449,14 @@ void P_RunEffect (AActor *actor, int effects) particle = JitterParticle (3 + (M_Random() & 31)); if (particle) { - fixed_t pathdist = M_Random()<<8; - fixedvec3 pos = actor->Vec3Offset( - FLOAT2FIXED(backx) - fixed_t(actor->Vel.X * pathdist), - FLOAT2FIXED(backy) - fixed_t(actor->Vel.Y * pathdist), - FLOAT2FIXED(backz) - fixed_t(actor->Vel.Z * pathdist)); - particle->x = pos.x; - particle->y = pos.y; - particle->z = pos.z; + double pathdist = M_Random() / 256.; + DVector3 pos = actor->Vec3Offset( + backx - actor->Vel.X * pathdist, + backy - actor->Vel.Y * pathdist, + backz - actor->Vel.Z * pathdist); + particle->x = FLOAT2FIXED(pos.X); + particle->y = FLOAT2FIXED(pos.Y); + particle->z = FLOAT2FIXED(pos.Z); speed = (M_Random () - 128) * (FRACUNIT/200); particle->vel.x += fixed_t(speed * an.Cos()); particle->vel.y += fixed_t(speed * an.Sin()); @@ -468,14 +468,15 @@ void P_RunEffect (AActor *actor, int effects) for (i = 6; i; i--) { particle_t *particle = JitterParticle (3 + (M_Random() & 31)); if (particle) { - fixed_t pathdist = M_Random()<<8; - fixedvec3 pos = actor->Vec3Offset( - FLOAT2FIXED(backx) - fixed_t(actor->Vel.X * pathdist), - FLOAT2FIXED(backy) - fixed_t(actor->Vel.Y * pathdist), - FLOAT2FIXED(backz) - fixed_t(actor->Vel.Z * pathdist) + (M_Random() << 10)); - particle->x = pos.x; - particle->y = pos.y; - particle->z = pos.z; + double pathdist = M_Random() / 256.; + DVector3 pos = actor->Vec3Offset( + backx - actor->Vel.X * pathdist, + backy - actor->Vel.Y * pathdist, + backz - actor->Vel.Z * pathdist + (M_Random() / 64.)); + particle->x = FLOAT2FIXED(pos.X); + particle->y = FLOAT2FIXED(pos.Y); + particle->z = FLOAT2FIXED(pos.Z); + speed = (M_Random () - 128) * (FRACUNIT/200); particle->vel.x += fixed_t(speed * an.Cos()); particle->vel.y += fixed_t(speed * an.Sin()); @@ -526,18 +527,18 @@ void P_RunEffect (AActor *actor, int effects) particle = JitterParticle (16); if (particle != NULL) { - angle_t ang = M_Random () << (32-ANGLETOFINESHIFT-8); - fixedvec3 pos = actor->Vec3Offset(FixedMul (actor->_f_radius(), finecosine[ang]), FixedMul (actor->_f_radius(), finesine[ang]), 0); - particle->x = pos.x; - particle->y = pos.y; - particle->z = pos.z; + DAngle ang = M_Random() * (360 / 256.); + DVector3 pos = actor->Vec3Angle(actor->radius, ang, 0); + particle->x = FLOAT2FIXED(pos.X); + particle->y = FLOAT2FIXED(pos.Y); + particle->z = FLOAT2FIXED(pos.Z); particle->color = *protectColors[M_Random() & 1]; particle->vel.z = FRACUNIT; particle->accz = M_Random () << 7; particle->size = 1; if (M_Random () < 128) { // make particle fall from top of actor - particle->z += actor->_f_height(); + particle->z += FLOAT2FIXED(actor->Height); particle->vel.z = -particle->vel.z; particle->accz = -particle->accz; } @@ -882,14 +883,14 @@ void P_DisconnectEffect (AActor *actor) if (!p) break; - - fixed_t xo = ((M_Random() - 128) << 9) * int(actor->radius); - fixed_t yo = ((M_Random() - 128) << 9) * int(actor->radius); - fixed_t zo = (M_Random() << 8) * int(actor->Height); - fixedvec3 pos = actor->Vec3Offset(xo, yo, zo); - p->x = pos.x; - p->y = pos.y; - p->z = pos.z; + double xo = (M_Random() - 128)*actor->radius / 128; + double yo = (M_Random() - 128)*actor->radius / 128; + double zo = M_Random()*actor->Height / 256; + + DVector3 pos = actor->Vec3Offset(xo, yo, zo); + p->x = FLOAT2FIXED(pos.X); + p->y = FLOAT2FIXED(pos.Y); + p->z = FLOAT2FIXED(pos.Z); p->accz -= FRACUNIT/4096; p->color = M_Random() < 128 ? maroon1 : maroon2; p->size = 4; diff --git a/src/p_effect.h b/src/p_effect.h index f079434940..cea9b2fdff 100644 --- a/src/p_effect.h +++ b/src/p_effect.h @@ -52,6 +52,12 @@ struct subsector_t; // [RH] Particle details +struct fixedvec3 +{ + fixed_t x, y, z; +}; + + struct particle_t { fixed_t x,y,z; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 57b2200d29..784c70fd54 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -162,12 +162,12 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun // I wish there was a better method to do this than randomly looking through the portal at a few places... if (checkabove) { - sector_t *upper = P_PointInSector(check->V1() + check->Delta() / 2 + sec->SkyBoxes[sector_t::ceiling]->Scale); + sector_t *upper = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->SkyBoxes[sector_t::ceiling]->Scale); P_RecursiveSound(upper, soundtarget, splash, soundblocks, emitter, maxdist); } if (checkbelow) { - sector_t *lower = P_PointInSector(check->V1() + check->Delta() / 2 + sec->SkyBoxes[sector_t::floor]->Scale); + sector_t *lower = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->SkyBoxes[sector_t::floor]->Scale); P_RecursiveSound(lower, soundtarget, splash, soundblocks, emitter, maxdist); } FLinePortal *port = check->getPortal(); @@ -195,18 +195,18 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun other = check->sidedef[0]->sector; // check for closed door - if ((sec->floorplane.ZatPoint (check->V1()) >= - other->ceilingplane.ZatPoint (check->V1()) && - sec->floorplane.ZatPoint (check->V2()) >= - other->ceilingplane.ZatPoint (check->V2())) - || (other->floorplane.ZatPoint (check->V1()) >= - sec->ceilingplane.ZatPoint (check->V1()) && - other->floorplane.ZatPoint (check->V2()) >= - sec->ceilingplane.ZatPoint (check->V2())) - || (other->floorplane.ZatPoint (check->V1()) >= - other->ceilingplane.ZatPoint (check->V1()) && - other->floorplane.ZatPoint (check->V2()) >= - other->ceilingplane.ZatPoint (check->V2()))) + if ((sec->floorplane.ZatPoint (check->v1->fPos()) >= + other->ceilingplane.ZatPoint (check->v1->fPos()) && + sec->floorplane.ZatPoint (check->v2->fPos()) >= + other->ceilingplane.ZatPoint (check->v2->fPos())) + || (other->floorplane.ZatPoint (check->v1->fPos()) >= + sec->ceilingplane.ZatPoint (check->v1->fPos()) && + other->floorplane.ZatPoint (check->v2->fPos()) >= + sec->ceilingplane.ZatPoint (check->v2->fPos())) + || (other->floorplane.ZatPoint (check->v1->fPos()) >= + other->ceilingplane.ZatPoint (check->v1->fPos()) && + other->floorplane.ZatPoint (check->v2->fPos()) >= + other->ceilingplane.ZatPoint (check->v2->fPos()))) { continue; } diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index e4993a2733..becd1f3bea 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -81,7 +81,7 @@ static void CreateCachedNodes(MapData *map); // fixed 32 bit gl_vert format v2.0+ (glBsp 1.91) struct mapglvertex_t { - fixed_t x,y; + SDWORD x,y; }; struct gl3_mapsubsector_t @@ -1333,7 +1333,7 @@ CCMD(clearnodecache) // //========================================================================== -subsector_t *P_PointInSubsector (fixed_t x, fixed_t y) +subsector_t *P_PointInSubsector (double x, double y) { node_t *node; int side; diff --git a/src/p_local.h b/src/p_local.h index a9b6c802d1..4a68c236cb 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -52,9 +52,6 @@ struct FTranslatedLineTarget; // against lines and things #define MAPBLOCKUNITS 128 #define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT) -#define MAPBLOCKSHIFT (FRACBITS+7) -#define MAPBMASK (MAPBLOCKSIZE-1) -#define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS) // Inspired by Maes extern int bmapnegx; @@ -202,7 +199,7 @@ AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false) // If "floatok" true, move would be ok -// if within "tmfloorz - tm_f_ceilingz()". +// if within "tmfloorz - tmceilingz". extern msecnode_t *sector_list; // phares 3/16/98 struct spechit_t @@ -264,7 +261,6 @@ enum void P_FindFloorCeiling (AActor *actor, int flags=0); bool P_ChangeSector (sector_t* sector, int crunch, double amt, int floorOrCeil, bool isreset); -inline bool P_ChangeSector(sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset) = delete; DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLineTarget *pLineTarget = NULL, DAngle vrange = 0., int flags = 0, AActor *target = NULL, AActor *friender = NULL); diff --git a/src/p_map.cpp b/src/p_map.cpp index c26cfc5e88..e6b189d7b3 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -109,7 +109,7 @@ static DVector2 FindRefPoint(line_t *ld, const DVector2 &pos) !ld->frontsector->PortalBlocksMovement(sector_t::floor)) { - DVector2 v1 = ld->V1(); + DVector2 v1 = ld->v1->fPos(); DVector2 d = ld->Delta(); double r = clamp(((pos.X - v1.X) * d.X + (pos.Y - v1.Y) * d.Y) / (d.X*d.X + d.Y*d.Y), 0., 1.); return v1 + d*r; @@ -2728,11 +2728,11 @@ void FSlide::SlideTraverse(const DVector2 &start, const DVector2 &end) // the line does block movement, // see if it is closer than best so far isblocking: - if (in->Frac < bestSlidefrac) + if (in->frac < bestSlidefrac) { secondSlidefrac = bestSlidefrac; secondslideline = bestslideline; - bestSlidefrac = in->Frac; + bestSlidefrac = in->frac; bestslideline = li; } @@ -3057,11 +3057,11 @@ bool FSlide::BounceTraverse(const DVector2 &start, const DVector2 &end) // the line does block movement, see if it is closer than best so far bounceblocking: - if (in->Frac < bestSlidefrac) + if (in->frac < bestSlidefrac) { secondSlidefrac = bestSlidefrac; secondslideline = bestslideline; - bestSlidefrac = in->Frac; + bestSlidefrac = in->frac; bestslideline = li; } return false; // stop @@ -3419,9 +3419,9 @@ struct aim_t F3DFloor* rover; DAngle highpitch, lowpitch; - double trX = trace.x + trace.dx * in->Frac; - double trY = trace.y + trace.dy * in->Frac; - double dist = attackrange * in->Frac; + double trX = trace.x + trace.dx * in->frac; + double trY = trace.y + trace.dy * in->frac; + double dist = attackrange * in->frac; // 3D floor check. This is not 100% accurate but normally sufficient when // combined with a final sight check @@ -3632,7 +3632,7 @@ struct aim_t double dist; DAngle thingpitch; - if (linetarget.linetarget != NULL && in->Frac > linetarget.frac) return; // we already found something better in another portal section. + if (linetarget.linetarget != NULL && in->frac > linetarget.frac) return; // we already found something better in another portal section. if (in->isaline) { @@ -3644,7 +3644,7 @@ struct aim_t if (li->isLinePortal() && frontflag == 0) { - EnterLinePortal(li, in->Frac); + EnterLinePortal(li, in->frac); return; } @@ -3662,7 +3662,7 @@ struct aim_t if (open.range <= 0 || open.bottom >= open.top) return; - dist = attackrange * in->Frac; + dist = attackrange * in->frac; if (open.bottom != LINEOPEN_MIN) { @@ -3692,11 +3692,11 @@ struct aim_t // check portal in backsector when aiming up/downward is possible, the line doesn't have portals on both sides and there's actually a portal in the backsector if ((planestocheck & aim_up) && toppitch < 0 && open.top != LINEOPEN_MAX && !entersec->PortalBlocksMovement(sector_t::ceiling)) { - EnterSectorPortal(sector_t::ceiling, in->Frac, entersec, toppitch, MIN(0., bottompitch)); + EnterSectorPortal(sector_t::ceiling, in->frac, entersec, toppitch, MIN(0., bottompitch)); } if ((planestocheck & aim_down) && bottompitch > 0 && open.bottom != LINEOPEN_MIN && !entersec->PortalBlocksMovement(sector_t::floor)) { - EnterSectorPortal(sector_t::floor, in->Frac, entersec, MAX(0., toppitch), bottompitch); + EnterSectorPortal(sector_t::floor, in->frac, entersec, MAX(0., toppitch), bottompitch); } continue; // shot continues } @@ -3728,7 +3728,7 @@ struct aim_t } } } - dist = attackrange * in->Frac; + dist = attackrange * in->frac; // Don't autoaim certain special actors if (!cl_doautoaim && th->flags6 & MF6_NOTAUTOAIMED) @@ -3811,7 +3811,7 @@ struct aim_t if (cosine != 0) { double tracelen = DVector2(it.Trace().dx, it.Trace().dy).Length(); - double d3 = tracelen * in->Frac / cosine; + double d3 = tracelen * in->frac / cosine; if (d3 > attackrange) { return; @@ -3834,7 +3834,7 @@ struct aim_t // friends don't aim at friends (except players), at least not first if (aimdebug) Printf("Hit friend %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); - SetResult(thing_friend, in->Frac, th, thingpitch); + SetResult(thing_friend, in->frac, th, thingpitch); } } else if (!(th->flags3 & MF3_ISMONSTER) && th->player == NULL) @@ -3844,14 +3844,14 @@ struct aim_t // don't autoaim at barrels and other shootable stuff unless no monsters have been found if (aimdebug) Printf("Hit other %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); - SetResult(thing_other, in->Frac, th, thingpitch); + SetResult(thing_other, in->frac, th, thingpitch); } } else { if (aimdebug) Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); - SetResult(linetarget, in->Frac, th, thingpitch); + SetResult(linetarget, in->frac, th, thingpitch); return; } } @@ -3859,7 +3859,7 @@ struct aim_t { if (aimdebug) Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); - SetResult(linetarget, in->Frac, th, thingpitch); + SetResult(linetarget, in->frac, th, thingpitch); return; } } diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 58c186593c..8c03674afa 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -46,8 +46,8 @@ #include "po_man.h" static AActor *RoughBlockCheck (AActor *mo, int index, void *); -static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node); -sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y); +sector_t *P_PointInSectorBuggy(double x, double y); +int P_VanillaPointOnDivlineSide(double x, double y, const divline_t* line); //========================================================================== @@ -58,13 +58,28 @@ sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y); // //========================================================================== -fixed_t P_AproxDistance (fixed_t dx, fixed_t dy) +int P_AproxDistance (int dx, int dy) { dx = abs(dx); dy = abs(dy); return (dx < dy) ? dx+dy-(dx>>1) : dx+dy-(dy>>1); } +//========================================================================== +// +// P_PointOnDivlineSideCompat +// +// Returns the fractional intercept point along the first divline +// with compatibility flag handling +// +//========================================================================== + +inline int P_PointOnDivlineSideCompat(double x, double y, const divline_t *line) +{ + return (i_compatflags2 & COMPATF2_POINTONLINE) + ? P_VanillaPointOnDivlineSide(x, y, line) : P_PointOnDivlineSide(x, y, line); +} + //========================================================================== // // P_InterceptVector @@ -96,69 +111,6 @@ double P_InterceptVector(const divline_t *v2, const divline_t *v1) return num / den; } - -fixed_t P_InterceptVector (const fdivline_t *v2, const fdivline_t *v1) -{ -#if 0 // [RH] Use 64 bit ints, so long divlines don't overflow - - SQWORD den = ( ((SQWORD)v1->dy*v2->dx - (SQWORD)v1->dx*v2->dy) >> FRACBITS ); - if (den == 0) - return 0; // parallel - SQWORD num = ((SQWORD)(v1->fixX() - v2->fixX())*v1->dy + (SQWORD)(v2->fixY() - v1->fixY())*v1->dx); - return (fixed_t)(num / den); - -#elif 0 // This is the original Doom version - - fixed_t frac; - fixed_t num; - fixed_t den; - - den = FixedMul (v1->dy>>8,v2->dx) - FixedMul(v1->dx>>8,v2->dy); - - if (den == 0) - return 0; - // I_Error ("P_InterceptVector: parallel"); - - num = - FixedMul ( (v1->fixX() - v2->fixX())>>8 ,v1->dy ) - +FixedMul ( (v2->fixY() - v1->fixY())>>8, v1->dx ); - - frac = FixedDiv (num , den); - - return frac; - -#else // optimized version of the float debug version. A lot faster on modern systens. - - - double frac; - double num; - double den; - - // There's no need to divide by FRACUNIT here. - // At the end both num and den will contain a factor - // 1/(FRACUNIT*FRACUNIT) so they'll cancel each other out. - double v1x = (double)v1->x; - double v1y = (double)v1->y; - double v1dx = (double)v1->dx; - double v1dy = (double)v1->dy; - double v2x = (double)v2->x; - double v2y = (double)v2->y; - double v2dx = (double)v2->dx; - double v2dy = (double)v2->dy; - - den = v1dy*v2dx - v1dx*v2dy; - - if (den == 0) - return 0; // parallel - - num = (v1x - v2x)*v1dy + (v2y - v1y)*v1dx; - frac = num / den; - - return FLOAT2FIXED(frac); -#endif -} - - //========================================================================== // // P_LineOpening @@ -374,7 +326,7 @@ void AActor::UnlinkFromWorld () bool AActor::FixMapthingPos() { - sector_t *secstart = P_PointInSectorBuggy(_f_X(), _f_Y()); + sector_t *secstart = P_PointInSectorBuggy(X(), Y()); int blockx = GetBlockX(X()); int blocky = GetBlockY(Y()); @@ -472,12 +424,12 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) } else { - sector = P_PointInSectorBuggy(_f_X(), _f_Y()); + sector = P_PointInSectorBuggy(X(), Y()); } } Sector = sector; - subsector = R_PointInSubsector(_f_X(), _f_Y()); // this is from the rendering nodes, not the gameplay nodes! + subsector = R_PointInSubsector(Pos()); // this is from the rendering nodes, not the gameplay nodes! if (!(flags & MF_NOSECTOR)) { @@ -515,7 +467,7 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) { FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); - P_CollectConnectedGroups(Sector->PortalGroup, _f_Pos(), _f_Top(), _f_radius(), check); + P_CollectConnectedGroups(Sector->PortalGroup, Pos(), Top(), radius, check); for (int i = -1; i < (int)check.Size(); i++) { @@ -564,10 +516,10 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) } } -void AActor::SetOrigin (fixed_t ix, fixed_t iy, fixed_t iz, bool moving) +void AActor::SetOrigin(double x, double y, double z, bool moving) { UnlinkFromWorld (); - SetXYZ(ix, iy, iz); + SetXYZ(x, y, z); LinkToWorld (); P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS); if (!moving) ClearInterpolation(); @@ -638,10 +590,10 @@ FBlockLinesIterator::FBlockLinesIterator(int _minx, int _miny, int _maxx, int _m void FBlockLinesIterator::init(const FBoundingBox &box) { validcount++; - maxy = GetBlockY(FIXED2DBL(box.Top())); - miny = GetBlockY(FIXED2DBL(box.Bottom())); - maxx = GetBlockX(FIXED2DBL(box.Right())); - minx = GetBlockX(FIXED2DBL(box.Left())); + maxy = GetBlockY(box.Top()); + miny = GetBlockY(box.Bottom()); + maxx = GetBlockX(box.Right()); + minx = GetBlockX(box.Left()); Reset(); } @@ -756,28 +708,26 @@ line_t *FBlockLinesIterator::Next() // //=========================================================================== -FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius) +FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, double checkradius) : checklist(check) { - checkpoint = origin->_f_Pos(); - if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->_f_Top(), checkradius, checklist); - checkpoint.z = checkradius == -1? origin->_f_radius() : checkradius; + checkpoint = origin->Pos(); + if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist); + checkpoint.Z = checkradius == -1? origin->radius : checkradius; basegroup = origin->Sector->PortalGroup; startsector = origin->Sector; Reset(); } -FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, sector_t *newsec) +FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, sector_t *newsec) : checklist(check) { - checkpoint.x = checkx; - checkpoint.y = checky; - checkpoint.z = checkz; + checkpoint = { checkx, checky, checkz }; if (newsec == NULL) newsec = P_PointInSector(checkx, checky); startsector = newsec; basegroup = newsec->PortalGroup; if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist); - checkpoint.z = checkradius; + checkpoint.Z = checkradius; Reset(); } @@ -787,7 +737,7 @@ FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, fix // //=========================================================================== -bool FMultiBlockLinesIterator::GoUp(fixed_t x, fixed_t y) +bool FMultiBlockLinesIterator::GoUp(double x, double y) { if (continueup) { @@ -808,7 +758,7 @@ bool FMultiBlockLinesIterator::GoUp(fixed_t x, fixed_t y) // //=========================================================================== -bool FMultiBlockLinesIterator::GoDown(fixed_t x, fixed_t y) +bool FMultiBlockLinesIterator::GoDown(double x, double y) { if (continuedown) { @@ -835,10 +785,8 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) if (line != NULL) { item->line = line; - item->position.x = offset.x; - item->position.y = offset.y; - // same as above in floating point. This is here so that this stuff can be converted piece by piece. - item->Position = { FIXED2DBL(item->position.x), FIXED2DBL(item->position.y), FIXED2DBL(item->position.z) }; + item->Position.X = offset.X; + item->Position.Y = offset.Y; item->portalflags = portalflags; return true; } @@ -848,19 +796,19 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) if (portalflags == FFCF_NOFLOOR && nextflags != FPortalGroupArray::UPPER) { // if this is the last upper portal in the list, check if we need to go further up to find the real ceiling. - if (GoUp(offset.x, offset.y)) return Next(item); + if (GoUp(offset.X, offset.Y)) return Next(item); } else if (portalflags == FFCF_NOCEILING && nextflags != FPortalGroupArray::LOWER) { // if this is the last lower portal in the list, check if we need to go further down to find the real floor. - if (GoDown(offset.x, offset.y)) return Next(item); + if (GoDown(offset.X, offset.Y)) return Next(item); } if (onlast) { cursector = startsector; // We reached the end of the list. Check if we still need to check up- and downwards. - if (GoUp(checkpoint.x, checkpoint.y) || - GoDown(checkpoint.x, checkpoint.y)) + if (GoUp(checkpoint.X, checkpoint.Y) || + GoDown(checkpoint.X, checkpoint.Y)) { return Next(item); } @@ -894,11 +842,11 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) void FMultiBlockLinesIterator::startIteratorForGroup(int group) { - offset = Displacements._f_getOffset(basegroup, group); - offset.x += checkpoint.x; - offset.y += checkpoint.y; - cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset.x, offset.y); - bbox.setBox(offset.x, offset.y, checkpoint.z); + offset = Displacements.getOffset(basegroup, group); + offset.X += checkpoint.X; + offset.Y += checkpoint.Y; + cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset); + bbox.setBox(offset.X, offset.Y, checkpoint.Z); blockIterator.init(bbox); } @@ -944,10 +892,10 @@ FBlockThingsIterator::FBlockThingsIterator(int _minx, int _miny, int _maxx, int void FBlockThingsIterator::init(const FBoundingBox &box) { - maxy = GetBlockY(FIXED2DBL(box.Top())); - miny = GetBlockY(FIXED2DBL(box.Bottom())); - maxx = GetBlockX(FIXED2DBL(box.Right())); - minx = GetBlockX(FIXED2DBL(box.Left())); + maxy = GetBlockY(box.Top()); + miny = GetBlockY(box.Bottom()); + maxx = GetBlockX(box.Right()); + minx = GetBlockX(box.Left()); ClearHash(); Reset(); } @@ -1025,14 +973,14 @@ AActor *FBlockThingsIterator::Next(bool centeronly) if (centeronly) { // Block boundaries for compatibility mode - fixed_t blockleft = (curx << MAPBLOCKSHIFT) + FLOAT2FIXED(bmaporgx); - fixed_t blockright = blockleft + MAPBLOCKSIZE; - fixed_t blockbottom = (cury << MAPBLOCKSHIFT) + FLOAT2FIXED(bmaporgy); - fixed_t blocktop = blockbottom + MAPBLOCKSIZE; + double blockleft = (curx * MAPBLOCKUNITS) + bmaporgx; + double blockright = blockleft + MAPBLOCKUNITS; + double blockbottom = (cury * MAPBLOCKUNITS) + bmaporgy; + double blocktop = blockbottom + MAPBLOCKUNITS; // only return actors with the center in this block - if (me->_f_X() >= blockleft && me->_f_X() < blockright && - me->_f_Y() >= blockbottom && me->_f_Y() < blocktop) + if (me->X() >= blockleft && me->X() < blockright && + me->Y() >= blockbottom && me->Y() < blocktop) { return me; } @@ -1093,26 +1041,26 @@ AActor *FBlockThingsIterator::Next(bool centeronly) // //=========================================================================== -FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius, bool ignorerestricted) +FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, double checkradius, bool ignorerestricted) : checklist(check) { - checkpoint = origin->_f_Pos(); - if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->_f_Top(), checkradius, checklist); - checkpoint.z = checkradius == -1? origin->_f_radius() : checkradius; + checkpoint = origin->Pos(); + if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist); + checkpoint.Z = checkradius == -1? origin->radius : checkradius; basegroup = origin->Sector->PortalGroup; Reset(); } -FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted, sector_t *newsec) +FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec) : checklist(check) { - checkpoint.x = checkx; - checkpoint.y = checky; - checkpoint.z = checkz; + checkpoint.X = checkx; + checkpoint.Y = checky; + checkpoint.Z = checkz; if (newsec == NULL) newsec = P_PointInSector(checkx, checky); basegroup = newsec->PortalGroup; if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist); - checkpoint.z = checkradius; + checkpoint.Z = checkradius; Reset(); } @@ -1128,11 +1076,8 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite if (thing != NULL) { item->thing = thing; - item->position = checkpoint + Displacements._f_getOffset(basegroup, thing->Sector->PortalGroup); + item->Position = checkpoint + Displacements.getOffset(basegroup, thing->Sector->PortalGroup); item->portalflags = portalflags; - - // same as above in floating point. This is here so that this stuff can be converted piece by piece. - item->Position = { FIXED2DBL(item->position.x), FIXED2DBL(item->position.y), FIXED2DBL(item->position.z) }; return true; } bool onlast = unsigned(index + 1) >= checklist.Size(); @@ -1170,10 +1115,10 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite void FMultiBlockThingsIterator::startIteratorForGroup(int group) { - fixedvec2 offset = Displacements._f_getOffset(basegroup, group); - offset.x += checkpoint.x; - offset.y += checkpoint.y; - bbox.setBox(offset.x, offset.y, checkpoint.z); + DVector2 offset = Displacements.getOffset(basegroup, group); + offset.X += checkpoint.X; + offset.Y += checkpoint.Y; + bbox.setBox(offset.X, offset.Y, checkpoint.Z); blockIterator.init(bbox); } @@ -1220,17 +1165,17 @@ void FPathTraverse::AddLineIntercepts(int bx, int by) { int s1; int s2; - fixed_t frac; - fdivline_t dl; + double frac; + divline_t dl; // avoid precision problems with two routines - if ( trace.dx > FRACUNIT*16 - || trace.dy > FRACUNIT*16 - || trace.dx < -FRACUNIT*16 - || trace.dy < -FRACUNIT*16) + if ( trace.dx > 16 + || trace.dy > 16 + || trace.dx < -16 + || trace.dy < -16) { - s1 = P_PointOnDivlineSide (ld->v1->fixX(), ld->v1->fixY(), &trace); - s2 = P_PointOnDivlineSide (ld->v2->fixX(), ld->v2->fixY(), &trace); + s1 = P_PointOnDivlineSideCompat (ld->v1->fX(), ld->v1->fY(), &trace); + s2 = P_PointOnDivlineSideCompat (ld->v2->fX(), ld->v2->fY(), &trace); } else { @@ -1244,7 +1189,7 @@ void FPathTraverse::AddLineIntercepts(int bx, int by) P_MakeDivline (ld, &dl); frac = P_InterceptVector (&trace, &dl); - if (frac < startfrac || frac > FRACUNIT) continue; // behind source or beyond end point + if (frac < Startfrac || frac > 1.) continue; // behind source or beyond end point intercept_t newintercept; @@ -1271,7 +1216,7 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it while ((thing = it.Next(compatible))) { int numfronts = 0; - fdivline_t line; + divline_t line; int i; @@ -1287,69 +1232,69 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it switch (i) { case 0: // Top edge - line.x = thing->_f_X() + thing->_f_radius(); - line.y = thing->_f_Y() + thing->_f_radius(); - line.dx = -thing->_f_radius() * 2; + line.x = thing->X() + thing->radius; + line.y = thing->Y() + thing->radius; + line.dx = -thing->radius * 2; line.dy = 0; break; case 1: // Right edge - line.x = thing->_f_X() + thing->_f_radius(); - line.y = thing->_f_Y() - thing->_f_radius(); + line.x = thing->X() + thing->radius; + line.y = thing->Y() - thing->radius; line.dx = 0; - line.dy = thing->_f_radius() * 2; + line.dy = thing->radius * 2; break; case 2: // Bottom edge - line.x = thing->_f_X() - thing->_f_radius(); - line.y = thing->_f_Y() - thing->_f_radius(); - line.dx = thing->_f_radius() * 2; + line.x = thing->X() - thing->radius; + line.y = thing->Y() - thing->radius; + line.dx = thing->radius * 2; line.dy = 0; break; case 3: // Left edge - line.x = thing->_f_X() - thing->_f_radius(); - line.y = thing->_f_Y() + thing->_f_radius(); + line.x = thing->X() - thing->radius; + line.y = thing->Y() + thing->radius; line.dx = 0; - line.dy = thing->_f_radius() * -2; + line.dy = thing->radius * -2; break; } // Check if this side is facing the trace origin - if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &line) == 0) + if (P_PointOnDivlineSide (trace.x, trace.y, &line) == 0) { numfronts++; // If it is, see if the trace crosses it - if (P_PointOnDivlineSidePrecise (line.x, line.y, &trace) != - P_PointOnDivlineSidePrecise (line.x + line.dx, line.y + line.dy, &trace)) + if (P_PointOnDivlineSide (line.x, line.y, &trace) != + P_PointOnDivlineSide (line.x + line.dx, line.y + line.dy, &trace)) { // It's a hit - fixed_t frac = P_InterceptVector (&trace, &line); - if (frac < startfrac) + double frac = P_InterceptVector (&trace, &line); + if (frac < Startfrac) { // behind source - if (startfrac > 0) + if (Startfrac > 0) { // check if the trace starts within this actor switch (i) { case 0: - line.y -= 2 * thing->_f_radius(); + line.y -= 2 * thing->radius; break; case 1: - line.x -= 2 * thing->_f_radius(); + line.x -= 2 * thing->radius; break; case 2: - line.y += 2 * thing->_f_radius(); + line.y += 2 * thing->radius; break; case 3: - line.x += 2 * thing->_f_radius(); + line.x += 2 * thing->radius; break; } - fixed_t frac2 = P_InterceptVector(&trace, &line); - if (frac2 >= startfrac) goto addit; + double frac2 = P_InterceptVector(&trace, &line); + if (frac2 >= Startfrac) goto addit; } continue; } @@ -1380,33 +1325,33 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it else { // Old code for compatibility purposes - fixed_t x1, y1, x2, y2; + double x1, y1, x2, y2; int s1, s2; - fdivline_t dl; - fixed_t frac; + divline_t dl; + double frac; - bool tracepositive = (trace.dx ^ trace.dy)>0; + bool tracepositive = (trace.dx * trace.dy)>0; // check a corner to corner crossection for hit if (tracepositive) { - x1 = thing->_f_X() - thing->_f_radius(); - y1 = thing->_f_Y() + thing->_f_radius(); + x1 = thing->X() - thing->radius; + y1 = thing->Y() + thing->radius; - x2 = thing->_f_X() + thing->_f_radius(); - y2 = thing->_f_Y() - thing->_f_radius(); + x2 = thing->X() + thing->radius; + y2 = thing->Y() - thing->radius; } else { - x1 = thing->_f_X() - thing->_f_radius(); - y1 = thing->_f_Y() - thing->_f_radius(); + x1 = thing->X() - thing->radius; + y1 = thing->Y() - thing->radius; - x2 = thing->_f_X() + thing->_f_radius(); - y2 = thing->_f_Y() + thing->_f_radius(); + x2 = thing->X() + thing->radius; + y2 = thing->Y() + thing->radius; } - s1 = P_PointOnDivlineSide (x1, y1, &trace); - s2 = P_PointOnDivlineSide (x2, y2, &trace); + s1 = P_PointOnDivlineSideCompat (x1, y1, &trace); + s2 = P_PointOnDivlineSideCompat (x2, y2, &trace); if (s1 != s2) { @@ -1417,7 +1362,7 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it frac = P_InterceptVector (&trace, &dl); - if (frac >= startfrac) + if (frac >= Startfrac) { intercept_t newintercept; newintercept.frac = frac; @@ -1442,7 +1387,7 @@ intercept_t *FPathTraverse::Next() { intercept_t *in = NULL; - fixed_t dist = FIXED_MAX; + double dist = FLT_MAX; for (unsigned scanpos = intercept_index; scanpos < intercepts.Size (); scanpos++) { intercept_t *scan = &intercepts[scanpos]; @@ -1450,11 +1395,10 @@ intercept_t *FPathTraverse::Next() { dist = scan->frac; in = scan; - in->Frac = FIXED2FLOAT(in->frac); } } - if (dist > FRACUNIT || in == NULL) return NULL; // checked everything in range + if (dist > 1. || in == NULL) return NULL; // checked everything in range in->done = true; return in; } @@ -1466,19 +1410,12 @@ intercept_t *FPathTraverse::Next() // //=========================================================================== -void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac) +void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags, double startfrac) { - fixed_t xt1, xt2; - fixed_t yt1, yt2; - long long _x1, _x2, _y1, _y2; - - fixed_t xstep; - fixed_t ystep; - - fixed_t partialx, partialy; - - fixed_t xintercept; - fixed_t yintercept; + double xt1, yt1, xt2, yt2; + double xstep, ystep; + double partialx, partialy; + double xintercept, yintercept; int mapx; int mapy; @@ -1502,8 +1439,8 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl } if (startfrac > 0) { - fixed_t startdx = FixedMul(trace.dx, startfrac); - fixed_t startdy = FixedMul(trace.dy, startfrac); + double startdx = trace.dx * startfrac; + double startdy = trace.dy * startfrac; x1 += startdx; y1 += startdy; @@ -1514,110 +1451,95 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl validcount++; intercept_index = intercepts.Size(); - this->startfrac = startfrac; - - fixed_t _f_bmaporgx = FLOAT2FIXED(bmaporgx); - fixed_t _f_bmaporgy = FLOAT2FIXED(bmaporgy); - - if ( ((x1-_f_bmaporgx)&(MAPBLOCKSIZE-1)) == 0) - x1 += FRACUNIT; // don't side exactly on a line - - if ( ((y1-_f_bmaporgy)&(MAPBLOCKSIZE-1)) == 0) - y1 += FRACUNIT; // don't side exactly on a line - - _x1 = (long long)x1 - _f_bmaporgx; - _y1 = (long long)y1 - _f_bmaporgy; - x1 -= _f_bmaporgx; - y1 -= _f_bmaporgy; - xt1 = int(_x1 >> MAPBLOCKSHIFT); - yt1 = int(_y1 >> MAPBLOCKSHIFT); + Startfrac = startfrac; if (flags & PT_DELTA) { - _x2 = _x1 + x2; - _y2 = _y1 + y2; - xt2 = int(_x2 >> MAPBLOCKSHIFT); - yt2 = int(_y2 >> MAPBLOCKSHIFT); - x2 = (int)_x2; - y2 = (int)_y2; - } - else - { - _x2 = (long long)x2 - _f_bmaporgx; - _y2 = (long long)y2 - _f_bmaporgy; - x2 -= _f_bmaporgx; - y2 -= _f_bmaporgy; - xt2 = int(_x2 >> MAPBLOCKSHIFT); - yt2 = int(_y2 >> MAPBLOCKSHIFT); + x2 += x1; + y2 += y2; } - if (xt2 > xt1) + x1 -= bmaporgx; + y1 -= bmaporgy; + xt1 = x1 / MAPBLOCKUNITS; + yt1 = y1 / MAPBLOCKUNITS; + + x2 -= bmaporgx; + y2 -= bmaporgy; + xt2 = x2 / MAPBLOCKUNITS; + yt2 = y2 / MAPBLOCKUNITS; + + mapx = int(xt1); + mapy = int(yt1); + int mapex = int(xt2); + int mapey = int(yt2); + + + if (mapex > mapx) { mapxstep = 1; - partialx = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1)); - ystep = FixedDiv (y2-y1,abs(x2-x1)); + partialx = xs_CeilToInt(xt1) - xt1; + ystep = (y2 - y1) / fabs(x2 - x1); } - else if (xt2 < xt1) + else if (mapex < mapx) { mapxstep = -1; - partialx = (x1>>MAPBTOFRAC)&(FRACUNIT-1); - ystep = FixedDiv (y2-y1,abs(x2-x1)); + partialx = xt1 - xs_FloorToInt(xt1); + ystep = (y2 - y1) / fabs(x2 - x1); } else { mapxstep = 0; - partialx = FRACUNIT; - ystep = 256*FRACUNIT; - } - yintercept = int(_y1>>MAPBTOFRAC) + FixedMul (partialx, ystep); + partialx = 1.; + ystep = 256; + } + yintercept = yt1 + partialx * ystep; - if (yt2 > yt1) + if (mapey > mapy) { mapystep = 1; - partialy = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1)); - xstep = FixedDiv (x2-x1,abs(y2-y1)); + partialy = xs_CeilToInt(yt1) - yt1; + xstep = (x2 - x1) / fabs(y2 - y1); } - else if (yt2 < yt1) + else if (mapey < mapy) { mapystep = -1; - partialy = (y1>>MAPBTOFRAC)&(FRACUNIT-1); - xstep = FixedDiv (x2-x1,abs(y2-y1)); + partialy = yt1 - xs_FloorToInt(yt1); + xstep = (x2 - x1) / fabs(y2 - y1); } else { mapystep = 0; - partialy = FRACUNIT; - xstep = 256*FRACUNIT; - } - xintercept = int(_x1>>MAPBTOFRAC) + FixedMul (partialy, xstep); + partialy = 1; + xstep = 256; + } + xintercept = xt1 + partialy * xstep; // [RH] Fix for traces that pass only through blockmap corners. In that case, // xintercept and yintercept can both be set ahead of mapx and mapy, so the // for loop would never advance anywhere. - if (abs(xstep) == FRACUNIT && abs(ystep) == FRACUNIT) + if (fabs(xstep) == 1. && fabs(ystep) == 1.) { if (ystep < 0) { - partialx = FRACUNIT - partialx; + partialx = 1. - partialx; } if (xstep < 0) { - partialy = FRACUNIT - partialy; + partialy = 1. - partialy; } if (partialx == partialy) { - xintercept = xt1 << FRACBITS; - yintercept = yt1 << FRACBITS; + xintercept = xt1; + yintercept = yt1; } } // Step through map blocks. // Count is present to prevent a round off error // from skipping the break statement. - mapx = xt1; - mapy = yt1; bool compatible = (flags & PT_COMPATIBLE) && (i_compatflags & COMPATF_HITSCAN); @@ -1641,7 +1563,7 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl } // [RH] Handle corner cases properly instead of pretending they don't exist. - switch ((((yintercept >> FRACBITS) == mapy) << 1) | ((xintercept >> FRACBITS) == mapx)) + switch (((int(yintercept) == mapy) << 1) | (int(xintercept) == mapx)) { case 0: // neither xintercept nor yintercept match! count = 100; // Stop traversing, because somebody screwed up. @@ -1687,10 +1609,6 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl break; } } - ftrace.dx = FIXED2DBL(trace.dx); - ftrace.dy = FIXED2DBL(trace.dy); - ftrace.x = FIXED2DBL(trace.x); - ftrace.y = FIXED2DBL(trace.y); } //=========================================================================== @@ -1704,10 +1622,10 @@ int FPathTraverse::PortalRelocate(intercept_t *in, int flags, DVector3 *optpos) if (!in->isaline || !in->d.line->isLinePortal()) return false; if (P_PointOnLineSidePrecise(trace.x, trace.y, in->d.line) == 1) return false; - fixed_t hitx = trace.x; - fixed_t hity = trace.y; - fixed_t endx = trace.x + trace.dx; - fixed_t endy = trace.y + trace.dy; + double hitx = trace.x; + double hity = trace.y; + double endx = trace.x + trace.dx; + double endy = trace.y + trace.dy; P_TranslatePortalXY(in->d.line, hitx, hity); P_TranslatePortalXY(in->d.line, endx, endy); @@ -1873,12 +1791,12 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param) // //========================================================================== -static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node) +static int R_PointOnSideSlow(double xx, double yy, node_t *node) { // [RH] This might have been faster than two multiplies and an // add on a 386/486, but it certainly isn't on anything newer than that. - fixed_t dx; - fixed_t dy; + auto x = FloatToFixed(xx); + auto y = FloatToFixed(yy); double left; double right; @@ -1897,8 +1815,8 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node) return node->dx > 0; } - dx = (x - node->x); - dy = (y - node->y); + auto dx = (x - node->x); + auto dy = (y - node->y); // Try to quickly decide by looking at sign bits. if ((node->dy ^ node->dx ^ dx ^ dy) & 0x80000000) @@ -1912,6 +1830,7 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node) } // we must use doubles here because the fixed point code will produce errors due to loss of precision for extremely short linedefs. + // Note that this function is used for all map spawned actors and not just a compatibility fallback! left = (double)node->dy * (double)dx; right = (double)dy * (double)node->dx; @@ -1932,24 +1851,20 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node) // //=========================================================================== -int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line) +int P_VanillaPointOnLineSide(double x, double y, const line_t* line) { - fixed_t dx; - fixed_t dy; - fixed_t left; - fixed_t right; DVector2 delta = line->Delta(); if (delta.X == 0) { - if (x <= line->v1->fixX()) + if (x <= line->v1->fX()) return delta.Y > 0; return delta.Y < 0; } if (delta.Y == 0) { - if (y <= line->v1->fixY()) + if (y <= line->v1->fY()) return delta.X < 0; return delta.X > 0; @@ -1957,13 +1872,13 @@ int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line) // Note: This cannot really be converted to floating point // without breaking the intended use of this function - // (i.e. to emulate the horrible imprecision of the entire methpd) + // (i.e. to emulate the horrible imprecision of the entire method) - dx = (x - line->v1->fixX()); - dy = (y - line->v1->fixY()); + auto dx = FloatToFixed(x - line->v1->fX()); + auto dy = FloatToFixed(y - line->v1->fY()); - left = FixedMul ( int(delta.Y * 256) , dx ); - right = FixedMul ( dy , int(delta.X * 256) ); + auto left = MulScale16( int(delta.Y * 256) , dx ); + auto right = MulScale16( dy , int(delta.X * 256) ); if (right < left) return 0; // front side @@ -1973,16 +1888,18 @@ int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line) //=========================================================================== // // P_VanillaPointOnDivlineSide -// P_PointOnDivlineSide() from the initial Doom source code release +// P_PointOnDivlineSideCompat() from the initial Doom source code release // //=========================================================================== -int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const fdivline_t* line) +int P_VanillaPointOnDivlineSide(double x, double y, const divline_t* line) { - fixed_t dx; - fixed_t dy; - fixed_t left; - fixed_t right; + int dx; + int dy; + int left; + int right; + int ldx; + int ldy; if (!line->dx) { @@ -1999,26 +1916,37 @@ int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const fdivline_t* line) return line->dx > 0; } - dx = (x - line->x); - dy = (y - line->y); + // This is supposed to be compatible so the rest needs to be done + // with the same broken fixed point checks as the original + dx = FloatToFixed(x - line->x); + dy = FloatToFixed(y - line->y); + ldx = FloatToFixed(line->dx); + ldy = FloatToFixed(line->dy); // try to quickly decide by looking at sign bits - if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 ) + if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 ) { - if ( (line->dy ^ dx) & 0x80000000 ) + if ( (ldy ^ dx) & 0x80000000 ) return 1; // (left is negative) return 0; } - left = FixedMul ( line->dy>>8, dx>>8 ); - right = FixedMul ( dy>>8 , line->dx>>8 ); + left = MulScale16( ldy>>8, dx>>8 ); + right = MulScale16( dy>>8 , ldx>>8 ); if (right < left) return 0; // front side return 1; // back side } -sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y) +//========================================================================== +// +// Use buggy PointOnSide and fix actors that lie on +// lines to compensate for some IWAD maps. +// +//========================================================================== + +sector_t *P_PointInSectorBuggy(double x, double y) { // single subsector is a special case if (numgamenodes == 0) diff --git a/src/p_maputl.h b/src/p_maputl.h index 2a68898c1d..d53ab49a77 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -8,14 +8,6 @@ extern int validcount; -struct fdivline_t -{ - fixed_t x; - fixed_t y; - fixed_t dx; - fixed_t dy; -}; - struct divline_t { double x; @@ -26,8 +18,7 @@ struct divline_t struct intercept_t { - double Frac; - fixed_t frac; // along trace line + double frac; bool isaline; bool done; union { @@ -45,74 +36,49 @@ struct intercept_t // //========================================================================== -const double POL_Epsilon = -1. / 65536.; - -inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) -{ - extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); - - return i_compatflags2 & COMPATF2_POINTONLINE - ? P_VanillaPointOnLineSide(x, y, line) - : DMulScale32 (y-line->v1->fixY(), line->fixDx(), line->v1->fixX()-x, line->fixDy()) > 0; -} - -inline int P_PointOnLineSidePrecise (fixed_t x, fixed_t y, const line_t *line) -{ - return DMulScale32 (y-line->v1->fixY(), line->fixDx(), line->v1->fixX()-x, line->fixDy()) > 0; -} - -inline int P_PointOnLineSide(double x, double y, const line_t *line) -{ - return P_PointOnLineSide(FLOAT2FIXED(x), FLOAT2FIXED(y), line); -} - -inline int P_PointOnLineSide(const DVector2 & p, const line_t *line) -{ - return P_PointOnLineSide(FLOAT2FIXED(p.X), FLOAT2FIXED(p.Y), line); -} - inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line) { - return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > POL_Epsilon ; + return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > -EQUAL_EPSILON; } inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line) { - return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > POL_Epsilon; + return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > -EQUAL_EPSILON; } +inline int P_PointOnLineSide (double x, double y, const line_t *line) +{ + extern int P_VanillaPointOnLineSide(double x, double y, const line_t* line); + + return i_compatflags2 & COMPATF2_POINTONLINE + ? P_VanillaPointOnLineSide(x, y, line) : P_PointOnLineSidePrecise(x, y, line); +} + +inline int P_PointOnLineSide(const DVector2 & p, const line_t *line) +{ + return P_PointOnLineSide(p.X, p.Y, line); +} + + + //========================================================================== // -// P_PointOnDivlineSide +// P_PointOnDivlineSideCompat // // Same as P_PointOnLineSide except it uses divlines // [RH] inlined, stripped down, and made more precise // //========================================================================== -inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const fdivline_t *line) +inline int P_PointOnDivlineSide(double x, double y, const divline_t *line) { - extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const fdivline_t* line); - - return (i_compatflags2 & COMPATF2_POINTONLINE) - ? P_VanillaPointOnDivlineSide(x, y, line) - : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); + return (y - line->y) * line->dx + (line->x - x) * line->dy > -EQUAL_EPSILON; } -inline int P_PointOnDivlineSidePrecise (fixed_t x, fixed_t y, const fdivline_t *line) +inline int P_PointOnDivlineSide(const DVector2 &pos, const divline_t *line) { - return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0; -} - -inline int P_PointOnDivlineSidePrecise(double x, double y, const divline_t *line) -{ - return (y - line->y) * line->dx + (line->x - x) * line->dy > 0; -} - -inline int P_PointOnDivlineSidePrecise(const DVector2 &pos, const divline_t *line) -{ - return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > 0; + return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > -EQUAL_EPSILON; } //========================================================================== @@ -121,14 +87,6 @@ inline int P_PointOnDivlineSidePrecise(const DVector2 &pos, const divline_t *lin // //========================================================================== -inline void P_MakeDivline (const line_t *li, fdivline_t *dl) -{ - dl->x = li->v1->fixX(); - dl->y = li->v1->fixY(); - dl->dx = li->fixDx(); - dl->dy = li->fixDy(); -} - inline void P_MakeDivline(const line_t *li, divline_t *dl) { dl->x = li->v1->fX(); @@ -163,15 +121,6 @@ inline void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *lined P_LineOpening(open, thing, linedef, xy, reinterpret_cast(ref), flags); } -inline void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx = FIXED_MIN, fixed_t refy = 0, int flags = 0) -{ - P_LineOpening(open, thing, linedef, DVector2(FIXED2DBL(x), FIXED2DBL(y)), &DVector2(FIXED2DBL(refx), FIXED2DBL(refy)), flags); -} -inline void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *linedef, fixedvec2 xy, fixed_t refx = FIXED_MIN, fixed_t refy = 0, int flags = 0) -{ - P_LineOpening(open, thing, linedef, xy.x, xy.y, refx, refy, flags); -} - class FBoundingBox; struct polyblock_t; @@ -277,8 +226,8 @@ public: class FMultiBlockLinesIterator { FPortalGroupArray &checklist; - fixedvec3 checkpoint; - fixedvec2 offset; + DVector3 checkpoint; + DVector2 offset; sector_t *startsector; sector_t *cursector; short basegroup; @@ -289,8 +238,8 @@ class FMultiBlockLinesIterator FBlockLinesIterator blockIterator; FBoundingBox bbox; - bool GoUp(fixed_t x, fixed_t y); - bool GoDown(fixed_t x, fixed_t y); + bool GoUp(double x, double y); + bool GoDown(double x, double y); void startIteratorForGroup(int group); public: @@ -298,18 +247,12 @@ public: struct CheckResult { line_t *line; - fixedvec3 position; DVector3 Position; int portalflags; }; - FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1); - FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, sector_t *newsec); - - FMultiBlockLinesIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, sector_t *newsec) - : FMultiBlockLinesIterator(check, FLOAT2FIXED(checkx), FLOAT2FIXED(checky), FLOAT2FIXED(checkz), FLOAT2FIXED(checkh), FLOAT2FIXED(checkradius), newsec) - { - } + FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, double checkradius = -1); + FMultiBlockLinesIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, sector_t *newsec); bool Next(CheckResult *item); void Reset(); @@ -376,7 +319,7 @@ public: class FMultiBlockThingsIterator { FPortalGroupArray &checklist; - fixedvec3 checkpoint; + DVector3 checkpoint; short basegroup; short portalflags; short index; @@ -390,17 +333,12 @@ public: struct CheckResult { AActor *thing; - fixedvec3 position; // keep these both until the fixed version can be removed. DVector3 Position; int portalflags; }; - FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1, bool ignorerestricted = false); - FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted, sector_t *newsec); - FMultiBlockThingsIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec) - : FMultiBlockThingsIterator(check, FLOAT2FIXED(checkx), FLOAT2FIXED(checky), FLOAT2FIXED(checkz), FLOAT2FIXED(checkh), FLOAT2FIXED(checkradius), ignorerestricted, newsec) - { - } + FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, double checkradius = -1, bool ignorerestricted = false); + FMultiBlockThingsIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec); bool Next(CheckResult *item); void Reset(); const FBoundingBox &Box() const @@ -416,9 +354,8 @@ class FPathTraverse protected: static TArray intercepts; - divline_t ftrace; - fdivline_t trace; - fixed_t startfrac; + divline_t trace; + double Startfrac; unsigned int intercept_index; unsigned int intercept_count; unsigned int count; @@ -430,34 +367,21 @@ public: intercept_t *Next(); - FPathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac = 0) + FPathTraverse(double x1, double y1, double x2, double y2, int flags, double startfrac = 0) { init(x1, y1, x2, y2, flags, startfrac); } - FPathTraverse(double x1, double y1, double x2, double y2, int flags, double startfrac = 0) - { - init(FLOAT2FIXED(x1), FLOAT2FIXED(y1), FLOAT2FIXED(x2), FLOAT2FIXED(y2), flags, FLOAT2FIXED(startfrac)); - } - void init(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac = 0); + void init(double x1, double y1, double x2, double y2, int flags, double startfrac = 0); int PortalRelocate(intercept_t *in, int flags, DVector3 *optpos = NULL); virtual ~FPathTraverse(); - const fdivline_t &_f_Trace() const { return trace; } - const divline_t &Trace() const { return ftrace; } + const divline_t &Trace() const { return trace; } - inline fixedvec2 _f_InterceptPoint(const intercept_t *in) - { - return - { - trace.x + FixedMul(trace.dx, in->frac), - trace.y + FixedMul(trace.dy, in->frac) - }; - } inline DVector2 InterceptPoint(const intercept_t *in) { return { - FIXED2DBL(trace.x + FixedMul(trace.dx, in->frac)), - FIXED2DBL(trace.y + FixedMul(trace.dy, in->frac)) + trace.x + trace.dx * in->frac, + trace.y + trace.dy * in->frac }; } @@ -480,18 +404,13 @@ public: } }; - - // // P_MAPUTL // typedef bool(*traverser_t) (intercept_t *in); -fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); - - -fixed_t P_InterceptVector (const fdivline_t *v2, const fdivline_t *v1); +int P_AproxDistance (int dx, int dy); double P_InterceptVector(const divline_t *v2, const divline_t *v1); #define PT_ADDLINES 1 diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index a96194426e..a05c7ca6dd 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1401,9 +1401,9 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) den = line->Delta().LengthSquared(); if (den != 0) { - frac = clamp((mo->Pos() - line->V1()) | line->Delta(), 0, den) / den; + frac = clamp((mo->Pos().XY() - line->v1->fPos()) | line->Delta(), 0, den) / den; - linepos = DVector3(line->V1() + line->Delta() * frac, pos.Z); + linepos = DVector3(line->v1->fPos() + line->Delta() * frac, pos.Z); F3DFloor * ffloor=NULL; if (line->sidedef[side^1] != NULL) diff --git a/src/p_pusher.cpp b/src/p_pusher.cpp index bbc140c518..4fb3b8f1f7 100644 --- a/src/p_pusher.cpp +++ b/src/p_pusher.cpp @@ -232,7 +232,7 @@ void DPusher::Tick () // point pusher. Crosses sectors, so use blockmap. FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); // no sector portals because this thing is utterly z-unaware. - FMultiBlockThingsIterator it(check, m_Source, FLOAT2FIXED(m_Radius)); + FMultiBlockThingsIterator it(check, m_Source, m_Radius); FMultiBlockThingsIterator::CheckResult cres; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index a636f585cd..e5f837ad3c 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -714,10 +714,10 @@ void sector_t::SetFade(int r, int g, int b) // //=========================================================================== -void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) const +void sector_t::ClosestPoint(const DVector2 &in, DVector2 &out) const { int i; - double x = fx, y = fy; + double x = in.X, y = in.Y; double bestdist = HUGE_VAL; double bestx = 0, besty = 0; @@ -725,34 +725,34 @@ void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) co { vertex_t *v1 = lines[i]->v1; vertex_t *v2 = lines[i]->v2; - double a = v2->fixX() - v1->fixX(); - double b = v2->fixY() - v1->fixY(); + double a = v2->fX() - v1->fX(); + double b = v2->fY() - v1->fY(); double den = a*a + b*b; double ix, iy, dist; if (den == 0) { // Line is actually a point! - ix = v1->fixX(); - iy = v1->fixY(); + ix = v1->fX(); + iy = v1->fY(); } else { - double num = (x - v1->fixX()) * a + (y - v1->fixY()) * b; + double num = (x - v1->fX()) * a + (y - v1->fY()) * b; double u = num / den; if (u <= 0) { - ix = v1->fixX(); - iy = v1->fixY(); + ix = v1->fX(); + iy = v1->fY(); } else if (u >= 1) { - ix = v2->fixX(); - iy = v2->fixY(); + ix = v2->fX(); + iy = v2->fY(); } else { - ix = v1->fixX() + u * a; - iy = v1->fixY() + u * b; + ix = v1->fX() + u * a; + iy = v1->fY() + u * b; } } a = (ix - x); @@ -765,8 +765,7 @@ void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) co besty = iy; } } - ox = fixed_t(bestx); - oy = fixed_t(besty); + out = { bestx, besty }; } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 4cb4229498..6c6b05d0a8 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3208,14 +3208,14 @@ static void P_GroupLines (bool buildmap) for (j = 0; j < sector->linecount; ++j) { li = sector->lines[j]; - bbox.AddToBox (li->v1->fixX(), li->v1->fixY()); - bbox.AddToBox (li->v2->fixX(), li->v2->fixY()); + bbox.AddToBox (li->v1->fPos()); + bbox.AddToBox (li->v2->fPos()); } } // set the center to the middle of the bounding box - sector->centerspot.X = FIXED2DBL(bbox.Right()/2 + bbox.Left()/2); - sector->centerspot.Y = FIXED2DBL(bbox.Top()/2 + bbox.Bottom()/2); + sector->centerspot.X = (bbox.Right() + bbox.Left()/2); + sector->centerspot.Y = (bbox.Top() + bbox.Bottom()/2); // For triangular sectors the above does not calculate good points unless the longest of the triangle's lines is perfectly horizontal and vertical if (sector->linecount == 3) @@ -3917,8 +3917,8 @@ void P_SetupLevel (const char *lumpname, int position) seg_t * seg=&segs[i]; if (seg->backsector == seg->frontsector && seg->linedef) { - fixed_t d1=P_AproxDistance(seg->v1->fixX()-seg->linedef->v1->fixX(),seg->v1->fixY()-seg->linedef->v1->fixY()); - fixed_t d2=P_AproxDistance(seg->v2->fixX()-seg->linedef->v1->fixX(),seg->v2->fixY()-seg->linedef->v1->fixY()); + double d1 = (seg->v1->fPos() - seg->linedef->v1->fPos()).LengthSquared(); + double d2 = (seg->v2->fPos() - seg->linedef->v1->fPos()).LengthSquared(); if (d2frontsector == li->backsector) return true; - double trX = Trace.x + Trace.dx * in->Frac; - double trY = Trace.y + Trace.dy * in->Frac; + double trX = Trace.x + Trace.dx * in->frac; + double trY = Trace.y + Trace.dy * in->frac; P_SightOpening (open, li, trX, trY); FLinePortal *lport = li->getPortal(); @@ -219,7 +219,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) // check bottom if (open.bottom > LINEOPEN_MIN) { - slope = (open.bottom - sightstart.Z) / in->Frac; + slope = (open.bottom - sightstart.Z) / in->frac; if (slope > bottomslope) bottomslope = slope; } @@ -227,7 +227,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) // check top if (open.top < LINEOPEN_MAX) { - slope = (open.top - sightstart.Z) / in->Frac; + slope = (open.top - sightstart.Z) / in->frac; if (slope < topslope) topslope = slope; } @@ -251,16 +251,16 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) if (portaldir != sector_t::floor && (open.portalflags & SO_TOPBACK) && !(open.portalflags & SO_TOPFRONT)) { - portals.Push({ in->Frac, topslope, bottomslope, sector_t::ceiling, backsec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup }); + portals.Push({ in->frac, topslope, bottomslope, sector_t::ceiling, backsec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup }); } if (portaldir != sector_t::ceiling && (open.portalflags & SO_BOTTOMBACK) && !(open.portalflags & SO_BOTTOMFRONT)) { - portals.Push({ in->Frac, topslope, bottomslope, sector_t::floor, backsec->SkyBoxes[sector_t::floor]->Sector->PortalGroup }); + portals.Push({ in->frac, topslope, bottomslope, sector_t::floor, backsec->SkyBoxes[sector_t::floor]->Sector->PortalGroup }); } } if (lport) { - portals.Push({ in->Frac, topslope, bottomslope, portaldir, lport->mDestination->frontsector->PortalGroup }); + portals.Push({ in->frac, topslope, bottomslope, portaldir, lport->mDestination->frontsector->PortalGroup }); return false; } @@ -278,8 +278,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) sector_t * s=i==1? li->frontsector:li->backsector; double highslope, lowslope; - double topz= topslope * in->Frac + sightstart.Z; - double bottomz= bottomslope * in->Frac + sightstart.Z; + double topz= topslope * in->frac + sightstart.Z; + double bottomz= bottomslope * in->frac + sightstart.Z; for (auto rover : s->e->XFloor.ffloors) { @@ -289,8 +289,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) double ff_bottom = rover->bottom.plane->ZatPoint(trX, trY); double ff_top = rover->top.plane->ZatPoint(trX, trY); - highslope = (ff_top - sightstart.Z) / in->Frac; - lowslope = (ff_bottom - sightstart.Z) / in->Frac; + highslope = (ff_top - sightstart.Z) / in->frac; + lowslope = (ff_bottom - sightstart.Z) / in->frac; if (highslope >= topslope) { @@ -350,8 +350,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) } else lastsector=NULL; // don't need it if there are no 3D-floors - Lastztop = (topslope * in->Frac) + sightstart.Z; - Lastzbottom = (bottomslope * in->Frac) + sightstart.Z; + Lastztop = (topslope * in->frac) + sightstart.Z; + Lastzbottom = (bottomslope * in->frac) + sightstart.Z; return true; // keep going } @@ -375,14 +375,14 @@ bool SightCheck::P_SightCheckLine (line_t *ld) return true; } ld->validcount = validcount; - if (P_PointOnDivlineSidePrecise (ld->V1(), &Trace) == - P_PointOnDivlineSidePrecise (ld->V2(), &Trace)) + if (P_PointOnDivlineSide (ld->v1->fPos(), &Trace) == + P_PointOnDivlineSide (ld->v2->fPos(), &Trace)) { return true; // line isn't crossed } P_MakeDivline (ld, &dl); - if (P_PointOnDivlineSidePrecise (Trace.x, Trace.y, &dl) == - P_PointOnDivlineSidePrecise (Trace.x+Trace.dx, Trace.y+Trace.dy, &dl)) + if (P_PointOnDivlineSide (Trace.x, Trace.y, &dl) == + P_PointOnDivlineSide (Trace.x+Trace.dx, Trace.y+Trace.dy, &dl)) { return true; // line isn't crossed } @@ -514,10 +514,10 @@ bool SightCheck::P_SightTraverseIntercepts () { scan = &intercepts[scanpos]; P_MakeDivline (scan->d.line, &dl); - scan->Frac = P_InterceptVector (&Trace, &dl); - if (scan->Frac < Startfrac) + scan->frac = P_InterceptVector (&Trace, &dl); + if (scan->frac < Startfrac) { - scan->Frac = INT_MAX; + scan->frac = INT_MAX; count--; } } @@ -534,9 +534,9 @@ bool SightCheck::P_SightTraverseIntercepts () for (scanpos = 0; scanpos < intercepts.Size (); scanpos++) { scan = &intercepts[scanpos]; - if (scan->Frac < dist) + if (scan->frac < dist) { - dist = scan->Frac; + dist = scan->frac; in = scan; } } @@ -545,7 +545,7 @@ bool SightCheck::P_SightTraverseIntercepts () { if (!PTR_SightTraverse (in)) return false; // don't bother going farther - in->Frac = INT_MAX; + in->frac = INT_MAX; } } diff --git a/src/p_spec.h b/src/p_spec.h index 236c287900..7cabf0ad3d 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -69,7 +69,6 @@ typedef enum // Factor to scale scrolling effect into mobj-carrying properties = 3/32. // (This is so scrolling floors and objects on them can move at same speed.) -enum { _f_CARRYFACTOR = (3*FRACUNIT >> 5) }; const double CARRYFACTOR = 3 / 32.; // Define values for map objects diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 9add918503..fdea7747ba 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -291,7 +291,7 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques // which wasn't necessarily anywhere near the switch if it was // facing a big sector (and which wasn't necessarily for the // button just activated, either). - DVector2 pt(side->linedef->V1() + side->linedef->Delta() / 2); + DVector2 pt(side->linedef->v1->fPos() + side->linedef->Delta() / 2); bool playsound; side->SetTexture(texture, Switch->frames[0].Texture); diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 8dba3a7727..40ae4efedb 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -438,7 +438,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO } else { - double num = (thing->Pos().XY() - line->V1()) | line->Delta(); + double num = (thing->Pos().XY() - line->v1->fPos()) | line->Delta(); if (num <= 0) { pos = 0; @@ -451,7 +451,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO { pos = num / den; } - npos = thing->Pos().XY() - line->V1() - line->Delta() * pos; + npos = thing->Pos().XY() - line->v1->fPos() - line->Delta() * pos; } // Get the angle between the two linedefs, for rotating @@ -476,7 +476,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO p.Y = npos.Y*c + npos.X*s; // Interpolate position across the exit linedef - p += l->V1() + pos*l->Delta(); + p += l->v1->fPos() + pos*l->Delta(); // Whether this is a player, and if so, a pointer to its player_t. // Voodoo dolls are excluded by making sure thing->player->mo==thing. diff --git a/src/p_trace.cpp b/src/p_trace.cpp index a6b46f32d0..b5346d96d1 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -359,7 +359,7 @@ bool FTraceInfo::LineCheck(intercept_t *in) int lineside; sector_t *entersector; - double dist = MaxDist * in->Frac; + double dist = MaxDist * in->frac; DVector3 hit = Start + Vec * dist; double ff, fc, bf = 0, bc = 0; @@ -468,7 +468,7 @@ bool FTraceInfo::LineCheck(intercept_t *in) { if (entersector == NULL || (hit.Z >= bf && hit.Z <= bc)) { - int res = EnterLinePortal(in->d.line, in->Frac); + int res = EnterLinePortal(in->d.line, in->frac); if (res != -1) { aimdir = INT_MAX; // flag for ending the traverse @@ -610,7 +610,7 @@ cont: Results->HitPos = hit; SetSourcePosition(); Results->Distance = dist; - Results->Fraction = in->Frac; + Results->Fraction = in->frac; Results->Line = in->d.line; Results->Side = lineside; } @@ -648,7 +648,7 @@ cont: bool FTraceInfo::ThingCheck(intercept_t *in) { - double dist = MaxDist * in->Frac; + double dist = MaxDist * in->frac; DVector3 hit = Start + Vec * dist; if (hit.Z > in->d.thing->Top()) @@ -660,7 +660,7 @@ bool FTraceInfo::ThingCheck(intercept_t *in) dist = (in->d.thing->Top() - Start.Z) / Vec.Z; if (dist > MaxDist) return true; - in->Frac = dist / MaxDist; + in->frac = dist / MaxDist; hit = Start + Vec * dist; @@ -675,7 +675,7 @@ bool FTraceInfo::ThingCheck(intercept_t *in) // Does it hit the bottom of the actor? dist = (in->d.thing->Z() - Start.Z) / Vec.Z; if (dist > MaxDist) return true; - in->Frac = dist / MaxDist; + in->frac = dist / MaxDist; hit = Start + Vec * dist; @@ -731,7 +731,7 @@ cont1: Results->HitPos = hit; SetSourcePosition(); Results->Distance = dist; - Results->Fraction = in->Frac; + Results->Fraction = in->frac; Results->Actor = in->d.thing; if (TraceCallback != NULL) @@ -785,7 +785,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) } // We have something closer in the storage for portal subtraces. - if (TempResults->HitType != TRACE_HitNone && in->Frac > TempResults->Fraction) + if (TempResults->HitType != TRACE_HitNone && in->frac > TempResults->Fraction) { break; } diff --git a/src/po_man.cpp b/src/po_man.cpp index 04798dc496..d21141c358 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -1216,14 +1216,14 @@ void FPolyObj::LinkPolyobj () vertex_t *vt; vt = Sidedefs[i]->linedef->v1; - Bounds.AddToBox(vt->fixX(), vt->fixY()); + Bounds.AddToBox(vt->fPos()); vt = Sidedefs[i]->linedef->v2; - Bounds.AddToBox(vt->fixX(), vt->fixY()); + Bounds.AddToBox(vt->fPos()); } - bbox[BOXRIGHT] = GetBlockX(FIXED2DBL(Bounds.Right())); - bbox[BOXLEFT] = GetBlockX(FIXED2DBL(Bounds.Left())); - bbox[BOXTOP] = GetBlockY(FIXED2DBL(Bounds.Top())); - bbox[BOXBOTTOM] = GetBlockY(FIXED2DBL(Bounds.Bottom())); + bbox[BOXRIGHT] = GetBlockX(Bounds.Right()); + bbox[BOXLEFT] = GetBlockX(Bounds.Left()); + bbox[BOXTOP] = GetBlockY(Bounds.Top()); + bbox[BOXBOTTOM] = GetBlockY(Bounds.Bottom()); // add the polyobj to each blockmap section for(int j = bbox[BOXBOTTOM]*bmapwidth; j <= bbox[BOXTOP]*bmapwidth; j += bmapwidth) diff --git a/src/portal.cpp b/src/portal.cpp index c56a790989..b8e0f80e5d 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -163,19 +163,19 @@ void FLinePortalTraverse::AddLineIntercepts(int bx, int by) for (unsigned i = 0; ivalidcount == validcount) continue; // already processed - if (P_PointOnDivlineSidePrecise (ld->v1->fixX(), ld->v1->fixY(), &trace) == - P_PointOnDivlineSidePrecise (ld->v2->fixX(), ld->v2->fixY(), &trace)) + if (P_PointOnDivlineSide (ld->v1->fPos(), &trace) == + P_PointOnDivlineSide (ld->v2->fPos(), &trace)) { continue; // line isn't crossed } P_MakeDivline (ld, &dl); - if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &dl) != 0 || - P_PointOnDivlineSidePrecise (trace.x+trace.dx, trace.y+trace.dy, &dl) != 1) + if (P_PointOnDivlineSide(trace.x, trace.y, &dl) != 0 || + P_PointOnDivlineSide(trace.x + trace.dx, trace.y + trace.dy, &dl) != 1) { continue; // line isn't crossed from the front side } @@ -183,7 +183,7 @@ void FLinePortalTraverse::AddLineIntercepts(int bx, int by) // hit the line P_MakeDivline(ld, &dl); frac = P_InterceptVector(&trace, &dl); - if (frac < 0 || frac > FRACUNIT) continue; // behind source + if (frac < 0 || frac > 1.) continue; // behind source intercept_t newintercept; @@ -252,8 +252,8 @@ static void SetRotation(FLinePortal *port) line_t *dst = port->mDestination; line_t *line = port->mOrigin; DAngle angle = dst->Delta().Angle() - line->Delta().Angle() + 180.; - port->mSinRot = FLOAT2FIXED(angle.Sin()); - port->mCosRot = FLOAT2FIXED(angle.Cos()); + port->mSinRot = sindeg(angle.Degrees); // Here precision matters so use the slower but more precise versions. + port->mCosRot = cosdeg(angle.Degrees); port->mAngleDiff = angle; } } @@ -500,26 +500,22 @@ void P_ClearPortals() } -inline int P_PointOnLineSideExplicit (fixed_t x, fixed_t y, fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2) -{ - return DMulScale32 (y-y1, x2-x1, x1-x, y2-y1) > 0; -} - //============================================================================ // // check if this line is between portal and the viewer. clip away if it is. // //============================================================================ -inline int P_GetLineSide(fixed_t x, fixed_t y, const line_t *line) +inline int P_GetLineSide(const DVector2 &pos, const line_t *line) { - return DMulScale32(y - line->v1->fixY(), line->fixDx(), line->v1->fixX() - x, line->fixDy()); + double v = (pos.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pos.X) * line->Delta().Y; + return v < -1. / 65536. ? -1 : v > 1. / 65536 ? 1 : 0; } -bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial, bool samebehind) +bool P_ClipLineToPortal(line_t* line, line_t* portal, DVector2 view, bool partial, bool samebehind) { - int behind1 = P_GetLineSide(line->v1->fixX(), line->v1->fixY(), portal); - int behind2 = P_GetLineSide(line->v2->fixX(), line->v2->fixY(), portal); + int behind1 = P_GetLineSide(line->v1->fPos(), portal); + int behind2 = P_GetLineSide(line->v2->fPos(), portal); if (behind1 == 0 && behind2 == 0) { @@ -543,14 +539,12 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie else { // The line intersects with the portal straight, so we need to do another check to see how both ends of the portal lie in relation to the viewer. - int viewside = P_PointOnLineSidePrecise(viewx, viewy, line); - int p1side = P_GetLineSide(portal->v1->fixX(), portal->v1->fixY(), line); - int p2side = P_GetLineSide(portal->v2->fixX(), portal->v2->fixY(), line); - // Do the same handling of points on the portal straight than above. + int viewside = P_GetLineSide(view, line); + int p1side = P_GetLineSide(portal->v1->fPos(), line); + int p2side = P_GetLineSide(portal->v2->fPos(), line); + // Do the same handling of points on the portal straight as above. if (p1side == 0) p1side = p2side; else if (p2side == 0) p2side = p1side; - p1side = p1side > 0; - p2side = p2side > 0; // If the portal is on the other side of the line than the viewpoint, there is no possibility to see this line inside the portal. return (p1side == p2side && viewside != p1side); } @@ -562,22 +556,22 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie // //============================================================================ -void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y) +void P_TranslatePortalXY(line_t* src, double& x, double& y) { if (!src) return; FLinePortal *port = src->getPortal(); if (!port) return; // offsets from line - fixed_t nposx = x - src->v1->fixX(); - fixed_t nposy = y - src->v1->fixY(); + double nposx = x - src->v1->fX(); + double nposy = y - src->v1->fY(); // Rotate position along normal to match exit linedef - fixed_t tx = FixedMul(nposx, port->mCosRot) - FixedMul(nposy, port->mSinRot); - fixed_t ty = FixedMul(nposy, port->mCosRot) + FixedMul(nposx, port->mSinRot); + double tx = nposx * port->mCosRot - nposy * port->mSinRot; + double ty = nposy * port->mCosRot + nposx * port->mSinRot; - tx += port->mDestination->v2->fixX(); - ty += port->mDestination->v2->fixY(); + tx += port->mDestination->v2->fX(); + ty += port->mDestination->v2->fY(); x = tx; y = ty; @@ -589,16 +583,16 @@ void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y) // //============================================================================ -void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy) +void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely) { if (!src) return; FLinePortal *port = src->getPortal(); if (!port) return; - fixed_t orig_velx = vx; - fixed_t orig_vely = vy; - vx = FixedMul(orig_velx, port->mCosRot) - FixedMul(orig_vely, port->mSinRot); - vy = FixedMul(orig_vely, port->mCosRot) + FixedMul(orig_velx, port->mSinRot); + double orig_velx = velx; + double orig_vely = vely; + velx = orig_velx * port->mCosRot - orig_vely * port->mSinRot; + vely = orig_vely * port->mCosRot - orig_velx * port->mSinRot; } //============================================================================ @@ -621,7 +615,7 @@ void P_TranslatePortalAngle(line_t* src, DAngle& angle) // //============================================================================ -void P_TranslatePortalZ(line_t* src, fixed_t& z) +void P_TranslatePortalZ(line_t* src, double& z) { // args[2] = 0 - no adjustment // args[2] = 1 - adjust by floor difference @@ -632,11 +626,11 @@ void P_TranslatePortalZ(line_t* src, fixed_t& z) switch (src->getPortalAlignment()) { case PORG_FLOOR: - z = z - src->frontsector->floorplane.ZatPoint(src->v1->fixX(), src->v1->fixY()) + dst->frontsector->floorplane.ZatPoint(dst->v2->fixX(), dst->v2->fixY()); + z = z - src->frontsector->floorplane.ZatPoint(src->v1) + dst->frontsector->floorplane.ZatPoint(dst->v2); return; case PORG_CEILING: - z = z - src->frontsector->ceilingplane.ZatPoint(src->v1->fixX(), src->v1->fixY()) + dst->frontsector->ceilingplane.ZatPoint(dst->v2->fixX(), dst->v2->fixY()); + z = z - src->frontsector->ceilingplane.ZatPoint(src->v1) + dst->frontsector->ceilingplane.ZatPoint(dst->v2); return; default: @@ -644,37 +638,6 @@ void P_TranslatePortalZ(line_t* src, fixed_t& z) } } -//============================================================================ -// -// calculate shortest distance from a point (x,y) to a linedef -// -//============================================================================ - -fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y) -{ - angle_t angle = R_PointToAngle2(0, 0, line->fixDx(), line->fixDy()); - angle += ANGLE_180; - - fixed_t dx = line->v1->fixX() - x; - fixed_t dy = line->v1->fixY() - y; - - fixed_t s = finesine[angle>>ANGLETOFINESHIFT]; - fixed_t c = finecosine[angle>>ANGLETOFINESHIFT]; - - fixed_t d2x = FixedMul(dx, c) - FixedMul(dy, s); - - return abs(d2x); -} - -void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy) -{ - double _vx = FIXED2DBL(vx); - double _vy = FIXED2DBL(vy); - double len = g_sqrt(_vx*_vx+_vy*_vy); - vx = FLOAT2FIXED(_vx/len); - vy = FLOAT2FIXED(_vy/len); -} - //============================================================================ // // P_GetOffsetPosition @@ -684,17 +647,17 @@ void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy) // //============================================================================ -fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy) +DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy) { - fixedvec2 dest = { x + dx, y + dy }; + DVector2 dest(x + dx, y + dy); if (PortalBlockmap.containsLines) { - fixed_t actx = x, acty = y; + double actx = x, acty = y; // Try some easily discoverable early-out first. If we know that the trace cannot possibly find a portal, this saves us from calling the traverser completely for vast parts of the map. - if (dx < 128 * FRACUNIT && dy < 128 * FRACUNIT) + if (dx < 128 && dy < 128) { - int blockx = GetBlockX(FIXED2DBL(actx)); - int blocky = GetBlockY(FIXED2DBL(acty)); + int blockx = GetBlockX(actx); + int blocky = GetBlockY(acty); if (blockx < 0 || blocky < 0 || blockx >= bmapwidth || blocky >= bmapheight || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest; } @@ -715,26 +678,24 @@ fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy) // Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence. if (port->mFlags & PORTF_INTERACTIVE) { - fixedvec2 hit = it._f_InterceptPoint(in); + DVector2 hit = it.InterceptPoint(in); if (port->mType == PORTT_LINKED) { // optimized handling for linked portals where we only need to add an offset. - hit.x += FLOAT2FIXED(port->mDisplacement.X); - hit.y += FLOAT2FIXED(port->mDisplacement.Y); - dest.x += FLOAT2FIXED(port->mDisplacement.X); - dest.y += FLOAT2FIXED(port->mDisplacement.Y); + hit += port->mDisplacement; + dest += port->mDisplacement; } else { // interactive ones are more complex because the vector may be rotated. // Note: There is no z-translation here, there's just too much code in the engine that wouldn't be able to handle interactive portals with a height difference. - P_TranslatePortalXY(line, hit.x, hit.y); - P_TranslatePortalXY(line, dest.x, dest.y); + P_TranslatePortalXY(line, hit.X, hit.Y); + P_TranslatePortalXY(line, dest.X, dest.Y); } // update the fields, end this trace and restart from the new position - dx = dest.x - hit.x; - dy = dest.y - hit.y; + dx = dest.X - hit.X; + dy = dest.Y - hit.Y; repeat = true; } @@ -814,13 +775,12 @@ static void AddDisplacementForPortal(AStackPoint *portal) FDisplacement & disp = Displacements(thisgroup, othergroup); if (!disp.isSet) { - disp.pos.x = FLOAT2FIXED(portal->Scale.X); - disp.pos.y = FLOAT2FIXED(portal->Scale.Y); + disp.pos = portal->Scale; disp.isSet = true; } else { - if (disp.pos.x != FLOAT2FIXED(portal->Scale.X) || disp.pos.y != FLOAT2FIXED(portal->Scale.Y)) + if (disp.pos != portal->Scale) { Printf("Portal between sectors %d and %d has displacement mismatch and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum); portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL; @@ -850,13 +810,12 @@ static void AddDisplacementForPortal(FLinePortal *portal) FDisplacement & disp = Displacements(thisgroup, othergroup); if (!disp.isSet) { - disp.pos.x = FLOAT2FIXED(portal->mDisplacement.X); - disp.pos.y = FLOAT2FIXED(portal->mDisplacement.Y); + disp.pos = portal->mDisplacement; disp.isSet = true; } else { - if (disp.pos.x != FLOAT2FIXED(portal->mDisplacement.X) || disp.pos.y != FLOAT2FIXED(portal->mDisplacement.Y)) + if (disp.pos != portal->mDisplacement) { Printf("Portal between lines %d and %d has displacement mismatch\n", int(portal->mOrigin - lines), int(portal->mDestination - lines)); portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; @@ -897,7 +856,7 @@ static bool ConnectGroups() FDisplacement &dispxz = Displacements(x, z); if (dispxz.isSet) { - if (dispxy.pos.x + dispyz.pos.x != dispxz.pos.x || dispxy.pos.y + dispyz.pos.y != dispxz.pos.y) + if (dispxy.pos.X + dispyz.pos.X != dispxz.pos.X || dispxy.pos.Y + dispyz.pos.Y != dispxz.pos.Y) { bogus = true; } @@ -1033,7 +992,7 @@ void P_CreateLinkedPortals() FDisplacement &dispxy = Displacements(x, y); FDisplacement &dispyx = Displacements(y, x); if (dispxy.isSet && dispyx.isSet && - (dispxy.pos.x != -dispyx.pos.x || dispxy.pos.y != -dispyx.pos.y)) + (dispxy.pos.X != -dispyx.pos.X || dispxy.pos.Y != -dispyx.pos.Y)) { int sec1 = -1, sec2 = -1; for (int i = 0; i < numsectors && (sec1 == -1 || sec2 == -1); i++) @@ -1119,7 +1078,7 @@ void P_CreateLinkedPortals() if (!(actor->flags & MF_NOBLOCKMAP)) { FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); - P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->_f_Pos(), actor->_f_Top(), actor->_f_radius(), check); + P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->Pos(), actor->Top(), actor->radius, check); if (check.Size() > 0) { actor->UnlinkFromWorld(); @@ -1138,7 +1097,7 @@ void P_CreateLinkedPortals() // //============================================================================ -bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t upperz, fixed_t checkradius, FPortalGroupArray &out) +bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out) { // Keep this temporary work stuff static. This function can never be called recursively // and this would have to be reallocated for each call otherwise. @@ -1172,7 +1131,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t FDisplacement &disp = Displacements(thisgroup, othergroup); if (!disp.isSet) continue; // no connection. - FBoundingBox box(position.x + disp.pos.x, position.y + disp.pos.y, checkradius); + FBoundingBox box(position.X + disp.pos.X, position.Y + disp.pos.Y, checkradius); if (!box.inRange(ld) || box.BoxOnLineSide(linkedPortals[i]->mOrigin) != -1) continue; // not touched foundPortals.Push(linkedPortals[i]); @@ -1197,29 +1156,25 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t } if (out.method != FPortalGroupArray::PGA_NoSectorPortals) { - sector_t *sec = P_PointInSector(position.x, position.y); + sector_t *sec = P_PointInSector(position); sector_t *wsec = sec; - while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > FLOAT2FIXED(wsec->SkyBoxes[sector_t::ceiling]->specialf1)) + while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->SkyBoxes[sector_t::ceiling]->specialf1) { sector_t *othersec = wsec->SkyBoxes[sector_t::ceiling]->Sector; - fixedvec2 pos = Displacements._f_getOffset(startgroup, othersec->PortalGroup); - fixed_t dx = position.x + pos.x; - fixed_t dy = position.y + pos.y; + DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position; processMask.setBit(othersec->PortalGroup); out.Add(othersec->PortalGroup | FPortalGroupArray::UPPER); - wsec = P_PointInSector(dx, dy); // get upper sector at the exact spot we want to check and repeat + wsec = P_PointInSector(pos); // get upper sector at the exact spot we want to check and repeat retval = true; } wsec = sec; - while (!wsec->PortalBlocksMovement(sector_t::floor) && position.z < FLOAT2FIXED(wsec->SkyBoxes[sector_t::floor]->specialf1)) + while (!wsec->PortalBlocksMovement(sector_t::floor) && position.Z < wsec->SkyBoxes[sector_t::floor]->specialf1) { sector_t *othersec = wsec->SkyBoxes[sector_t::floor]->Sector; - fixedvec2 pos = Displacements._f_getOffset(startgroup, othersec->PortalGroup); - fixed_t dx = position.x + pos.x; - fixed_t dy = position.y + pos.y; + DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position; processMask.setBit(othersec->PortalGroup | FPortalGroupArray::LOWER); out.Add(othersec->PortalGroup); - wsec = P_PointInSector(dx, dy); // get lower sector at the exact spot we want to check and repeat + wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat retval = true; } if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals) @@ -1229,8 +1184,8 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t int thisgroup = startgroup; for (unsigned i = 0; i < groupsToCheck.Size();i++) { - fixedvec2 disp = Displacements._f_getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT); - FBoundingBox box(position.x + disp.x, position.y + disp.y, checkradius); + DVector2 disp = Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT); + FBoundingBox box(position.X + disp.X, position.Y + disp.Y, checkradius); FBlockLinesIterator it(box); line_t *ld; while ((ld = it.Next())) @@ -1245,7 +1200,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t sector_t *sec = s ? ld->backsector : ld->frontsector; if (sec && !(sec->PortalBlocksMovement(sector_t::ceiling))) { - if (FLOAT2FIXED(sec->SkyBoxes[sector_t::ceiling]->specialf1) < upperz) + if (sec->SkyBoxes[sector_t::ceiling]->specialf1 < upperz) { int grp = sec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup; if (!(processMask.getBit(grp))) @@ -1264,7 +1219,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t sector_t *sec = s ? ld->backsector : ld->frontsector; if (sec && !(sec->PortalBlocksMovement(sector_t::floor))) { - if (FLOAT2FIXED(sec->SkyBoxes[sector_t::floor]->specialf1) > position.z) + if (sec->SkyBoxes[sector_t::floor]->specialf1 > position.Z) { int grp = sec->SkyBoxes[sector_t::floor]->Sector->PortalGroup; if (!(processMask.getBit(grp))) @@ -1297,7 +1252,7 @@ CCMD(dumplinktable) for (int y = 1; y < Displacements.size; y++) { FDisplacement &disp = Displacements(x, y); - Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, disp.pos.x >> FRACBITS, disp.pos.y >> FRACBITS); + Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y)); } Printf("\n"); } diff --git a/src/portal.h b/src/portal.h index 935d6cf6c5..2868521bcb 100644 --- a/src/portal.h +++ b/src/portal.h @@ -26,7 +26,7 @@ struct FPortalGroupArray; struct FDisplacement { - fixedvec2 pos; + DVector2 pos; bool isSet; BYTE indirect; // just for illustration. @@ -54,16 +54,6 @@ struct FDisplacementTable return data[x + size*y]; } - fixedvec2 _f_getOffset(int x, int y) const - { - if (x == y) - { - fixedvec2 nulvec = { 0,0 }; - return nulvec; // shortcut for the most common case - } - return data[x + size*y].pos; - } - DVector2 getOffset(int x, int y) const { if (x == y) @@ -71,8 +61,7 @@ struct FDisplacementTable DVector2 nulvec = { 0,0 }; return nulvec; // shortcut for the most common case } - fixedvec2 &p = data[x + size*y].pos; - return{ FIXED2DBL(p.x), FIXED2DBL(p.y) }; + return data[x + size*y].pos; } }; @@ -191,8 +180,8 @@ struct FLinePortal BYTE mDefFlags; BYTE mAlign; DAngle mAngleDiff; - fixed_t mSinRot; - fixed_t mCosRot; + double mSinRot; + double mCosRot; }; extern TArray linePortals; @@ -202,7 +191,7 @@ void P_SpawnLinePortal(line_t* line); void P_FinalizePortals(); bool P_ChangePortal(line_t *ln, int thisid, int destid); void P_CreateLinkedPortals(); -bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t upperz, fixed_t checkradius, FPortalGroupArray &out); +bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out); void P_CollectLinkedPortals(); inline int P_NumPortalGroups() { @@ -211,43 +200,12 @@ inline int P_NumPortalGroups() /* code ported from prototype */ -bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial = true, bool samebehind = true); -void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y); -inline void P_TranslatePortalXY(line_t* src, double& vx, double& vy) -{ - fixed_t x = FLOAT2FIXED(vx); - fixed_t y = FLOAT2FIXED(vy); - P_TranslatePortalXY(src, x, y); - vx = FIXED2DBL(x); - vx = FIXED2DBL(y); -} -void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy); -inline void P_TranslatePortalVXVY(line_t* src, double& vx, double& vy) -{ - fixed_t x = FLOAT2FIXED(vx); - fixed_t y = FLOAT2FIXED(vy); - P_TranslatePortalVXVY(src, x, y); - vx = FIXED2DBL(x); - vx = FIXED2DBL(y); -} +bool P_ClipLineToPortal(line_t* line, line_t* portal, DVector2 view, bool partial = true, bool samebehind = true); +void P_TranslatePortalXY(line_t* src, double& vx, double& vy); +void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely); void P_TranslatePortalAngle(line_t* src, DAngle& angle); - -void P_TranslatePortalZ(line_t* src, fixed_t& z); -inline void P_TranslatePortalZ(line_t* src, double& vz) -{ - fixed_t x = FLOAT2FIXED(vz); - P_TranslatePortalZ(src, x); - vz = FIXED2DBL(x); -} -void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy); -fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y); -fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy); - -inline DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy) -{ - fixedvec2 v = P_GetOffsetPosition(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(dx), FLOAT2FIXED(dy)); - return{ FIXED2DBL(v.x), FIXED2DBL(v.y) }; -} +void P_TranslatePortalZ(line_t* src, double& vz); +DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy); #endif \ No newline at end of file diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 9761b2264b..4f6c2509ff 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -555,7 +555,7 @@ void R_AddLine (seg_t *line) // reject lines that aren't seen from the portal (if any) // [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes. - if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, viewx, viewy)) + if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, DVector2(FIXED2DBL(viewx), FIXED2DBL(viewy)))) return; vertex_t *v1, *v2; diff --git a/src/r_defs.h b/src/r_defs.h index b09c0f3548..750f96cd09 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -389,16 +389,6 @@ public: return ic < 0 ? d : -d; } - fixed_t ZatPoint(const fixedvec2 &spot) const - { - return FixedMul(ic, -d - DMulScale16(a, spot.x, b, spot.y)); - } - - fixed_t ZatPoint(const fixedvec3 &spot) const - { - return FixedMul(ic, -d - DMulScale16(a, spot.x, b, spot.y)); - } - // Returns the value of z at (x,y) fixed_t ZatPoint (fixed_t x, fixed_t y) const { @@ -489,11 +479,6 @@ public: return -TMulScale16 (a, x, y, b, z, c); } - fixed_t PointToDist(fixedvec2 xy, fixed_t z) const - { - return -TMulScale16(a, xy.x, xy.y, b, z, c); - } - fixed_t PointToDist (const vertex_t *v, fixed_t z) const { return -TMulScale16 (a, v->fixX(), b, v->fixY(), z, c); @@ -714,7 +699,7 @@ struct sector_t void AdjustFloorClip () const; void SetColor(int r, int g, int b, int desat); void SetFade(int r, int g, int b); - void ClosestPoint(fixed_t x, fixed_t y, fixed_t &ox, fixed_t &oy) const; + void ClosestPoint(const DVector2 &pos, DVector2 &out) const; int GetFloorLight () const; int GetCeilingLight () const; sector_t *GetHeightSec() const; @@ -1135,11 +1120,6 @@ struct sector_t int validcount; // if == validcount, already checked AActor* thinglist; // list of mobjs in sector - fixedvec2 _f_centerspot() const - { - return{ FLOAT2FIXED(centerspot.X), FLOAT2FIXED(centerspot.Y) }; - } - // killough 8/28/98: friction is a sector property, not an mobj property. // these fields used to be in AActor, but presented performance problems // when processed as mobj properties. Fix is to make them sector properties. @@ -1477,31 +1457,11 @@ public: unsigned portalindex; TObjPtr skybox; - DVector2 V1() const - { - return v1->fPos(); - } - - DVector2 V2() const - { - return v1->fPos(); - } - DVector2 Delta() const { return{ FIXED2DBL(dx), FIXED2DBL(dy) }; } - fixed_t fixDx() const - { - return dx; - } - - fixed_t fixDy() const - { - return dy; - } - void setDelta(fixed_t x, fixed_t y) { dx = x; @@ -1705,20 +1665,16 @@ struct visstyle_t // not the same as R_PointInSubsector // //---------------------------------------------------------------------------------- -subsector_t *P_PointInSubsector(fixed_t x, fixed_t y); -inline sector_t *P_PointInSector(fixed_t x, fixed_t y) -{ - return P_PointInSubsector(x, y)->sector; -} +subsector_t *P_PointInSubsector(double x, double y); inline sector_t *P_PointInSector(const DVector2 &pos) { - return P_PointInSubsector(FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y))->sector; + return P_PointInSubsector(pos.X, pos.Y)->sector; } inline sector_t *P_PointInSector(double X, double Y) { - return P_PointInSubsector(FLOAT2FIXED(X), FLOAT2FIXED(Y))->sector; + return P_PointInSubsector(X, Y)->sector; } inline DVector3 AActor::PosRelative(int portalgroup) const @@ -1757,10 +1713,10 @@ inline void AActor::ClearInterpolation() inline bool FBoundingBox::inRange(const line_t *ld) const { - return FIXED2DBL(Left()) < ld->bbox[BOXRIGHT] && - FIXED2DBL(Right()) > ld->bbox[BOXLEFT] && - FIXED2DBL(Top()) > ld->bbox[BOXBOTTOM] && - FIXED2DBL(Bottom()) < ld->bbox[BOXTOP]; + return Left() < ld->bbox[BOXRIGHT] && + Right() > ld->bbox[BOXLEFT] && + Top() > ld->bbox[BOXBOTTOM] && + Bottom() < ld->bbox[BOXTOP]; } diff --git a/src/r_main.cpp b/src/r_main.cpp index 599eb738e3..80e2eb8591 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -733,10 +733,14 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) } else { - P_TranslatePortalXY(pds->src, viewx, viewy); - P_TranslatePortalZ(pds->src, viewz); + DVector3 view(FIXED2DBL(viewx), FIXED2DBL(viewy), FIXED2DBL(viewz)); DAngle va = ANGLE2DBL(viewangle); + P_TranslatePortalXY(pds->src, view.X, view.Y); + P_TranslatePortalZ(pds->src, view.Z); P_TranslatePortalAngle(pds->src, va); + viewx = FLOAT2FIXED(view.X); + viewy = FLOAT2FIXED(view.Y); + viewz = FLOAT2FIXED(view.Z); viewangle = va.BAMs(); } diff --git a/src/r_things.cpp b/src/r_things.cpp index 96d38e54d8..0e4e717f6e 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -374,7 +374,7 @@ static inline bool R_ClipSpriteColumnWithPortals(fixed_t x, fixed_t y, vissprite line_t* line = seg->curline->linedef; // don't clip if the sprite is in front of the portal - if (!P_PointOnLineSidePrecise(x, y, line)) + if (!P_PointOnLineSidePrecise(FIXED2DBL(x), FIXED2DBL(y), line)) continue; // now if current column is covered by this drawseg, we clip it away diff --git a/src/r_utility.cpp b/src/r_utility.cpp index f6792d1b15..169463752f 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -57,6 +57,7 @@ #include "r_utility.h" #include "d_player.h" #include "p_local.h" +#include "p_maputl.h" #include "math/cmath.h" @@ -652,9 +653,9 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie } else { - fixedvec2 disp = Displacements._f_getOffset(oldgroup, newgroup); - viewx = iview->oviewx + FixedMul(frac, iview->nviewx - iview->oviewx - disp.x); - viewy = iview->oviewy + FixedMul(frac, iview->nviewy - iview->oviewy - disp.y); + DVector2 disp = Displacements.getOffset(oldgroup, newgroup); + viewx = iview->oviewx + FixedMul(frac, iview->nviewx - iview->oviewx - FLOAT2FIXED(disp.X)); + viewy = iview->oviewy + FixedMul(frac, iview->nviewy - iview->oviewy - FLOAT2FIXED(disp.Y)); viewz = iview->oviewz + FixedMul(frac, iview->nviewz - iview->oviewz); } if (player != NULL && diff --git a/src/r_utility.h b/src/r_utility.h index 7df9c3606d..f37fc01ee3 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -55,6 +55,10 @@ inline int R_PointOnSide (fixed_t x, fixed_t y, const node_t *node) { return DMulScale32 (y-node->y, node->dx, node->x-x, node->dy) > 0; } +inline int R_PointOnSide(double x, double y, const node_t *node) +{ + return DMulScale32(FLOAT2FIXED(y) - node->y, node->dx, node->x - FLOAT2FIXED(x), node->dy) > 0; +} inline int R_PointOnSide(const DVector2 &pos, const node_t *node) { return DMulScale32(FLOAT2FIXED(pos.Y) - node->y, node->dx, node->x - FLOAT2FIXED(pos.X), node->dy) > 0; diff --git a/src/s_sound.cpp b/src/s_sound.cpp index e30e438525..c7ac7cebc5 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -104,8 +104,8 @@ static void S_ActivatePlayList(bool goBack); static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel); static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, const FPolyObj *poly, const float pt[3], int channel, int chanflags, FVector3 *pos, FVector3 *vel); -static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z); -static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z); +static void CalcSectorSoundOrg(const DVector3 &listenpos, const sector_t *sec, int channum, FVector3 &res); +static void CalcPolyobjSoundOrg(const DVector3 &listenpos, const FPolyObj *poly, FVector3 &res); static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly, const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo *rolloff); static void S_SetListener(SoundListener &listener, AActor *listenactor); @@ -658,27 +658,30 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, { if (pos != NULL) { - fixed_t x, y, z; + DVector3 listenpos; + int pgroup; + AActor *listener = players[consoleplayer].camera; - if (players[consoleplayer].camera != NULL) + if (listener != NULL) { - FVector3 v = players[consoleplayer].camera->SoundPos(); - x = FLOAT2FIXED(v.X); - y = FLOAT2FIXED(v.Y); - z = FLOAT2FIXED(v.Z); + listenpos = listener->Pos(); + pgroup = listener->Sector->PortalGroup; } else { - z = y = x = 0; + listenpos.Zero(); + pgroup = 0; } // [BL] Moved this case out of the switch statement to make code easier // on static analysis. if(type == SOURCE_Unattached) - { - pos->X = pt[0]; - pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : FIXED2FLOAT(y); - pos->Z = pt[2]; + { + sector_t *sec = P_PointInSector(pt[0], pt[2]); + DVector2 disp = Displacements.getOffset(pgroup, sec->PortalGroup); + pos->X = pt[0] + (float)disp.X; + pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : (float)listenpos.Z; + pos->Z = pt[2] + (float)disp.Y; } else { @@ -692,10 +695,9 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, //assert(actor != NULL); if (actor != NULL) { - FVector3 v = actor->SoundPos(); - x = FLOAT2FIXED(v.X); - y = FLOAT2FIXED(v.Y); - z = FLOAT2FIXED(v.Z); + DVector2 disp = Displacements.getOffset(pgroup, actor->Sector->PortalGroup); + DVector3 posi = actor->Pos() + disp; + *pos = { (float)posi.X, (float)posi.Z, (float)posi.Y }; } break; @@ -703,14 +705,19 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, assert(sector != NULL); if (sector != NULL) { + DVector2 disp = Displacements.getOffset(pgroup, sector->PortalGroup); if (chanflags & CHAN_AREA) { - CalcSectorSoundOrg(sector, channum, &x, &z, &y); + // listener must be reversely offset to calculate the proper sound origin. + CalcSectorSoundOrg(listenpos-disp, sector, channum, *pos); + pos->X += (float)disp.X; + pos->Z += (float)disp.Y; } else { - x = sector->_f_centerspot().x; - z = sector->_f_centerspot().y; + + pos->X = (float)(sector->centerspot.X + disp.X); + pos->Z = (float)(sector->centerspot.Y + disp.Y); chanflags |= CHAN_LISTENERZ; } } @@ -718,17 +725,20 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, case SOURCE_Polyobj: assert(poly != NULL); - CalcPolyobjSoundOrg(poly, &x, &z, &y); + if (poly != NULL) + { + DVector2 disp = Displacements.getOffset(pgroup, poly->CenterSubsector->sector->PortalGroup); + CalcPolyobjSoundOrg(listenpos-disp, poly, *pos); + pos->X += (float)disp.X; + pos->Z += (float)disp.Y; + } break; } if ((chanflags & CHAN_LISTENERZ) && players[consoleplayer].camera != NULL) { - y = players[consoleplayer].camera != NULL ? FLOAT2FIXED(players[consoleplayer].camera->SoundPos().Z) : 0; + pos->Y = (float)listenpos.Z; } - pos->X = FIXED2FLOAT(x); - pos->Y = FIXED2FLOAT(y); - pos->Z = FIXED2FLOAT(z); } } if (vel != NULL) @@ -757,42 +767,44 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, // //========================================================================== -static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z) +static void CalcSectorSoundOrg(const DVector3 &listenpos, const sector_t *sec, int channum, FVector3 &pos) { if (!(i_compatflags & COMPATF_SECTORSOUNDS)) { // Are we inside the sector? If yes, the closest point is the one we're on. - if (P_PointInSector(*x, *y) == sec) + if (P_PointInSector(pos.X, pos.Y) == sec) { - FVector3 p = players[consoleplayer].camera->SoundPos(); - *x = FLOAT2FIXED(p.X); - *y = FLOAT2FIXED(p.Y); + pos.X = (float)listenpos.X; + pos.Z = (float)listenpos.Y; } else { // Find the closest point on the sector's boundary lines and use // that as the perceived origin of the sound. - sec->ClosestPoint(*x, *y, *x, *y); + DVector2 xy; + sec->ClosestPoint(listenpos, xy); + pos.X = (float)xy.X; + pos.Z = (float)xy.Y; } } else { - *x = sec->_f_centerspot().x; - *y = sec->_f_centerspot().y; + pos.X = float(sec->centerspot.X); + pos.Z = float(sec->centerspot.Y); } // Set sound vertical position based on channel. if (channum == CHAN_FLOOR) { - *z = MIN(sec->floorplane.ZatPoint(*x, *y), *z); + pos.Y = (float)MIN(sec->floorplane.ZatPoint(listenpos), listenpos.Z); } else if (channum == CHAN_CEILING) { - *z = MAX(sec->ceilingplane.ZatPoint(*x, *y), *z); + pos.Y = (float)MAX(sec->ceilingplane.ZatPoint(listenpos), listenpos.Z); } else if (channum == CHAN_INTERIOR) { - *z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y)); + pos.Y = (float)clamp(listenpos.Z, sec->floorplane.ZatPoint(listenpos), sec->ceilingplane.ZatPoint(listenpos)); } } @@ -807,17 +819,17 @@ static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fix // //========================================================================== -static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z) +static void CalcPolyobjSoundOrg(const DVector3 &listenpos, const FPolyObj *poly, FVector3 &pos) { side_t *side; sector_t *sec; - DVector2 pos(FIXED2DBL(*x), FIXED2DBL(*y)); - poly->ClosestPoint(pos, pos, &side); - *x = FLOAT2FIXED(pos.X); - *y = FLOAT2FIXED(pos.Y); + DVector2 ppos; + poly->ClosestPoint(listenpos, ppos, &side); + pos.X = (float)ppos.X; + pos.Z = (float)ppos.Y; sec = side->sector; - *z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y)); + pos.Y = (float)clamp(listenpos.Z, sec->floorplane.ZatPoint(listenpos), sec->ceilingplane.ZatPoint(listenpos)); } //========================================================================== diff --git a/src/vectors.h b/src/vectors.h index e6b512538f..91cf1e9629 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -46,7 +46,7 @@ #include "math/cmath.h" -#define EQUAL_EPSILON (1/65536.f) +#define EQUAL_EPSILON (1/65536.) // make this a local inline function to avoid any dependencies on other headers and not pollute the global namespace namespace pi @@ -493,6 +493,11 @@ struct TVector3 return TVector3(v3.X + v2.X, v3.Y + v2.Y, v3.Z); } + friend TVector3 operator- (const TVector3 &v3, const Vector2 &v2) + { + return TVector3(v3.X - v2.X, v3.Y - v2.Y, v3.Z); + } + friend Vector2 operator+ (const Vector2 &v2, const TVector3 &v3) { return Vector2(v2.X + v3.X, v2.Y + v3.Y); @@ -500,11 +505,6 @@ struct TVector3 // Subtract a 3D vector and a 2D vector. // Discards the Z component of the 3D vector and returns a 2D vector. - friend Vector2 operator- (const TVector3 &v3, const Vector2 &v2) - { - return Vector2(v3.X - v2.X, v3.Y - v2.Y); - } - friend Vector2 operator- (const TVector2 &v2, const TVector3 &v3) { return Vector2(v2.X - v3.X, v2.Y - v3.Y);