Merge branch 'floatcvt' of https://github.com/rheit/zdoom into floatcvt

# Conflicts:
#	src/actor.h
This commit is contained in:
Christoph Oelckers 2016-03-31 21:24:26 +02:00
commit 466c4c75df
36 changed files with 609 additions and 1079 deletions

View file

@ -561,11 +561,7 @@ public:
int Amount; int Amount;
}; };
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); // since we cannot include p_local here... const double MinVel = EQUAL_EPSILON;
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.;
// Map Object definition. // Map Object definition.
class AActor : public DThinker class AActor : public DThinker
@ -752,17 +748,6 @@ public:
return BobSin(FloatBobPhase + level.maptime + ticfrac); 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 // Enter the crash state
void Crash(); void Crash();
@ -850,8 +835,6 @@ public:
return VecToAngle(otherpos - Pos().XY()); 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 DAngle AngleTo(AActor *other, double oxofs, double oyofs, bool absolute = false) const
{ {
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); 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) DVector3 Vec3Offset(double dx, double dy, double dz, bool absolute = false)
{ {
if (absolute) if (absolute)
@ -959,22 +927,14 @@ public:
void ClearInterpolation(); void ClearInterpolation();
void SetOrigin(const fixedvec3 & npos, bool moving)
{
SetOrigin(npos.x, npos.y, npos.z, moving);
}
void Move(const DVector3 &vel) void Move(const DVector3 &vel)
{ {
SetOrigin(Pos() + vel, true); SetOrigin(Pos() + vel, true);
} }
void SetOrigin(double x, double y, double z, bool moving) virtual void SetOrigin(double x, double y, double z, bool moving);
{
SetOrigin(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(z), moving);
}
void SetOrigin(const DVector3 & npos, 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); inline void SetFriendPlayer(player_t *player);
@ -1021,11 +981,6 @@ public:
double floorz, ceilingz; // closest together of contacted secs double floorz, ceilingz; // closest together of contacted secs
double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors. double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors.
inline fixed_t _f_floorz()
{
return FLOAT2FIXED(floorz);
}
struct sector_t *floorsector; struct sector_t *floorsector;
FTextureID floorpic; // contacted sec floorpic FTextureID floorpic; // contacted sec floorpic
int floorterrain; int floorterrain;
@ -1033,15 +988,6 @@ public:
FTextureID ceilingpic; // contacted sec ceilingpic FTextureID ceilingpic; // contacted sec ceilingpic
double radius, Height; // for movement checking 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 double projectilepassheight; // height for clipping projectile movement against this actor
SDWORD tics; // state tic counter SDWORD tics; // state tic counter
@ -1092,10 +1038,6 @@ public:
TObjPtr<AActor> tracer; // Thing being chased/attacked for tracers TObjPtr<AActor> tracer; // Thing being chased/attacked for tracers
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks) TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)
double Floorclip; // value to use for floor clipping double Floorclip; // value to use for floor clipping
fixed_t _f_floorclip()
{
return FLOAT2FIXED(Floorclip);
}
int tid; // thing identifier int tid; // thing identifier
int special; // special int special; // special
@ -1222,7 +1164,6 @@ public:
void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL); void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL);
void UnlinkFromWorld (); void UnlinkFromWorld ();
void AdjustFloorClip (); void AdjustFloorClip ();
virtual void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false);
bool InStateSequence(FState * newstate, FState * basestate); bool InStateSequence(FState * newstate, FState * basestate);
int GetTics(FState * newstate); int GetTics(FState * newstate);
bool SetState (FState *newstate, bool nofunction=false); bool SetState (FState *newstate, bool nofunction=false);
@ -1260,14 +1201,6 @@ public:
{ {
return FLOAT2FIXED(__Pos.Y); 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 double X() const
{ {
@ -1289,15 +1222,15 @@ public:
// Comparing with floorz is ok because those values come from the same calculations. // Comparing with floorz is ok because those values come from the same calculations.
bool isAbove(double checkz) const bool isAbove(double checkz) const
{ {
return Z() > checkz + Z_Epsilon; return Z() > checkz + EQUAL_EPSILON;
} }
bool isBelow(double checkz) const bool isBelow(double checkz) const
{ {
return Z() < checkz - Z_Epsilon; return Z() < checkz - EQUAL_EPSILON;
} }
bool isAtZ(double checkz) const bool isAtZ(double checkz) const
{ {
return fabs(Z() - checkz) < Z_Epsilon; return fabs(Z() - checkz) < EQUAL_EPSILON;
} }
DVector3 PosRelative(int grp) const; DVector3 PosRelative(int grp) const;
@ -1307,18 +1240,14 @@ public:
FVector3 SoundPos() const FVector3 SoundPos() const
{ {
// the sound system switches y and z axes so this function must, too.
// fixme: This still needs portal handling // 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 DVector3 InterpolatedPosition(double ticFrac) const
{ {
return Prev + (ticFrac * (Pos() - Prev)); 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 DVector3 PosPlusZ(double zadd) const
{ {
return { X(), Y(), Z() + zadd }; return { X(), Y(), Z() + zadd };
@ -1327,18 +1256,6 @@ public:
{ {
return{ X(), Y(), zadd }; 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 double Top() const
{ {
return Z() + Height; return Z() + Height;
@ -1363,11 +1280,6 @@ public:
__Pos.X = FIXED2DBL(xx); __Pos.X = FIXED2DBL(xx);
__Pos.Y = FIXED2DBL(yy); __Pos.Y = FIXED2DBL(yy);
} }
void SetXY(const fixedvec2 &npos)
{
__Pos.X = FIXED2DBL(npos.x);
__Pos.Y = FIXED2DBL(npos.y);
}
void SetXY(const DVector2 &npos) void SetXY(const DVector2 &npos)
{ {
__Pos.X = npos.X; __Pos.X = npos.X;
@ -1383,12 +1295,6 @@ public:
{ {
__Pos = { xx,yy,zz }; __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) void SetXYZ(const DVector3 &npos)
{ {
__Pos = npos; __Pos = npos;
@ -1578,13 +1484,6 @@ template<class T> inline T *Spawn() // for inventory items we do not need coordi
return static_cast<T *>(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), DVector3(0, 0, 0), NO_REPLACE)); return static_cast<T *>(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); void PrintMiscActorInfo(AActor * query);
AActor *P_LinePickActor(AActor *t1, DAngle angle, double distance, DAngle pitch, ActorFlags actorMask, DWORD wallMask); AActor *P_LinePickActor(AActor *t1, DAngle angle, double distance, DAngle pitch, ActorFlags actorMask, DWORD wallMask);

View file

@ -55,7 +55,7 @@ bool DBot::Reachable (AActor *rtarget)
double dist; double dist;
sector_t *s; sector_t *s;
frac = in->Frac - 4 /MAX_TRAVERSE_DIST; frac = in->frac - 4 /MAX_TRAVERSE_DIST;
dist = frac * MAX_TRAVERSE_DIST; dist = frac * MAX_TRAVERSE_DIST;
hitx = it.Trace().x + player->mo->Vel.X * frac; hitx = it.Trace().x + player->mo->Vel.X * frac;

View file

@ -66,89 +66,6 @@ union QWORD_UNION
typedef SDWORD fixed_t; typedef SDWORD fixed_t;
typedef DWORD dsfixed_t; // fixedpt used by span drawer 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_MAX (signed)(0x7fffffff)
#define FIXED_MIN (signed)(0x80000000) #define FIXED_MIN (signed)(0x80000000)

View file

@ -340,7 +340,7 @@ enum : unsigned int
COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW. COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW.
COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom. 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_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) COMPATF2_MULTIEXIT = 1 << 4, // Level exit can be triggered multiple times (required by Daedalus's travel tubes, thanks to a faulty script)
}; };

View file

@ -213,7 +213,7 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *)
{ {
if (link->Me != mo) 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)) mo->IsOkayToAttack (link->Me))
{ {
return link->Me; return link->Me;

View file

@ -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>((SQWORD)y + radius, FIXED_MAX); if (pos.X < m_Box[BOXLEFT])
m_Box[BOXLEFT] = (fixed_t)MAX<SQWORD>((SQWORD)x - radius, FIXED_MIN); m_Box[BOXLEFT] = pos.X;
m_Box[BOXRIGHT] = (fixed_t)MIN<SQWORD>((SQWORD)x + radius, FIXED_MAX); if (pos.X > m_Box[BOXRIGHT])
m_Box[BOXBOTTOM] = (fixed_t)MAX<SQWORD>((SQWORD)y - radius, FIXED_MIN); m_Box[BOXRIGHT] = pos.X;
}
if (pos.Y < m_Box[BOXBOTTOM])
//========================================================================== m_Box[BOXBOTTOM] = pos.Y;
// if (pos.Y > m_Box[BOXTOP])
// m_Box[BOXTOP] = pos.Y;
//
//==========================================================================
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;
} }
//========================================================================== //==========================================================================
@ -78,8 +63,8 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const
if (ld->Delta().X == 0) if (ld->Delta().X == 0)
{ // ST_VERTICAL { // ST_VERTICAL
p1 = m_Box[BOXRIGHT] < ld->v1->fixX(); p1 = m_Box[BOXRIGHT] < ld->v1->fX();
p2 = m_Box[BOXLEFT] < ld->v1->fixX(); p2 = m_Box[BOXLEFT] < ld->v1->fX();
if (ld->Delta().Y < 0) if (ld->Delta().Y < 0)
{ {
p1 ^= 1; p1 ^= 1;
@ -88,8 +73,8 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const
} }
else if (ld->Delta().Y == 0) else if (ld->Delta().Y == 0)
{ // ST_HORIZONTAL: { // ST_HORIZONTAL:
p1 = m_Box[BOXTOP] > ld->v1->fixY(); p1 = m_Box[BOXTOP] > ld->v1->fY();
p2 = m_Box[BOXBOTTOM] > ld->v1->fixY(); p2 = m_Box[BOXBOTTOM] > ld->v1->fY();
if (ld->Delta().X < 0) if (ld->Delta().X < 0)
{ {
p1 ^= 1; p1 ^= 1;

View file

@ -22,7 +22,8 @@
#ifndef __M_BBOX_H__ #ifndef __M_BBOX_H__
#define __M_BBOX_H__ #define __M_BBOX_H__
#include "doomtype.h" #include <float.h>
#include "vectors.h"
#include "m_fixed.h" #include "m_fixed.h"
struct line_t; struct line_t;
@ -36,7 +37,7 @@ public:
ClearBox(); 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[BOXTOP] = top;
m_Box[BOXLEFT] = left; m_Box[BOXLEFT] = left;
@ -44,35 +45,24 @@ public:
m_Box[BOXBOTTOM] = bottom; 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) FBoundingBox(double x, double y, double radius)
{ {
setBox(x, y, radius); setBox(x, y, radius);
} }
void setBox(fixed_t x, fixed_t y, fixed_t radius);
void setBox(double x, double y, double 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 () void ClearBox ()
{ {
m_Box[BOXTOP] = m_Box[BOXRIGHT] = FIXED_MIN; m_Box[BOXTOP] = m_Box[BOXRIGHT] = -FLT_MAX;
m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FIXED_MAX; m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FLT_MAX;
} }
// Returns a bounding box that encloses both bounding boxes // 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]); 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 double Top () const { return m_Box[BOXTOP]; }
inline fixed_t Bottom () const { return m_Box[BOXBOTTOM]; } inline double Bottom () const { return m_Box[BOXBOTTOM]; }
inline fixed_t Left () const { return m_Box[BOXLEFT]; } inline double Left () const { return m_Box[BOXLEFT]; }
inline fixed_t Right () const { return m_Box[BOXRIGHT]; } inline double Right () const { return m_Box[BOXRIGHT]; }
bool inRange(const line_t *ld) const; bool inRange(const line_t *ld) const;
int BoxOnLineSide (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: protected:
fixed_t m_Box[4]; double m_Box[4];
}; };

View file

@ -48,6 +48,7 @@ public:
extern FFastTrig fasttrig; extern FFastTrig fasttrig;
// This must use xs_Float to guarantee proper integer wraparound.
#define DEG2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x40000000/90.))) #define DEG2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x40000000/90.)))
#define RAD2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x80000000/3.14159265358979323846))) #define RAD2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x80000000/3.14159265358979323846)))

View file

@ -279,9 +279,9 @@ void P_ThinkParticles ()
continue; continue;
} }
fixedvec2 newxy = P_GetOffsetPosition(particle->x, particle->y, particle->vel.x, particle->vel.y); DVector2 newxy = P_GetOffsetPosition(FIXED2DBL(particle->x), FIXED2DBL(particle->y), FIXED2DBL(particle->vel.x), FIXED2DBL(particle->vel.y));
particle->x = newxy.x; particle->x = FLOAT2FIXED(newxy.X);
particle->y = newxy.y; particle->y = FLOAT2FIXED(newxy.Y);
//particle->x += particle->vel.x; //particle->x += particle->vel.x;
//particle->y += particle->vel.y; //particle->y += particle->vel.y;
particle->z += particle->vel.z; particle->z += particle->vel.z;
@ -408,14 +408,14 @@ static void MakeFountain (AActor *actor, int color1, int color2)
if (particle) if (particle)
{ {
angle_t an = M_Random()<<(24-ANGLETOFINESHIFT); DAngle an = M_Random() * (360. / 256);
fixed_t out = FixedMul (actor->_f_radius(), M_Random()<<8); double out = actor->radius * M_Random() / 256.;
fixedvec3 pos = actor->Vec3Offset(FixedMul(out, finecosine[an]), FixedMul(out, finesine[an]), actor->_f_height() + FRACUNIT); DVector3 pos = actor->Vec3Angle(out, an, actor->Height + 1);
particle->x = pos.x; particle->x = FLOAT2FIXED(pos.X);
particle->y = pos.y; particle->y = FLOAT2FIXED(pos.Y);
particle->z = pos.z; particle->z = FLOAT2FIXED(pos.Z);
if (out < actor->_f_radius()/8) if (out < actor->radius/8)
particle->vel.z += FRACUNIT*10/3; particle->vel.z += FRACUNIT*10/3;
else else
particle->vel.z += FRACUNIT*3; particle->vel.z += FRACUNIT*3;
@ -449,14 +449,14 @@ void P_RunEffect (AActor *actor, int effects)
particle = JitterParticle (3 + (M_Random() & 31)); particle = JitterParticle (3 + (M_Random() & 31));
if (particle) { if (particle) {
fixed_t pathdist = M_Random()<<8; double pathdist = M_Random() / 256.;
fixedvec3 pos = actor->Vec3Offset( DVector3 pos = actor->Vec3Offset(
FLOAT2FIXED(backx) - fixed_t(actor->Vel.X * pathdist), backx - actor->Vel.X * pathdist,
FLOAT2FIXED(backy) - fixed_t(actor->Vel.Y * pathdist), backy - actor->Vel.Y * pathdist,
FLOAT2FIXED(backz) - fixed_t(actor->Vel.Z * pathdist)); backz - actor->Vel.Z * pathdist);
particle->x = pos.x; particle->x = FLOAT2FIXED(pos.X);
particle->y = pos.y; particle->y = FLOAT2FIXED(pos.Y);
particle->z = pos.z; particle->z = FLOAT2FIXED(pos.Z);
speed = (M_Random () - 128) * (FRACUNIT/200); speed = (M_Random () - 128) * (FRACUNIT/200);
particle->vel.x += fixed_t(speed * an.Cos()); particle->vel.x += fixed_t(speed * an.Cos());
particle->vel.y += fixed_t(speed * an.Sin()); particle->vel.y += fixed_t(speed * an.Sin());
@ -468,14 +468,15 @@ void P_RunEffect (AActor *actor, int effects)
for (i = 6; i; i--) { for (i = 6; i; i--) {
particle_t *particle = JitterParticle (3 + (M_Random() & 31)); particle_t *particle = JitterParticle (3 + (M_Random() & 31));
if (particle) { if (particle) {
fixed_t pathdist = M_Random()<<8; double pathdist = M_Random() / 256.;
fixedvec3 pos = actor->Vec3Offset( DVector3 pos = actor->Vec3Offset(
FLOAT2FIXED(backx) - fixed_t(actor->Vel.X * pathdist), backx - actor->Vel.X * pathdist,
FLOAT2FIXED(backy) - fixed_t(actor->Vel.Y * pathdist), backy - actor->Vel.Y * pathdist,
FLOAT2FIXED(backz) - fixed_t(actor->Vel.Z * pathdist) + (M_Random() << 10)); backz - actor->Vel.Z * pathdist + (M_Random() / 64.));
particle->x = pos.x; particle->x = FLOAT2FIXED(pos.X);
particle->y = pos.y; particle->y = FLOAT2FIXED(pos.Y);
particle->z = pos.z; particle->z = FLOAT2FIXED(pos.Z);
speed = (M_Random () - 128) * (FRACUNIT/200); speed = (M_Random () - 128) * (FRACUNIT/200);
particle->vel.x += fixed_t(speed * an.Cos()); particle->vel.x += fixed_t(speed * an.Cos());
particle->vel.y += fixed_t(speed * an.Sin()); particle->vel.y += fixed_t(speed * an.Sin());
@ -526,18 +527,18 @@ void P_RunEffect (AActor *actor, int effects)
particle = JitterParticle (16); particle = JitterParticle (16);
if (particle != NULL) if (particle != NULL)
{ {
angle_t ang = M_Random () << (32-ANGLETOFINESHIFT-8); DAngle ang = M_Random() * (360 / 256.);
fixedvec3 pos = actor->Vec3Offset(FixedMul (actor->_f_radius(), finecosine[ang]), FixedMul (actor->_f_radius(), finesine[ang]), 0); DVector3 pos = actor->Vec3Angle(actor->radius, ang, 0);
particle->x = pos.x; particle->x = FLOAT2FIXED(pos.X);
particle->y = pos.y; particle->y = FLOAT2FIXED(pos.Y);
particle->z = pos.z; particle->z = FLOAT2FIXED(pos.Z);
particle->color = *protectColors[M_Random() & 1]; particle->color = *protectColors[M_Random() & 1];
particle->vel.z = FRACUNIT; particle->vel.z = FRACUNIT;
particle->accz = M_Random () << 7; particle->accz = M_Random () << 7;
particle->size = 1; particle->size = 1;
if (M_Random () < 128) if (M_Random () < 128)
{ // make particle fall from top of actor { // make particle fall from top of actor
particle->z += actor->_f_height(); particle->z += FLOAT2FIXED(actor->Height);
particle->vel.z = -particle->vel.z; particle->vel.z = -particle->vel.z;
particle->accz = -particle->accz; particle->accz = -particle->accz;
} }
@ -882,14 +883,14 @@ void P_DisconnectEffect (AActor *actor)
if (!p) if (!p)
break; break;
double xo = (M_Random() - 128)*actor->radius / 128;
fixed_t xo = ((M_Random() - 128) << 9) * int(actor->radius); double yo = (M_Random() - 128)*actor->radius / 128;
fixed_t yo = ((M_Random() - 128) << 9) * int(actor->radius); double zo = M_Random()*actor->Height / 256;
fixed_t zo = (M_Random() << 8) * int(actor->Height);
fixedvec3 pos = actor->Vec3Offset(xo, yo, zo); DVector3 pos = actor->Vec3Offset(xo, yo, zo);
p->x = pos.x; p->x = FLOAT2FIXED(pos.X);
p->y = pos.y; p->y = FLOAT2FIXED(pos.Y);
p->z = pos.z; p->z = FLOAT2FIXED(pos.Z);
p->accz -= FRACUNIT/4096; p->accz -= FRACUNIT/4096;
p->color = M_Random() < 128 ? maroon1 : maroon2; p->color = M_Random() < 128 ? maroon1 : maroon2;
p->size = 4; p->size = 4;

View file

@ -52,6 +52,12 @@
struct subsector_t; struct subsector_t;
// [RH] Particle details // [RH] Particle details
struct fixedvec3
{
fixed_t x, y, z;
};
struct particle_t struct particle_t
{ {
fixed_t x,y,z; fixed_t x,y,z;

View file

@ -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... // I wish there was a better method to do this than randomly looking through the portal at a few places...
if (checkabove) 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); P_RecursiveSound(upper, soundtarget, splash, soundblocks, emitter, maxdist);
} }
if (checkbelow) 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); P_RecursiveSound(lower, soundtarget, splash, soundblocks, emitter, maxdist);
} }
FLinePortal *port = check->getPortal(); 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; other = check->sidedef[0]->sector;
// check for closed door // check for closed door
if ((sec->floorplane.ZatPoint (check->V1()) >= if ((sec->floorplane.ZatPoint (check->v1->fPos()) >=
other->ceilingplane.ZatPoint (check->V1()) && other->ceilingplane.ZatPoint (check->v1->fPos()) &&
sec->floorplane.ZatPoint (check->V2()) >= sec->floorplane.ZatPoint (check->v2->fPos()) >=
other->ceilingplane.ZatPoint (check->V2())) other->ceilingplane.ZatPoint (check->v2->fPos()))
|| (other->floorplane.ZatPoint (check->V1()) >= || (other->floorplane.ZatPoint (check->v1->fPos()) >=
sec->ceilingplane.ZatPoint (check->V1()) && sec->ceilingplane.ZatPoint (check->v1->fPos()) &&
other->floorplane.ZatPoint (check->V2()) >= other->floorplane.ZatPoint (check->v2->fPos()) >=
sec->ceilingplane.ZatPoint (check->V2())) sec->ceilingplane.ZatPoint (check->v2->fPos()))
|| (other->floorplane.ZatPoint (check->V1()) >= || (other->floorplane.ZatPoint (check->v1->fPos()) >=
other->ceilingplane.ZatPoint (check->V1()) && other->ceilingplane.ZatPoint (check->v1->fPos()) &&
other->floorplane.ZatPoint (check->V2()) >= other->floorplane.ZatPoint (check->v2->fPos()) >=
other->ceilingplane.ZatPoint (check->V2()))) other->ceilingplane.ZatPoint (check->v2->fPos())))
{ {
continue; continue;
} }

View file

@ -81,7 +81,7 @@ static void CreateCachedNodes(MapData *map);
// fixed 32 bit gl_vert format v2.0+ (glBsp 1.91) // fixed 32 bit gl_vert format v2.0+ (glBsp 1.91)
struct mapglvertex_t struct mapglvertex_t
{ {
fixed_t x,y; SDWORD x,y;
}; };
struct gl3_mapsubsector_t 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; node_t *node;
int side; int side;

View file

@ -52,9 +52,6 @@ struct FTranslatedLineTarget;
// against lines and things // against lines and things
#define MAPBLOCKUNITS 128 #define MAPBLOCKUNITS 128
#define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT) #define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT)
#define MAPBLOCKSHIFT (FRACBITS+7)
#define MAPBMASK (MAPBLOCKSIZE-1)
#define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS)
// Inspired by Maes // Inspired by Maes
extern int bmapnegx; 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 "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 extern msecnode_t *sector_list; // phares 3/16/98
struct spechit_t struct spechit_t
@ -264,7 +261,6 @@ enum
void P_FindFloorCeiling (AActor *actor, int flags=0); void P_FindFloorCeiling (AActor *actor, int flags=0);
bool P_ChangeSector (sector_t* sector, int crunch, double amt, int floorOrCeil, bool isreset); 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); DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLineTarget *pLineTarget = NULL, DAngle vrange = 0., int flags = 0, AActor *target = NULL, AActor *friender = NULL);

View file

@ -109,7 +109,7 @@ static DVector2 FindRefPoint(line_t *ld, const DVector2 &pos)
!ld->frontsector->PortalBlocksMovement(sector_t::floor)) !ld->frontsector->PortalBlocksMovement(sector_t::floor))
{ {
DVector2 v1 = ld->V1(); DVector2 v1 = ld->v1->fPos();
DVector2 d = ld->Delta(); 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.); 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; return v1 + d*r;
@ -2728,11 +2728,11 @@ void FSlide::SlideTraverse(const DVector2 &start, const DVector2 &end)
// the line does block movement, // the line does block movement,
// see if it is closer than best so far // see if it is closer than best so far
isblocking: isblocking:
if (in->Frac < bestSlidefrac) if (in->frac < bestSlidefrac)
{ {
secondSlidefrac = bestSlidefrac; secondSlidefrac = bestSlidefrac;
secondslideline = bestslideline; secondslideline = bestslideline;
bestSlidefrac = in->Frac; bestSlidefrac = in->frac;
bestslideline = li; 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 // the line does block movement, see if it is closer than best so far
bounceblocking: bounceblocking:
if (in->Frac < bestSlidefrac) if (in->frac < bestSlidefrac)
{ {
secondSlidefrac = bestSlidefrac; secondSlidefrac = bestSlidefrac;
secondslideline = bestslideline; secondslideline = bestslideline;
bestSlidefrac = in->Frac; bestSlidefrac = in->frac;
bestslideline = li; bestslideline = li;
} }
return false; // stop return false; // stop
@ -3419,9 +3419,9 @@ struct aim_t
F3DFloor* rover; F3DFloor* rover;
DAngle highpitch, lowpitch; DAngle highpitch, lowpitch;
double trX = trace.x + trace.dx * in->Frac; double trX = trace.x + trace.dx * in->frac;
double trY = trace.y + trace.dy * in->Frac; double trY = trace.y + trace.dy * in->frac;
double dist = attackrange * in->Frac; double dist = attackrange * in->frac;
// 3D floor check. This is not 100% accurate but normally sufficient when // 3D floor check. This is not 100% accurate but normally sufficient when
// combined with a final sight check // combined with a final sight check
@ -3632,7 +3632,7 @@ struct aim_t
double dist; double dist;
DAngle thingpitch; 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) if (in->isaline)
{ {
@ -3644,7 +3644,7 @@ struct aim_t
if (li->isLinePortal() && frontflag == 0) if (li->isLinePortal() && frontflag == 0)
{ {
EnterLinePortal(li, in->Frac); EnterLinePortal(li, in->frac);
return; return;
} }
@ -3662,7 +3662,7 @@ struct aim_t
if (open.range <= 0 || open.bottom >= open.top) if (open.range <= 0 || open.bottom >= open.top)
return; return;
dist = attackrange * in->Frac; dist = attackrange * in->frac;
if (open.bottom != LINEOPEN_MIN) 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 // 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)) if ((planestocheck & aim_up) && toppitch < 0 && open.top != LINEOPEN_MAX && !entersec->PortalBlocksMovement(sector_t::ceiling))
{ {
EnterSectorPortal(sector_t::ceiling, in->Frac, entersec, toppitch, MIN<DAngle>(0., bottompitch)); EnterSectorPortal(sector_t::ceiling, in->frac, entersec, toppitch, MIN<DAngle>(0., bottompitch));
} }
if ((planestocheck & aim_down) && bottompitch > 0 && open.bottom != LINEOPEN_MIN && !entersec->PortalBlocksMovement(sector_t::floor)) if ((planestocheck & aim_down) && bottompitch > 0 && open.bottom != LINEOPEN_MIN && !entersec->PortalBlocksMovement(sector_t::floor))
{ {
EnterSectorPortal(sector_t::floor, in->Frac, entersec, MAX<DAngle>(0., toppitch), bottompitch); EnterSectorPortal(sector_t::floor, in->frac, entersec, MAX<DAngle>(0., toppitch), bottompitch);
} }
continue; // shot continues continue; // shot continues
} }
@ -3728,7 +3728,7 @@ struct aim_t
} }
} }
} }
dist = attackrange * in->Frac; dist = attackrange * in->frac;
// Don't autoaim certain special actors // Don't autoaim certain special actors
if (!cl_doautoaim && th->flags6 & MF6_NOTAUTOAIMED) if (!cl_doautoaim && th->flags6 & MF6_NOTAUTOAIMED)
@ -3811,7 +3811,7 @@ struct aim_t
if (cosine != 0) if (cosine != 0)
{ {
double tracelen = DVector2(it.Trace().dx, it.Trace().dy).Length(); 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) if (d3 > attackrange)
{ {
return; return;
@ -3834,7 +3834,7 @@ struct aim_t
// friends don't aim at friends (except players), at least not first // friends don't aim at friends (except players), at least not first
if (aimdebug) if (aimdebug)
Printf("Hit friend %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); 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) 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 // don't autoaim at barrels and other shootable stuff unless no monsters have been found
if (aimdebug) if (aimdebug)
Printf("Hit other %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); 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 else
{ {
if (aimdebug) if (aimdebug)
Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); 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; return;
} }
} }
@ -3859,7 +3859,7 @@ struct aim_t
{ {
if (aimdebug) if (aimdebug)
Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); 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; return;
} }
} }

View file

@ -46,8 +46,8 @@
#include "po_man.h" #include "po_man.h"
static AActor *RoughBlockCheck (AActor *mo, int index, void *); 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(double x, double y);
sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t 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); dx = abs(dx);
dy = abs(dy); dy = abs(dy);
return (dx < dy) ? dx+dy-(dx>>1) : dx+dy-(dy>>1); 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 // P_InterceptVector
@ -96,69 +111,6 @@ double P_InterceptVector(const divline_t *v2, const divline_t *v1)
return num / den; 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 // P_LineOpening
@ -374,7 +326,7 @@ void AActor::UnlinkFromWorld ()
bool AActor::FixMapthingPos() bool AActor::FixMapthingPos()
{ {
sector_t *secstart = P_PointInSectorBuggy(_f_X(), _f_Y()); sector_t *secstart = P_PointInSectorBuggy(X(), Y());
int blockx = GetBlockX(X()); int blockx = GetBlockX(X());
int blocky = GetBlockY(Y()); int blocky = GetBlockY(Y());
@ -472,12 +424,12 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector)
} }
else else
{ {
sector = P_PointInSectorBuggy(_f_X(), _f_Y()); sector = P_PointInSectorBuggy(X(), Y());
} }
} }
Sector = sector; 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)) if (!(flags & MF_NOSECTOR))
{ {
@ -515,7 +467,7 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector)
{ {
FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); 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++) 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 (); UnlinkFromWorld ();
SetXYZ(ix, iy, iz); SetXYZ(x, y, z);
LinkToWorld (); LinkToWorld ();
P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS); P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS);
if (!moving) ClearInterpolation(); if (!moving) ClearInterpolation();
@ -638,10 +590,10 @@ FBlockLinesIterator::FBlockLinesIterator(int _minx, int _miny, int _maxx, int _m
void FBlockLinesIterator::init(const FBoundingBox &box) void FBlockLinesIterator::init(const FBoundingBox &box)
{ {
validcount++; validcount++;
maxy = GetBlockY(FIXED2DBL(box.Top())); maxy = GetBlockY(box.Top());
miny = GetBlockY(FIXED2DBL(box.Bottom())); miny = GetBlockY(box.Bottom());
maxx = GetBlockX(FIXED2DBL(box.Right())); maxx = GetBlockX(box.Right());
minx = GetBlockX(FIXED2DBL(box.Left())); minx = GetBlockX(box.Left());
Reset(); 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) : checklist(check)
{ {
checkpoint = origin->_f_Pos(); checkpoint = origin->Pos();
if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->_f_Top(), checkradius, checklist); if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist);
checkpoint.z = checkradius == -1? origin->_f_radius() : checkradius; checkpoint.Z = checkradius == -1? origin->radius : checkradius;
basegroup = origin->Sector->PortalGroup; basegroup = origin->Sector->PortalGroup;
startsector = origin->Sector; startsector = origin->Sector;
Reset(); 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) : checklist(check)
{ {
checkpoint.x = checkx; checkpoint = { checkx, checky, checkz };
checkpoint.y = checky;
checkpoint.z = checkz;
if (newsec == NULL) newsec = P_PointInSector(checkx, checky); if (newsec == NULL) newsec = P_PointInSector(checkx, checky);
startsector = newsec; startsector = newsec;
basegroup = newsec->PortalGroup; basegroup = newsec->PortalGroup;
if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist); if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist);
checkpoint.z = checkradius; checkpoint.Z = checkradius;
Reset(); 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) 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) if (continuedown)
{ {
@ -835,10 +785,8 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
if (line != NULL) if (line != NULL)
{ {
item->line = line; item->line = line;
item->position.x = offset.x; item->Position.X = offset.X;
item->position.y = offset.y; 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->portalflags = portalflags; item->portalflags = portalflags;
return true; return true;
} }
@ -848,19 +796,19 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
if (portalflags == FFCF_NOFLOOR && nextflags != FPortalGroupArray::UPPER) 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 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) 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 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) if (onlast)
{ {
cursector = startsector; cursector = startsector;
// We reached the end of the list. Check if we still need to check up- and downwards. // We reached the end of the list. Check if we still need to check up- and downwards.
if (GoUp(checkpoint.x, checkpoint.y) || if (GoUp(checkpoint.X, checkpoint.Y) ||
GoDown(checkpoint.x, checkpoint.y)) GoDown(checkpoint.X, checkpoint.Y))
{ {
return Next(item); return Next(item);
} }
@ -894,11 +842,11 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
void FMultiBlockLinesIterator::startIteratorForGroup(int group) void FMultiBlockLinesIterator::startIteratorForGroup(int group)
{ {
offset = Displacements._f_getOffset(basegroup, group); offset = Displacements.getOffset(basegroup, group);
offset.x += checkpoint.x; offset.X += checkpoint.X;
offset.y += checkpoint.y; offset.Y += checkpoint.Y;
cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset.x, offset.y); cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset);
bbox.setBox(offset.x, offset.y, checkpoint.z); bbox.setBox(offset.X, offset.Y, checkpoint.Z);
blockIterator.init(bbox); blockIterator.init(bbox);
} }
@ -944,10 +892,10 @@ FBlockThingsIterator::FBlockThingsIterator(int _minx, int _miny, int _maxx, int
void FBlockThingsIterator::init(const FBoundingBox &box) void FBlockThingsIterator::init(const FBoundingBox &box)
{ {
maxy = GetBlockY(FIXED2DBL(box.Top())); maxy = GetBlockY(box.Top());
miny = GetBlockY(FIXED2DBL(box.Bottom())); miny = GetBlockY(box.Bottom());
maxx = GetBlockX(FIXED2DBL(box.Right())); maxx = GetBlockX(box.Right());
minx = GetBlockX(FIXED2DBL(box.Left())); minx = GetBlockX(box.Left());
ClearHash(); ClearHash();
Reset(); Reset();
} }
@ -1025,14 +973,14 @@ AActor *FBlockThingsIterator::Next(bool centeronly)
if (centeronly) if (centeronly)
{ {
// Block boundaries for compatibility mode // Block boundaries for compatibility mode
fixed_t blockleft = (curx << MAPBLOCKSHIFT) + FLOAT2FIXED(bmaporgx); double blockleft = (curx * MAPBLOCKUNITS) + bmaporgx;
fixed_t blockright = blockleft + MAPBLOCKSIZE; double blockright = blockleft + MAPBLOCKUNITS;
fixed_t blockbottom = (cury << MAPBLOCKSHIFT) + FLOAT2FIXED(bmaporgy); double blockbottom = (cury * MAPBLOCKUNITS) + bmaporgy;
fixed_t blocktop = blockbottom + MAPBLOCKSIZE; double blocktop = blockbottom + MAPBLOCKUNITS;
// only return actors with the center in this block // only return actors with the center in this block
if (me->_f_X() >= blockleft && me->_f_X() < blockright && if (me->X() >= blockleft && me->X() < blockright &&
me->_f_Y() >= blockbottom && me->_f_Y() < blocktop) me->Y() >= blockbottom && me->Y() < blocktop)
{ {
return me; 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) : checklist(check)
{ {
checkpoint = origin->_f_Pos(); checkpoint = origin->Pos();
if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->_f_Top(), checkradius, checklist); if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist);
checkpoint.z = checkradius == -1? origin->_f_radius() : checkradius; checkpoint.Z = checkradius == -1? origin->radius : checkradius;
basegroup = origin->Sector->PortalGroup; basegroup = origin->Sector->PortalGroup;
Reset(); 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) : checklist(check)
{ {
checkpoint.x = checkx; checkpoint.X = checkx;
checkpoint.y = checky; checkpoint.Y = checky;
checkpoint.z = checkz; checkpoint.Z = checkz;
if (newsec == NULL) newsec = P_PointInSector(checkx, checky); if (newsec == NULL) newsec = P_PointInSector(checkx, checky);
basegroup = newsec->PortalGroup; basegroup = newsec->PortalGroup;
if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist); if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist);
checkpoint.z = checkradius; checkpoint.Z = checkradius;
Reset(); Reset();
} }
@ -1128,11 +1076,8 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite
if (thing != NULL) if (thing != NULL)
{ {
item->thing = thing; 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; 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; return true;
} }
bool onlast = unsigned(index + 1) >= checklist.Size(); bool onlast = unsigned(index + 1) >= checklist.Size();
@ -1170,10 +1115,10 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite
void FMultiBlockThingsIterator::startIteratorForGroup(int group) void FMultiBlockThingsIterator::startIteratorForGroup(int group)
{ {
fixedvec2 offset = Displacements._f_getOffset(basegroup, group); DVector2 offset = Displacements.getOffset(basegroup, group);
offset.x += checkpoint.x; offset.X += checkpoint.X;
offset.y += checkpoint.y; offset.Y += checkpoint.Y;
bbox.setBox(offset.x, offset.y, checkpoint.z); bbox.setBox(offset.X, offset.Y, checkpoint.Z);
blockIterator.init(bbox); blockIterator.init(bbox);
} }
@ -1220,17 +1165,17 @@ void FPathTraverse::AddLineIntercepts(int bx, int by)
{ {
int s1; int s1;
int s2; int s2;
fixed_t frac; double frac;
fdivline_t dl; divline_t dl;
// avoid precision problems with two routines // avoid precision problems with two routines
if ( trace.dx > FRACUNIT*16 if ( trace.dx > 16
|| trace.dy > FRACUNIT*16 || trace.dy > 16
|| trace.dx < -FRACUNIT*16 || trace.dx < -16
|| trace.dy < -FRACUNIT*16) || trace.dy < -16)
{ {
s1 = P_PointOnDivlineSide (ld->v1->fixX(), ld->v1->fixY(), &trace); s1 = P_PointOnDivlineSideCompat (ld->v1->fX(), ld->v1->fY(), &trace);
s2 = P_PointOnDivlineSide (ld->v2->fixX(), ld->v2->fixY(), &trace); s2 = P_PointOnDivlineSideCompat (ld->v2->fX(), ld->v2->fY(), &trace);
} }
else else
{ {
@ -1244,7 +1189,7 @@ void FPathTraverse::AddLineIntercepts(int bx, int by)
P_MakeDivline (ld, &dl); P_MakeDivline (ld, &dl);
frac = P_InterceptVector (&trace, &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; intercept_t newintercept;
@ -1271,7 +1216,7 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
while ((thing = it.Next(compatible))) while ((thing = it.Next(compatible)))
{ {
int numfronts = 0; int numfronts = 0;
fdivline_t line; divline_t line;
int i; int i;
@ -1287,69 +1232,69 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
switch (i) switch (i)
{ {
case 0: // Top edge case 0: // Top edge
line.x = thing->_f_X() + thing->_f_radius(); line.x = thing->X() + thing->radius;
line.y = thing->_f_Y() + thing->_f_radius(); line.y = thing->Y() + thing->radius;
line.dx = -thing->_f_radius() * 2; line.dx = -thing->radius * 2;
line.dy = 0; line.dy = 0;
break; break;
case 1: // Right edge case 1: // Right edge
line.x = thing->_f_X() + thing->_f_radius(); line.x = thing->X() + thing->radius;
line.y = thing->_f_Y() - thing->_f_radius(); line.y = thing->Y() - thing->radius;
line.dx = 0; line.dx = 0;
line.dy = thing->_f_radius() * 2; line.dy = thing->radius * 2;
break; break;
case 2: // Bottom edge case 2: // Bottom edge
line.x = thing->_f_X() - thing->_f_radius(); line.x = thing->X() - thing->radius;
line.y = thing->_f_Y() - thing->_f_radius(); line.y = thing->Y() - thing->radius;
line.dx = thing->_f_radius() * 2; line.dx = thing->radius * 2;
line.dy = 0; line.dy = 0;
break; break;
case 3: // Left edge case 3: // Left edge
line.x = thing->_f_X() - thing->_f_radius(); line.x = thing->X() - thing->radius;
line.y = thing->_f_Y() + thing->_f_radius(); line.y = thing->Y() + thing->radius;
line.dx = 0; line.dx = 0;
line.dy = thing->_f_radius() * -2; line.dy = thing->radius * -2;
break; break;
} }
// Check if this side is facing the trace origin // 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++; numfronts++;
// If it is, see if the trace crosses it // If it is, see if the trace crosses it
if (P_PointOnDivlineSidePrecise (line.x, line.y, &trace) != if (P_PointOnDivlineSide (line.x, line.y, &trace) !=
P_PointOnDivlineSidePrecise (line.x + line.dx, line.y + line.dy, &trace)) P_PointOnDivlineSide (line.x + line.dx, line.y + line.dy, &trace))
{ {
// It's a hit // It's a hit
fixed_t frac = P_InterceptVector (&trace, &line); double frac = P_InterceptVector (&trace, &line);
if (frac < startfrac) if (frac < Startfrac)
{ // behind source { // behind source
if (startfrac > 0) if (Startfrac > 0)
{ {
// check if the trace starts within this actor // check if the trace starts within this actor
switch (i) switch (i)
{ {
case 0: case 0:
line.y -= 2 * thing->_f_radius(); line.y -= 2 * thing->radius;
break; break;
case 1: case 1:
line.x -= 2 * thing->_f_radius(); line.x -= 2 * thing->radius;
break; break;
case 2: case 2:
line.y += 2 * thing->_f_radius(); line.y += 2 * thing->radius;
break; break;
case 3: case 3:
line.x += 2 * thing->_f_radius(); line.x += 2 * thing->radius;
break; break;
} }
fixed_t frac2 = P_InterceptVector(&trace, &line); double frac2 = P_InterceptVector(&trace, &line);
if (frac2 >= startfrac) goto addit; if (frac2 >= Startfrac) goto addit;
} }
continue; continue;
} }
@ -1380,33 +1325,33 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
else else
{ {
// Old code for compatibility purposes // Old code for compatibility purposes
fixed_t x1, y1, x2, y2; double x1, y1, x2, y2;
int s1, s2; int s1, s2;
fdivline_t dl; divline_t dl;
fixed_t frac; double frac;
bool tracepositive = (trace.dx ^ trace.dy)>0; bool tracepositive = (trace.dx * trace.dy)>0;
// check a corner to corner crossection for hit // check a corner to corner crossection for hit
if (tracepositive) if (tracepositive)
{ {
x1 = thing->_f_X() - thing->_f_radius(); x1 = thing->X() - thing->radius;
y1 = thing->_f_Y() + thing->_f_radius(); y1 = thing->Y() + thing->radius;
x2 = thing->_f_X() + thing->_f_radius(); x2 = thing->X() + thing->radius;
y2 = thing->_f_Y() - thing->_f_radius(); y2 = thing->Y() - thing->radius;
} }
else else
{ {
x1 = thing->_f_X() - thing->_f_radius(); x1 = thing->X() - thing->radius;
y1 = thing->_f_Y() - thing->_f_radius(); y1 = thing->Y() - thing->radius;
x2 = thing->_f_X() + thing->_f_radius(); x2 = thing->X() + thing->radius;
y2 = thing->_f_Y() + thing->_f_radius(); y2 = thing->Y() + thing->radius;
} }
s1 = P_PointOnDivlineSide (x1, y1, &trace); s1 = P_PointOnDivlineSideCompat (x1, y1, &trace);
s2 = P_PointOnDivlineSide (x2, y2, &trace); s2 = P_PointOnDivlineSideCompat (x2, y2, &trace);
if (s1 != s2) if (s1 != s2)
{ {
@ -1417,7 +1362,7 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
frac = P_InterceptVector (&trace, &dl); frac = P_InterceptVector (&trace, &dl);
if (frac >= startfrac) if (frac >= Startfrac)
{ {
intercept_t newintercept; intercept_t newintercept;
newintercept.frac = frac; newintercept.frac = frac;
@ -1442,7 +1387,7 @@ intercept_t *FPathTraverse::Next()
{ {
intercept_t *in = NULL; intercept_t *in = NULL;
fixed_t dist = FIXED_MAX; double dist = FLT_MAX;
for (unsigned scanpos = intercept_index; scanpos < intercepts.Size (); scanpos++) for (unsigned scanpos = intercept_index; scanpos < intercepts.Size (); scanpos++)
{ {
intercept_t *scan = &intercepts[scanpos]; intercept_t *scan = &intercepts[scanpos];
@ -1450,11 +1395,10 @@ intercept_t *FPathTraverse::Next()
{ {
dist = scan->frac; dist = scan->frac;
in = scan; 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; in->done = true;
return in; 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; double xt1, yt1, xt2, yt2;
fixed_t yt1, yt2; double xstep, ystep;
long long _x1, _x2, _y1, _y2; double partialx, partialy;
double xintercept, yintercept;
fixed_t xstep;
fixed_t ystep;
fixed_t partialx, partialy;
fixed_t xintercept;
fixed_t yintercept;
int mapx; int mapx;
int mapy; 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) if (startfrac > 0)
{ {
fixed_t startdx = FixedMul(trace.dx, startfrac); double startdx = trace.dx * startfrac;
fixed_t startdy = FixedMul(trace.dy, startfrac); double startdy = trace.dy * startfrac;
x1 += startdx; x1 += startdx;
y1 += startdy; y1 += startdy;
@ -1514,110 +1451,95 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl
validcount++; validcount++;
intercept_index = intercepts.Size(); intercept_index = intercepts.Size();
this->startfrac = startfrac; 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);
if (flags & PT_DELTA) if (flags & PT_DELTA)
{ {
_x2 = _x1 + x2; x2 += x1;
_y2 = _y1 + y2; y2 += 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);
} }
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; mapxstep = 1;
partialx = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1)); partialx = xs_CeilToInt(xt1) - xt1;
ystep = FixedDiv (y2-y1,abs(x2-x1)); ystep = (y2 - y1) / fabs(x2 - x1);
} }
else if (xt2 < xt1) else if (mapex < mapx)
{ {
mapxstep = -1; mapxstep = -1;
partialx = (x1>>MAPBTOFRAC)&(FRACUNIT-1); partialx = xt1 - xs_FloorToInt(xt1);
ystep = FixedDiv (y2-y1,abs(x2-x1)); ystep = (y2 - y1) / fabs(x2 - x1);
} }
else else
{ {
mapxstep = 0; mapxstep = 0;
partialx = FRACUNIT; partialx = 1.;
ystep = 256*FRACUNIT; ystep = 256;
} }
yintercept = int(_y1>>MAPBTOFRAC) + FixedMul (partialx, ystep); yintercept = yt1 + partialx * ystep;
if (yt2 > yt1) if (mapey > mapy)
{ {
mapystep = 1; mapystep = 1;
partialy = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1)); partialy = xs_CeilToInt(yt1) - yt1;
xstep = FixedDiv (x2-x1,abs(y2-y1)); xstep = (x2 - x1) / fabs(y2 - y1);
} }
else if (yt2 < yt1) else if (mapey < mapy)
{ {
mapystep = -1; mapystep = -1;
partialy = (y1>>MAPBTOFRAC)&(FRACUNIT-1); partialy = yt1 - xs_FloorToInt(yt1);
xstep = FixedDiv (x2-x1,abs(y2-y1)); xstep = (x2 - x1) / fabs(y2 - y1);
} }
else else
{ {
mapystep = 0; mapystep = 0;
partialy = FRACUNIT; partialy = 1;
xstep = 256*FRACUNIT; xstep = 256;
} }
xintercept = int(_x1>>MAPBTOFRAC) + FixedMul (partialy, xstep); xintercept = xt1 + partialy * xstep;
// [RH] Fix for traces that pass only through blockmap corners. In that case, // [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 // xintercept and yintercept can both be set ahead of mapx and mapy, so the
// for loop would never advance anywhere. // for loop would never advance anywhere.
if (abs(xstep) == FRACUNIT && abs(ystep) == FRACUNIT) if (fabs(xstep) == 1. && fabs(ystep) == 1.)
{ {
if (ystep < 0) if (ystep < 0)
{ {
partialx = FRACUNIT - partialx; partialx = 1. - partialx;
} }
if (xstep < 0) if (xstep < 0)
{ {
partialy = FRACUNIT - partialy; partialy = 1. - partialy;
} }
if (partialx == partialy) if (partialx == partialy)
{ {
xintercept = xt1 << FRACBITS; xintercept = xt1;
yintercept = yt1 << FRACBITS; yintercept = yt1;
} }
} }
// Step through map blocks. // Step through map blocks.
// Count is present to prevent a round off error // Count is present to prevent a round off error
// from skipping the break statement. // from skipping the break statement.
mapx = xt1;
mapy = yt1;
bool compatible = (flags & PT_COMPATIBLE) && (i_compatflags & COMPATF_HITSCAN); 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. // [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! case 0: // neither xintercept nor yintercept match!
count = 100; // Stop traversing, because somebody screwed up. 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; 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 (!in->isaline || !in->d.line->isLinePortal()) return false;
if (P_PointOnLineSidePrecise(trace.x, trace.y, in->d.line) == 1) return false; if (P_PointOnLineSidePrecise(trace.x, trace.y, in->d.line) == 1) return false;
fixed_t hitx = trace.x; double hitx = trace.x;
fixed_t hity = trace.y; double hity = trace.y;
fixed_t endx = trace.x + trace.dx; double endx = trace.x + trace.dx;
fixed_t endy = trace.y + trace.dy; double endy = trace.y + trace.dy;
P_TranslatePortalXY(in->d.line, hitx, hity); P_TranslatePortalXY(in->d.line, hitx, hity);
P_TranslatePortalXY(in->d.line, endx, endy); 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 // [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. // add on a 386/486, but it certainly isn't on anything newer than that.
fixed_t dx; auto x = FloatToFixed(xx);
fixed_t dy; auto y = FloatToFixed(yy);
double left; double left;
double right; double right;
@ -1897,8 +1815,8 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node)
return node->dx > 0; return node->dx > 0;
} }
dx = (x - node->x); auto dx = (x - node->x);
dy = (y - node->y); auto dy = (y - node->y);
// Try to quickly decide by looking at sign bits. // Try to quickly decide by looking at sign bits.
if ((node->dy ^ node->dx ^ dx ^ dy) & 0x80000000) 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. // 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; left = (double)node->dy * (double)dx;
right = (double)dy * (double)node->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(); DVector2 delta = line->Delta();
if (delta.X == 0) if (delta.X == 0)
{ {
if (x <= line->v1->fixX()) if (x <= line->v1->fX())
return delta.Y > 0; return delta.Y > 0;
return delta.Y < 0; return delta.Y < 0;
} }
if (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;
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 // Note: This cannot really be converted to floating point
// without breaking the intended use of this function // 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()); auto dx = FloatToFixed(x - line->v1->fX());
dy = (y - line->v1->fixY()); auto dy = FloatToFixed(y - line->v1->fY());
left = FixedMul ( int(delta.Y * 256) , dx ); auto left = MulScale16( int(delta.Y * 256) , dx );
right = FixedMul ( dy , int(delta.X * 256) ); auto right = MulScale16( dy , int(delta.X * 256) );
if (right < left) if (right < left)
return 0; // front side return 0; // front side
@ -1973,16 +1888,18 @@ int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line)
//=========================================================================== //===========================================================================
// //
// P_VanillaPointOnDivlineSide // 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; int dx;
fixed_t dy; int dy;
fixed_t left; int left;
fixed_t right; int right;
int ldx;
int ldy;
if (!line->dx) if (!line->dx)
{ {
@ -1999,26 +1916,37 @@ int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const fdivline_t* line)
return line->dx > 0; return line->dx > 0;
} }
dx = (x - line->x); // This is supposed to be compatible so the rest needs to be done
dy = (y - line->y); // 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 // 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 1; // (left is negative)
return 0; return 0;
} }
left = FixedMul ( line->dy>>8, dx>>8 ); left = MulScale16( ldy>>8, dx>>8 );
right = FixedMul ( dy>>8 , line->dx>>8 ); right = MulScale16( dy>>8 , ldx>>8 );
if (right < left) if (right < left)
return 0; // front side return 0; // front side
return 1; // back 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 // single subsector is a special case
if (numgamenodes == 0) if (numgamenodes == 0)

View file

@ -8,14 +8,6 @@
extern int validcount; extern int validcount;
struct fdivline_t
{
fixed_t x;
fixed_t y;
fixed_t dx;
fixed_t dy;
};
struct divline_t struct divline_t
{ {
double x; double x;
@ -26,8 +18,7 @@ struct divline_t
struct intercept_t struct intercept_t
{ {
double Frac; double frac;
fixed_t frac; // along trace line
bool isaline; bool isaline;
bool done; bool done;
union { 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) 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) 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 // Same as P_PointOnLineSide except it uses divlines
// [RH] inlined, stripped down, and made more precise // [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 (y - line->y) * line->dx + (line->x - x) * line->dy > -EQUAL_EPSILON;
return (i_compatflags2 & COMPATF2_POINTONLINE)
? P_VanillaPointOnDivlineSide(x, y, line)
: (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0);
} }
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; return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > -EQUAL_EPSILON;
}
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;
} }
//========================================================================== //==========================================================================
@ -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) inline void P_MakeDivline(const line_t *li, divline_t *dl)
{ {
dl->x = li->v1->fX(); 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<const DVector2*>(ref), flags); P_LineOpening(open, thing, linedef, xy, reinterpret_cast<const DVector2*>(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; class FBoundingBox;
struct polyblock_t; struct polyblock_t;
@ -277,8 +226,8 @@ public:
class FMultiBlockLinesIterator class FMultiBlockLinesIterator
{ {
FPortalGroupArray &checklist; FPortalGroupArray &checklist;
fixedvec3 checkpoint; DVector3 checkpoint;
fixedvec2 offset; DVector2 offset;
sector_t *startsector; sector_t *startsector;
sector_t *cursector; sector_t *cursector;
short basegroup; short basegroup;
@ -289,8 +238,8 @@ class FMultiBlockLinesIterator
FBlockLinesIterator blockIterator; FBlockLinesIterator blockIterator;
FBoundingBox bbox; FBoundingBox bbox;
bool GoUp(fixed_t x, fixed_t y); bool GoUp(double x, double y);
bool GoDown(fixed_t x, fixed_t y); bool GoDown(double x, double y);
void startIteratorForGroup(int group); void startIteratorForGroup(int group);
public: public:
@ -298,18 +247,12 @@ public:
struct CheckResult struct CheckResult
{ {
line_t *line; line_t *line;
fixedvec3 position;
DVector3 Position; DVector3 Position;
int portalflags; int portalflags;
}; };
FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1); FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, double 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(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)
{
}
bool Next(CheckResult *item); bool Next(CheckResult *item);
void Reset(); void Reset();
@ -376,7 +319,7 @@ public:
class FMultiBlockThingsIterator class FMultiBlockThingsIterator
{ {
FPortalGroupArray &checklist; FPortalGroupArray &checklist;
fixedvec3 checkpoint; DVector3 checkpoint;
short basegroup; short basegroup;
short portalflags; short portalflags;
short index; short index;
@ -390,17 +333,12 @@ public:
struct CheckResult struct CheckResult
{ {
AActor *thing; AActor *thing;
fixedvec3 position; // keep these both until the fixed version can be removed.
DVector3 Position; DVector3 Position;
int portalflags; int portalflags;
}; };
FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1, bool ignorerestricted = false); FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, double 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(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)
{
}
bool Next(CheckResult *item); bool Next(CheckResult *item);
void Reset(); void Reset();
const FBoundingBox &Box() const const FBoundingBox &Box() const
@ -416,9 +354,8 @@ class FPathTraverse
protected: protected:
static TArray<intercept_t> intercepts; static TArray<intercept_t> intercepts;
divline_t ftrace; divline_t trace;
fdivline_t trace; double Startfrac;
fixed_t startfrac;
unsigned int intercept_index; unsigned int intercept_index;
unsigned int intercept_count; unsigned int intercept_count;
unsigned int count; unsigned int count;
@ -430,34 +367,21 @@ public:
intercept_t *Next(); 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); init(x1, y1, x2, y2, flags, startfrac);
} }
FPathTraverse(double x1, double y1, double x2, double y2, int flags, double startfrac = 0) void init(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);
int PortalRelocate(intercept_t *in, int flags, DVector3 *optpos = NULL); int PortalRelocate(intercept_t *in, int flags, DVector3 *optpos = NULL);
virtual ~FPathTraverse(); virtual ~FPathTraverse();
const fdivline_t &_f_Trace() const { return trace; } const divline_t &Trace() const { return trace; }
const divline_t &Trace() const { return ftrace; }
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) inline DVector2 InterceptPoint(const intercept_t *in)
{ {
return return
{ {
FIXED2DBL(trace.x + FixedMul(trace.dx, in->frac)), trace.x + trace.dx * in->frac,
FIXED2DBL(trace.y + FixedMul(trace.dy, in->frac)) trace.y + trace.dy * in->frac
}; };
} }
@ -480,18 +404,13 @@ public:
} }
}; };
// //
// P_MAPUTL // P_MAPUTL
// //
typedef bool(*traverser_t) (intercept_t *in); typedef bool(*traverser_t) (intercept_t *in);
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); int P_AproxDistance (int dx, int dy);
fixed_t P_InterceptVector (const fdivline_t *v2, const fdivline_t *v1);
double P_InterceptVector(const divline_t *v2, const divline_t *v1); double P_InterceptVector(const divline_t *v2, const divline_t *v1);
#define PT_ADDLINES 1 #define PT_ADDLINES 1

View file

@ -1401,9 +1401,9 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
den = line->Delta().LengthSquared(); den = line->Delta().LengthSquared();
if (den != 0) if (den != 0)
{ {
frac = clamp<double>((mo->Pos() - line->V1()) | line->Delta(), 0, den) / den; frac = clamp<double>((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; F3DFloor * ffloor=NULL;
if (line->sidedef[side^1] != NULL) if (line->sidedef[side^1] != NULL)

View file

@ -232,7 +232,7 @@ void DPusher::Tick ()
// point pusher. Crosses sectors, so use blockmap. // point pusher. Crosses sectors, so use blockmap.
FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); // no sector portals because this thing is utterly z-unaware. 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; FMultiBlockThingsIterator::CheckResult cres;

View file

@ -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; int i;
double x = fx, y = fy; double x = in.X, y = in.Y;
double bestdist = HUGE_VAL; double bestdist = HUGE_VAL;
double bestx = 0, besty = 0; 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 *v1 = lines[i]->v1;
vertex_t *v2 = lines[i]->v2; vertex_t *v2 = lines[i]->v2;
double a = v2->fixX() - v1->fixX(); double a = v2->fX() - v1->fX();
double b = v2->fixY() - v1->fixY(); double b = v2->fY() - v1->fY();
double den = a*a + b*b; double den = a*a + b*b;
double ix, iy, dist; double ix, iy, dist;
if (den == 0) if (den == 0)
{ // Line is actually a point! { // Line is actually a point!
ix = v1->fixX(); ix = v1->fX();
iy = v1->fixY(); iy = v1->fY();
} }
else 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; double u = num / den;
if (u <= 0) if (u <= 0)
{ {
ix = v1->fixX(); ix = v1->fX();
iy = v1->fixY(); iy = v1->fY();
} }
else if (u >= 1) else if (u >= 1)
{ {
ix = v2->fixX(); ix = v2->fX();
iy = v2->fixY(); iy = v2->fY();
} }
else else
{ {
ix = v1->fixX() + u * a; ix = v1->fX() + u * a;
iy = v1->fixY() + u * b; iy = v1->fY() + u * b;
} }
} }
a = (ix - x); 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; besty = iy;
} }
} }
ox = fixed_t(bestx); out = { bestx, besty };
oy = fixed_t(besty);
} }

View file

@ -3208,14 +3208,14 @@ static void P_GroupLines (bool buildmap)
for (j = 0; j < sector->linecount; ++j) for (j = 0; j < sector->linecount; ++j)
{ {
li = sector->lines[j]; li = sector->lines[j];
bbox.AddToBox (li->v1->fixX(), li->v1->fixY()); bbox.AddToBox (li->v1->fPos());
bbox.AddToBox (li->v2->fixX(), li->v2->fixY()); bbox.AddToBox (li->v2->fPos());
} }
} }
// set the center to the middle of the bounding box // set the center to the middle of the bounding box
sector->centerspot.X = FIXED2DBL(bbox.Right()/2 + bbox.Left()/2); sector->centerspot.X = (bbox.Right() + bbox.Left()/2);
sector->centerspot.Y = FIXED2DBL(bbox.Top()/2 + bbox.Bottom()/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 // 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) if (sector->linecount == 3)
@ -3917,8 +3917,8 @@ void P_SetupLevel (const char *lumpname, int position)
seg_t * seg=&segs[i]; seg_t * seg=&segs[i];
if (seg->backsector == seg->frontsector && seg->linedef) 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()); double d1 = (seg->v1->fPos() - seg->linedef->v1->fPos()).LengthSquared();
fixed_t d2=P_AproxDistance(seg->v2->fixX()-seg->linedef->v1->fixX(),seg->v2->fixY()-seg->linedef->v1->fixY()); double d2 = (seg->v2->fPos() - seg->linedef->v1->fPos()).LengthSquared();
if (d2<d1) // backside if (d2<d1) // backside
{ {

View file

@ -207,8 +207,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
if ((i_compatflags & COMPATF_TRACE) && li->frontsector == li->backsector) if ((i_compatflags & COMPATF_TRACE) && li->frontsector == li->backsector)
return true; return true;
double trX = Trace.x + Trace.dx * in->Frac; double trX = Trace.x + Trace.dx * in->frac;
double trY = Trace.y + Trace.dy * in->Frac; double trY = Trace.y + Trace.dy * in->frac;
P_SightOpening (open, li, trX, trY); P_SightOpening (open, li, trX, trY);
FLinePortal *lport = li->getPortal(); FLinePortal *lport = li->getPortal();
@ -219,7 +219,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
// check bottom // check bottom
if (open.bottom > LINEOPEN_MIN) if (open.bottom > LINEOPEN_MIN)
{ {
slope = (open.bottom - sightstart.Z) / in->Frac; slope = (open.bottom - sightstart.Z) / in->frac;
if (slope > bottomslope) if (slope > bottomslope)
bottomslope = slope; bottomslope = slope;
} }
@ -227,7 +227,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
// check top // check top
if (open.top < LINEOPEN_MAX) if (open.top < LINEOPEN_MAX)
{ {
slope = (open.top - sightstart.Z) / in->Frac; slope = (open.top - sightstart.Z) / in->frac;
if (slope < topslope) if (slope < topslope)
topslope = slope; 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)) 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)) 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) 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; return false;
} }
@ -278,8 +278,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
sector_t * s=i==1? li->frontsector:li->backsector; sector_t * s=i==1? li->frontsector:li->backsector;
double highslope, lowslope; double highslope, lowslope;
double topz= topslope * in->Frac + sightstart.Z; double topz= topslope * in->frac + sightstart.Z;
double bottomz= bottomslope * in->Frac + sightstart.Z; double bottomz= bottomslope * in->frac + sightstart.Z;
for (auto rover : s->e->XFloor.ffloors) 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_bottom = rover->bottom.plane->ZatPoint(trX, trY);
double ff_top = rover->top.plane->ZatPoint(trX, trY); double ff_top = rover->top.plane->ZatPoint(trX, trY);
highslope = (ff_top - sightstart.Z) / in->Frac; highslope = (ff_top - sightstart.Z) / in->frac;
lowslope = (ff_bottom - sightstart.Z) / in->Frac; lowslope = (ff_bottom - sightstart.Z) / in->frac;
if (highslope >= topslope) 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 else lastsector=NULL; // don't need it if there are no 3D-floors
Lastztop = (topslope * in->Frac) + sightstart.Z; Lastztop = (topslope * in->frac) + sightstart.Z;
Lastzbottom = (bottomslope * in->Frac) + sightstart.Z; Lastzbottom = (bottomslope * in->frac) + sightstart.Z;
return true; // keep going return true; // keep going
} }
@ -375,14 +375,14 @@ bool SightCheck::P_SightCheckLine (line_t *ld)
return true; return true;
} }
ld->validcount = validcount; ld->validcount = validcount;
if (P_PointOnDivlineSidePrecise (ld->V1(), &Trace) == if (P_PointOnDivlineSide (ld->v1->fPos(), &Trace) ==
P_PointOnDivlineSidePrecise (ld->V2(), &Trace)) P_PointOnDivlineSide (ld->v2->fPos(), &Trace))
{ {
return true; // line isn't crossed return true; // line isn't crossed
} }
P_MakeDivline (ld, &dl); P_MakeDivline (ld, &dl);
if (P_PointOnDivlineSidePrecise (Trace.x, Trace.y, &dl) == if (P_PointOnDivlineSide (Trace.x, Trace.y, &dl) ==
P_PointOnDivlineSidePrecise (Trace.x+Trace.dx, Trace.y+Trace.dy, &dl)) P_PointOnDivlineSide (Trace.x+Trace.dx, Trace.y+Trace.dy, &dl))
{ {
return true; // line isn't crossed return true; // line isn't crossed
} }
@ -514,10 +514,10 @@ bool SightCheck::P_SightTraverseIntercepts ()
{ {
scan = &intercepts[scanpos]; scan = &intercepts[scanpos];
P_MakeDivline (scan->d.line, &dl); P_MakeDivline (scan->d.line, &dl);
scan->Frac = P_InterceptVector (&Trace, &dl); scan->frac = P_InterceptVector (&Trace, &dl);
if (scan->Frac < Startfrac) if (scan->frac < Startfrac)
{ {
scan->Frac = INT_MAX; scan->frac = INT_MAX;
count--; count--;
} }
} }
@ -534,9 +534,9 @@ bool SightCheck::P_SightTraverseIntercepts ()
for (scanpos = 0; scanpos < intercepts.Size (); scanpos++) for (scanpos = 0; scanpos < intercepts.Size (); scanpos++)
{ {
scan = &intercepts[scanpos]; scan = &intercepts[scanpos];
if (scan->Frac < dist) if (scan->frac < dist)
{ {
dist = scan->Frac; dist = scan->frac;
in = scan; in = scan;
} }
} }
@ -545,7 +545,7 @@ bool SightCheck::P_SightTraverseIntercepts ()
{ {
if (!PTR_SightTraverse (in)) if (!PTR_SightTraverse (in))
return false; // don't bother going farther return false; // don't bother going farther
in->Frac = INT_MAX; in->frac = INT_MAX;
} }
} }

View file

@ -69,7 +69,6 @@ typedef enum
// Factor to scale scrolling effect into mobj-carrying properties = 3/32. // 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.) // (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.; const double CARRYFACTOR = 3 / 32.;
// Define values for map objects // Define values for map objects

View file

@ -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 // which wasn't necessarily anywhere near the switch if it was
// facing a big sector (and which wasn't necessarily for the // facing a big sector (and which wasn't necessarily for the
// button just activated, either). // 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; bool playsound;
side->SetTexture(texture, Switch->frames[0].Texture); side->SetTexture(texture, Switch->frames[0].Texture);

View file

@ -438,7 +438,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO
} }
else else
{ {
double num = (thing->Pos().XY() - line->V1()) | line->Delta(); double num = (thing->Pos().XY() - line->v1->fPos()) | line->Delta();
if (num <= 0) if (num <= 0)
{ {
pos = 0; pos = 0;
@ -451,7 +451,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO
{ {
pos = num / den; 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 // 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; p.Y = npos.Y*c + npos.X*s;
// Interpolate position across the exit linedef // 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. // 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. // Voodoo dolls are excluded by making sure thing->player->mo==thing.

View file

@ -359,7 +359,7 @@ bool FTraceInfo::LineCheck(intercept_t *in)
int lineside; int lineside;
sector_t *entersector; sector_t *entersector;
double dist = MaxDist * in->Frac; double dist = MaxDist * in->frac;
DVector3 hit = Start + Vec * dist; DVector3 hit = Start + Vec * dist;
double ff, fc, bf = 0, bc = 0; 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)) 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) if (res != -1)
{ {
aimdir = INT_MAX; // flag for ending the traverse aimdir = INT_MAX; // flag for ending the traverse
@ -610,7 +610,7 @@ cont:
Results->HitPos = hit; Results->HitPos = hit;
SetSourcePosition(); SetSourcePosition();
Results->Distance = dist; Results->Distance = dist;
Results->Fraction = in->Frac; Results->Fraction = in->frac;
Results->Line = in->d.line; Results->Line = in->d.line;
Results->Side = lineside; Results->Side = lineside;
} }
@ -648,7 +648,7 @@ cont:
bool FTraceInfo::ThingCheck(intercept_t *in) bool FTraceInfo::ThingCheck(intercept_t *in)
{ {
double dist = MaxDist * in->Frac; double dist = MaxDist * in->frac;
DVector3 hit = Start + Vec * dist; DVector3 hit = Start + Vec * dist;
if (hit.Z > in->d.thing->Top()) 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; dist = (in->d.thing->Top() - Start.Z) / Vec.Z;
if (dist > MaxDist) return true; if (dist > MaxDist) return true;
in->Frac = dist / MaxDist; in->frac = dist / MaxDist;
hit = Start + Vec * dist; hit = Start + Vec * dist;
@ -675,7 +675,7 @@ bool FTraceInfo::ThingCheck(intercept_t *in)
// Does it hit the bottom of the actor? // Does it hit the bottom of the actor?
dist = (in->d.thing->Z() - Start.Z) / Vec.Z; dist = (in->d.thing->Z() - Start.Z) / Vec.Z;
if (dist > MaxDist) return true; if (dist > MaxDist) return true;
in->Frac = dist / MaxDist; in->frac = dist / MaxDist;
hit = Start + Vec * dist; hit = Start + Vec * dist;
@ -731,7 +731,7 @@ cont1:
Results->HitPos = hit; Results->HitPos = hit;
SetSourcePosition(); SetSourcePosition();
Results->Distance = dist; Results->Distance = dist;
Results->Fraction = in->Frac; Results->Fraction = in->frac;
Results->Actor = in->d.thing; Results->Actor = in->d.thing;
if (TraceCallback != NULL) if (TraceCallback != NULL)
@ -785,7 +785,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
} }
// We have something closer in the storage for portal subtraces. // 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; break;
} }

View file

@ -1216,14 +1216,14 @@ void FPolyObj::LinkPolyobj ()
vertex_t *vt; vertex_t *vt;
vt = Sidedefs[i]->linedef->v1; vt = Sidedefs[i]->linedef->v1;
Bounds.AddToBox(vt->fixX(), vt->fixY()); Bounds.AddToBox(vt->fPos());
vt = Sidedefs[i]->linedef->v2; vt = Sidedefs[i]->linedef->v2;
Bounds.AddToBox(vt->fixX(), vt->fixY()); Bounds.AddToBox(vt->fPos());
} }
bbox[BOXRIGHT] = GetBlockX(FIXED2DBL(Bounds.Right())); bbox[BOXRIGHT] = GetBlockX(Bounds.Right());
bbox[BOXLEFT] = GetBlockX(FIXED2DBL(Bounds.Left())); bbox[BOXLEFT] = GetBlockX(Bounds.Left());
bbox[BOXTOP] = GetBlockY(FIXED2DBL(Bounds.Top())); bbox[BOXTOP] = GetBlockY(Bounds.Top());
bbox[BOXBOTTOM] = GetBlockY(FIXED2DBL(Bounds.Bottom())); bbox[BOXBOTTOM] = GetBlockY(Bounds.Bottom());
// add the polyobj to each blockmap section // add the polyobj to each blockmap section
for(int j = bbox[BOXBOTTOM]*bmapwidth; j <= bbox[BOXTOP]*bmapwidth; for(int j = bbox[BOXBOTTOM]*bmapwidth; j <= bbox[BOXTOP]*bmapwidth;
j += bmapwidth) j += bmapwidth)

View file

@ -163,19 +163,19 @@ void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
for (unsigned i = 0; i<block.portallines.Size(); i++) for (unsigned i = 0; i<block.portallines.Size(); i++)
{ {
line_t *ld = block.portallines[i]; line_t *ld = block.portallines[i];
fixed_t frac; double frac;
fdivline_t dl; divline_t dl;
if (ld->validcount == validcount) continue; // already processed if (ld->validcount == validcount) continue; // already processed
if (P_PointOnDivlineSidePrecise (ld->v1->fixX(), ld->v1->fixY(), &trace) == if (P_PointOnDivlineSide (ld->v1->fPos(), &trace) ==
P_PointOnDivlineSidePrecise (ld->v2->fixX(), ld->v2->fixY(), &trace)) P_PointOnDivlineSide (ld->v2->fPos(), &trace))
{ {
continue; // line isn't crossed continue; // line isn't crossed
} }
P_MakeDivline (ld, &dl); P_MakeDivline (ld, &dl);
if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &dl) != 0 || if (P_PointOnDivlineSide(trace.x, trace.y, &dl) != 0 ||
P_PointOnDivlineSidePrecise (trace.x+trace.dx, trace.y+trace.dy, &dl) != 1) P_PointOnDivlineSide(trace.x + trace.dx, trace.y + trace.dy, &dl) != 1)
{ {
continue; // line isn't crossed from the front side continue; // line isn't crossed from the front side
} }
@ -183,7 +183,7 @@ void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
// hit the line // hit the line
P_MakeDivline(ld, &dl); P_MakeDivline(ld, &dl);
frac = P_InterceptVector(&trace, &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; intercept_t newintercept;
@ -252,8 +252,8 @@ static void SetRotation(FLinePortal *port)
line_t *dst = port->mDestination; line_t *dst = port->mDestination;
line_t *line = port->mOrigin; line_t *line = port->mOrigin;
DAngle angle = dst->Delta().Angle() - line->Delta().Angle() + 180.; DAngle angle = dst->Delta().Angle() - line->Delta().Angle() + 180.;
port->mSinRot = FLOAT2FIXED(angle.Sin()); port->mSinRot = sindeg(angle.Degrees); // Here precision matters so use the slower but more precise versions.
port->mCosRot = FLOAT2FIXED(angle.Cos()); port->mCosRot = cosdeg(angle.Degrees);
port->mAngleDiff = angle; 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. // 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 behind1 = P_GetLineSide(line->v1->fPos(), portal);
int behind2 = P_GetLineSide(line->v2->fixX(), line->v2->fixY(), portal); int behind2 = P_GetLineSide(line->v2->fPos(), portal);
if (behind1 == 0 && behind2 == 0) 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 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. // 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 viewside = P_GetLineSide(view, line);
int p1side = P_GetLineSide(portal->v1->fixX(), portal->v1->fixY(), line); int p1side = P_GetLineSide(portal->v1->fPos(), line);
int p2side = P_GetLineSide(portal->v2->fixX(), portal->v2->fixY(), line); int p2side = P_GetLineSide(portal->v2->fPos(), line);
// Do the same handling of points on the portal straight than above. // Do the same handling of points on the portal straight as above.
if (p1side == 0) p1side = p2side; if (p1side == 0) p1side = p2side;
else if (p2side == 0) p2side = p1side; 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. // 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); 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; if (!src) return;
FLinePortal *port = src->getPortal(); FLinePortal *port = src->getPortal();
if (!port) return; if (!port) return;
// offsets from line // offsets from line
fixed_t nposx = x - src->v1->fixX(); double nposx = x - src->v1->fX();
fixed_t nposy = y - src->v1->fixY(); double nposy = y - src->v1->fY();
// Rotate position along normal to match exit linedef // Rotate position along normal to match exit linedef
fixed_t tx = FixedMul(nposx, port->mCosRot) - FixedMul(nposy, port->mSinRot); double tx = nposx * port->mCosRot - nposy * port->mSinRot;
fixed_t ty = FixedMul(nposy, port->mCosRot) + FixedMul(nposx, port->mSinRot); double ty = nposy * port->mCosRot + nposx * port->mSinRot;
tx += port->mDestination->v2->fixX(); tx += port->mDestination->v2->fX();
ty += port->mDestination->v2->fixY(); ty += port->mDestination->v2->fY();
x = tx; x = tx;
y = ty; 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; if (!src) return;
FLinePortal *port = src->getPortal(); FLinePortal *port = src->getPortal();
if (!port) return; if (!port) return;
fixed_t orig_velx = vx; double orig_velx = velx;
fixed_t orig_vely = vy; double orig_vely = vely;
vx = FixedMul(orig_velx, port->mCosRot) - FixedMul(orig_vely, port->mSinRot); velx = orig_velx * port->mCosRot - orig_vely * port->mSinRot;
vy = FixedMul(orig_vely, port->mCosRot) + FixedMul(orig_velx, 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] = 0 - no adjustment
// args[2] = 1 - adjust by floor difference // args[2] = 1 - adjust by floor difference
@ -632,11 +626,11 @@ void P_TranslatePortalZ(line_t* src, fixed_t& z)
switch (src->getPortalAlignment()) switch (src->getPortalAlignment())
{ {
case PORG_FLOOR: 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; return;
case PORG_CEILING: 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; return;
default: 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 // 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) 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. // 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 blockx = GetBlockX(actx);
int blocky = GetBlockY(FIXED2DBL(acty)); int blocky = GetBlockY(acty);
if (blockx < 0 || blocky < 0 || blockx >= bmapwidth || blocky >= bmapheight || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest; 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. // Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence.
if (port->mFlags & PORTF_INTERACTIVE) if (port->mFlags & PORTF_INTERACTIVE)
{ {
fixedvec2 hit = it._f_InterceptPoint(in); DVector2 hit = it.InterceptPoint(in);
if (port->mType == PORTT_LINKED) if (port->mType == PORTT_LINKED)
{ {
// optimized handling for linked portals where we only need to add an offset. // optimized handling for linked portals where we only need to add an offset.
hit.x += FLOAT2FIXED(port->mDisplacement.X); hit += port->mDisplacement;
hit.y += FLOAT2FIXED(port->mDisplacement.Y); dest += port->mDisplacement;
dest.x += FLOAT2FIXED(port->mDisplacement.X);
dest.y += FLOAT2FIXED(port->mDisplacement.Y);
} }
else else
{ {
// interactive ones are more complex because the vector may be rotated. // 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. // 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, hit.X, hit.Y);
P_TranslatePortalXY(line, dest.x, dest.y); P_TranslatePortalXY(line, dest.X, dest.Y);
} }
// update the fields, end this trace and restart from the new position // update the fields, end this trace and restart from the new position
dx = dest.x - hit.x; dx = dest.X - hit.X;
dy = dest.y - hit.y; dy = dest.Y - hit.Y;
repeat = true; repeat = true;
} }
@ -814,13 +775,12 @@ static void AddDisplacementForPortal(AStackPoint *portal)
FDisplacement & disp = Displacements(thisgroup, othergroup); FDisplacement & disp = Displacements(thisgroup, othergroup);
if (!disp.isSet) if (!disp.isSet)
{ {
disp.pos.x = FLOAT2FIXED(portal->Scale.X); disp.pos = portal->Scale;
disp.pos.y = FLOAT2FIXED(portal->Scale.Y);
disp.isSet = true; disp.isSet = true;
} }
else 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); 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; portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL;
@ -850,13 +810,12 @@ static void AddDisplacementForPortal(FLinePortal *portal)
FDisplacement & disp = Displacements(thisgroup, othergroup); FDisplacement & disp = Displacements(thisgroup, othergroup);
if (!disp.isSet) if (!disp.isSet)
{ {
disp.pos.x = FLOAT2FIXED(portal->mDisplacement.X); disp.pos = portal->mDisplacement;
disp.pos.y = FLOAT2FIXED(portal->mDisplacement.Y);
disp.isSet = true; disp.isSet = true;
} }
else 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)); 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; portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
@ -897,7 +856,7 @@ static bool ConnectGroups()
FDisplacement &dispxz = Displacements(x, z); FDisplacement &dispxz = Displacements(x, z);
if (dispxz.isSet) 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; bogus = true;
} }
@ -1033,7 +992,7 @@ void P_CreateLinkedPortals()
FDisplacement &dispxy = Displacements(x, y); FDisplacement &dispxy = Displacements(x, y);
FDisplacement &dispyx = Displacements(y, x); FDisplacement &dispyx = Displacements(y, x);
if (dispxy.isSet && dispyx.isSet && 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; int sec1 = -1, sec2 = -1;
for (int i = 0; i < numsectors && (sec1 == -1 || sec2 == -1); i++) for (int i = 0; i < numsectors && (sec1 == -1 || sec2 == -1); i++)
@ -1119,7 +1078,7 @@ void P_CreateLinkedPortals()
if (!(actor->flags & MF_NOBLOCKMAP)) if (!(actor->flags & MF_NOBLOCKMAP))
{ {
FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); 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) if (check.Size() > 0)
{ {
actor->UnlinkFromWorld(); 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 // Keep this temporary work stuff static. This function can never be called recursively
// and this would have to be reallocated for each call otherwise. // 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); FDisplacement &disp = Displacements(thisgroup, othergroup);
if (!disp.isSet) continue; // no connection. 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 if (!box.inRange(ld) || box.BoxOnLineSide(linkedPortals[i]->mOrigin) != -1) continue; // not touched
foundPortals.Push(linkedPortals[i]); foundPortals.Push(linkedPortals[i]);
@ -1197,29 +1156,25 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t
} }
if (out.method != FPortalGroupArray::PGA_NoSectorPortals) 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; 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; sector_t *othersec = wsec->SkyBoxes[sector_t::ceiling]->Sector;
fixedvec2 pos = Displacements._f_getOffset(startgroup, othersec->PortalGroup); DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position;
fixed_t dx = position.x + pos.x;
fixed_t dy = position.y + pos.y;
processMask.setBit(othersec->PortalGroup); processMask.setBit(othersec->PortalGroup);
out.Add(othersec->PortalGroup | FPortalGroupArray::UPPER); 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; retval = true;
} }
wsec = sec; 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; sector_t *othersec = wsec->SkyBoxes[sector_t::floor]->Sector;
fixedvec2 pos = Displacements._f_getOffset(startgroup, othersec->PortalGroup); DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position;
fixed_t dx = position.x + pos.x;
fixed_t dy = position.y + pos.y;
processMask.setBit(othersec->PortalGroup | FPortalGroupArray::LOWER); processMask.setBit(othersec->PortalGroup | FPortalGroupArray::LOWER);
out.Add(othersec->PortalGroup); 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; retval = true;
} }
if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals) 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; int thisgroup = startgroup;
for (unsigned i = 0; i < groupsToCheck.Size();i++) for (unsigned i = 0; i < groupsToCheck.Size();i++)
{ {
fixedvec2 disp = Displacements._f_getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT); DVector2 disp = Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT);
FBoundingBox box(position.x + disp.x, position.y + disp.y, checkradius); FBoundingBox box(position.X + disp.X, position.Y + disp.Y, checkradius);
FBlockLinesIterator it(box); FBlockLinesIterator it(box);
line_t *ld; line_t *ld;
while ((ld = it.Next())) 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; sector_t *sec = s ? ld->backsector : ld->frontsector;
if (sec && !(sec->PortalBlocksMovement(sector_t::ceiling))) 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; int grp = sec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup;
if (!(processMask.getBit(grp))) 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; sector_t *sec = s ? ld->backsector : ld->frontsector;
if (sec && !(sec->PortalBlocksMovement(sector_t::floor))) 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; int grp = sec->SkyBoxes[sector_t::floor]->Sector->PortalGroup;
if (!(processMask.getBit(grp))) if (!(processMask.getBit(grp)))
@ -1297,7 +1252,7 @@ CCMD(dumplinktable)
for (int y = 1; y < Displacements.size; y++) for (int y = 1; y < Displacements.size; y++)
{ {
FDisplacement &disp = Displacements(x, 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"); Printf("\n");
} }

View file

@ -26,7 +26,7 @@ struct FPortalGroupArray;
struct FDisplacement struct FDisplacement
{ {
fixedvec2 pos; DVector2 pos;
bool isSet; bool isSet;
BYTE indirect; // just for illustration. BYTE indirect; // just for illustration.
@ -54,16 +54,6 @@ struct FDisplacementTable
return data[x + size*y]; 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 DVector2 getOffset(int x, int y) const
{ {
if (x == y) if (x == y)
@ -71,8 +61,7 @@ struct FDisplacementTable
DVector2 nulvec = { 0,0 }; DVector2 nulvec = { 0,0 };
return nulvec; // shortcut for the most common case return nulvec; // shortcut for the most common case
} }
fixedvec2 &p = data[x + size*y].pos; return data[x + size*y].pos;
return{ FIXED2DBL(p.x), FIXED2DBL(p.y) };
} }
}; };
@ -191,8 +180,8 @@ struct FLinePortal
BYTE mDefFlags; BYTE mDefFlags;
BYTE mAlign; BYTE mAlign;
DAngle mAngleDiff; DAngle mAngleDiff;
fixed_t mSinRot; double mSinRot;
fixed_t mCosRot; double mCosRot;
}; };
extern TArray<FLinePortal> linePortals; extern TArray<FLinePortal> linePortals;
@ -202,7 +191,7 @@ void P_SpawnLinePortal(line_t* line);
void P_FinalizePortals(); void P_FinalizePortals();
bool P_ChangePortal(line_t *ln, int thisid, int destid); bool P_ChangePortal(line_t *ln, int thisid, int destid);
void P_CreateLinkedPortals(); 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(); void P_CollectLinkedPortals();
inline int P_NumPortalGroups() inline int P_NumPortalGroups()
{ {
@ -211,43 +200,12 @@ inline int P_NumPortalGroups()
/* code ported from prototype */ /* 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); bool P_ClipLineToPortal(line_t* line, line_t* portal, DVector2 view, bool partial = true, bool samebehind = true);
void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y); void P_TranslatePortalXY(line_t* src, double& vx, double& vy);
inline void P_TranslatePortalXY(line_t* src, double& vx, double& vy) void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely);
{
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);
}
void P_TranslatePortalAngle(line_t* src, DAngle& angle); void P_TranslatePortalAngle(line_t* src, DAngle& angle);
void P_TranslatePortalZ(line_t* src, double& vz);
void P_TranslatePortalZ(line_t* src, fixed_t& z); DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy);
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) };
}
#endif #endif

View file

@ -555,7 +555,7 @@ void R_AddLine (seg_t *line)
// reject lines that aren't seen from the portal (if any) // 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. // [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; return;
vertex_t *v1, *v2; vertex_t *v1, *v2;

View file

@ -389,16 +389,6 @@ public:
return ic < 0 ? d : -d; 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) // Returns the value of z at (x,y)
fixed_t ZatPoint (fixed_t x, fixed_t y) const fixed_t ZatPoint (fixed_t x, fixed_t y) const
{ {
@ -489,11 +479,6 @@ public:
return -TMulScale16 (a, x, y, b, z, c); 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 fixed_t PointToDist (const vertex_t *v, fixed_t z) const
{ {
return -TMulScale16 (a, v->fixX(), b, v->fixY(), z, c); return -TMulScale16 (a, v->fixX(), b, v->fixY(), z, c);
@ -714,7 +699,7 @@ struct sector_t
void AdjustFloorClip () const; void AdjustFloorClip () const;
void SetColor(int r, int g, int b, int desat); void SetColor(int r, int g, int b, int desat);
void SetFade(int r, int g, int b); 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 GetFloorLight () const;
int GetCeilingLight () const; int GetCeilingLight () const;
sector_t *GetHeightSec() const; sector_t *GetHeightSec() const;
@ -1135,11 +1120,6 @@ struct sector_t
int validcount; // if == validcount, already checked int validcount; // if == validcount, already checked
AActor* thinglist; // list of mobjs in sector 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. // killough 8/28/98: friction is a sector property, not an mobj property.
// these fields used to be in AActor, but presented performance problems // these fields used to be in AActor, but presented performance problems
// when processed as mobj properties. Fix is to make them sector properties. // when processed as mobj properties. Fix is to make them sector properties.
@ -1477,31 +1457,11 @@ public:
unsigned portalindex; unsigned portalindex;
TObjPtr<ASkyViewpoint> skybox; TObjPtr<ASkyViewpoint> skybox;
DVector2 V1() const
{
return v1->fPos();
}
DVector2 V2() const
{
return v1->fPos();
}
DVector2 Delta() const DVector2 Delta() const
{ {
return{ FIXED2DBL(dx), FIXED2DBL(dy) }; 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) void setDelta(fixed_t x, fixed_t y)
{ {
dx = x; dx = x;
@ -1705,20 +1665,16 @@ struct visstyle_t
// not the same as R_PointInSubsector // not the same as R_PointInSubsector
// //
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
subsector_t *P_PointInSubsector(fixed_t x, fixed_t y); subsector_t *P_PointInSubsector(double x, double y);
inline sector_t *P_PointInSector(fixed_t x, fixed_t y)
{
return P_PointInSubsector(x, y)->sector;
}
inline sector_t *P_PointInSector(const DVector2 &pos) 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) 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 inline DVector3 AActor::PosRelative(int portalgroup) const
@ -1757,10 +1713,10 @@ inline void AActor::ClearInterpolation()
inline bool FBoundingBox::inRange(const line_t *ld) const inline bool FBoundingBox::inRange(const line_t *ld) const
{ {
return FIXED2DBL(Left()) < ld->bbox[BOXRIGHT] && return Left() < ld->bbox[BOXRIGHT] &&
FIXED2DBL(Right()) > ld->bbox[BOXLEFT] && Right() > ld->bbox[BOXLEFT] &&
FIXED2DBL(Top()) > ld->bbox[BOXBOTTOM] && Top() > ld->bbox[BOXBOTTOM] &&
FIXED2DBL(Bottom()) < ld->bbox[BOXTOP]; Bottom() < ld->bbox[BOXTOP];
} }

View file

@ -733,10 +733,14 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
} }
else else
{ {
P_TranslatePortalXY(pds->src, viewx, viewy); DVector3 view(FIXED2DBL(viewx), FIXED2DBL(viewy), FIXED2DBL(viewz));
P_TranslatePortalZ(pds->src, viewz);
DAngle va = ANGLE2DBL(viewangle); DAngle va = ANGLE2DBL(viewangle);
P_TranslatePortalXY(pds->src, view.X, view.Y);
P_TranslatePortalZ(pds->src, view.Z);
P_TranslatePortalAngle(pds->src, va); P_TranslatePortalAngle(pds->src, va);
viewx = FLOAT2FIXED(view.X);
viewy = FLOAT2FIXED(view.Y);
viewz = FLOAT2FIXED(view.Z);
viewangle = va.BAMs(); viewangle = va.BAMs();
} }

View file

@ -374,7 +374,7 @@ static inline bool R_ClipSpriteColumnWithPortals(fixed_t x, fixed_t y, vissprite
line_t* line = seg->curline->linedef; line_t* line = seg->curline->linedef;
// don't clip if the sprite is in front of the portal // 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; continue;
// now if current column is covered by this drawseg, we clip it away // now if current column is covered by this drawseg, we clip it away

View file

@ -57,6 +57,7 @@
#include "r_utility.h" #include "r_utility.h"
#include "d_player.h" #include "d_player.h"
#include "p_local.h" #include "p_local.h"
#include "p_maputl.h"
#include "math/cmath.h" #include "math/cmath.h"
@ -652,9 +653,9 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie
} }
else else
{ {
fixedvec2 disp = Displacements._f_getOffset(oldgroup, newgroup); DVector2 disp = Displacements.getOffset(oldgroup, newgroup);
viewx = iview->oviewx + FixedMul(frac, iview->nviewx - iview->oviewx - disp.x); viewx = iview->oviewx + FixedMul(frac, iview->nviewx - iview->oviewx - FLOAT2FIXED(disp.X));
viewy = iview->oviewy + FixedMul(frac, iview->nviewy - iview->oviewy - disp.y); viewy = iview->oviewy + FixedMul(frac, iview->nviewy - iview->oviewy - FLOAT2FIXED(disp.Y));
viewz = iview->oviewz + FixedMul(frac, iview->nviewz - iview->oviewz); viewz = iview->oviewz + FixedMul(frac, iview->nviewz - iview->oviewz);
} }
if (player != NULL && if (player != NULL &&

View file

@ -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; 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) 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; return DMulScale32(FLOAT2FIXED(pos.Y) - node->y, node->dx, node->x - FLOAT2FIXED(pos.X), node->dy) > 0;

View file

@ -104,8 +104,8 @@ static void S_ActivatePlayList(bool goBack);
static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel); static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel);
static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, const FPolyObj *poly, 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); 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 CalcSectorSoundOrg(const DVector3 &listenpos, const sector_t *sec, int channum, FVector3 &res);
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 &res);
static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly, 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); const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo *rolloff);
static void S_SetListener(SoundListener &listener, AActor *listenactor); 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) 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(); listenpos = listener->Pos();
x = FLOAT2FIXED(v.X); pgroup = listener->Sector->PortalGroup;
y = FLOAT2FIXED(v.Y);
z = FLOAT2FIXED(v.Z);
} }
else else
{ {
z = y = x = 0; listenpos.Zero();
pgroup = 0;
} }
// [BL] Moved this case out of the switch statement to make code easier // [BL] Moved this case out of the switch statement to make code easier
// on static analysis. // on static analysis.
if(type == SOURCE_Unattached) if(type == SOURCE_Unattached)
{ {
pos->X = pt[0]; sector_t *sec = P_PointInSector(pt[0], pt[2]);
pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : FIXED2FLOAT(y); DVector2 disp = Displacements.getOffset(pgroup, sec->PortalGroup);
pos->Z = pt[2]; 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 else
{ {
@ -692,10 +695,9 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
//assert(actor != NULL); //assert(actor != NULL);
if (actor != NULL) if (actor != NULL)
{ {
FVector3 v = actor->SoundPos(); DVector2 disp = Displacements.getOffset(pgroup, actor->Sector->PortalGroup);
x = FLOAT2FIXED(v.X); DVector3 posi = actor->Pos() + disp;
y = FLOAT2FIXED(v.Y); *pos = { (float)posi.X, (float)posi.Z, (float)posi.Y };
z = FLOAT2FIXED(v.Z);
} }
break; break;
@ -703,14 +705,19 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
assert(sector != NULL); assert(sector != NULL);
if (sector != NULL) if (sector != NULL)
{ {
DVector2 disp = Displacements.getOffset(pgroup, sector->PortalGroup);
if (chanflags & CHAN_AREA) 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 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; chanflags |= CHAN_LISTENERZ;
} }
} }
@ -718,17 +725,20 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
case SOURCE_Polyobj: case SOURCE_Polyobj:
assert(poly != NULL); 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; break;
} }
if ((chanflags & CHAN_LISTENERZ) && players[consoleplayer].camera != NULL) 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) 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)) if (!(i_compatflags & COMPATF_SECTORSOUNDS))
{ {
// Are we inside the sector? If yes, the closest point is the one we're on. // 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(); pos.X = (float)listenpos.X;
*x = FLOAT2FIXED(p.X); pos.Z = (float)listenpos.Y;
*y = FLOAT2FIXED(p.Y);
} }
else else
{ {
// Find the closest point on the sector's boundary lines and use // Find the closest point on the sector's boundary lines and use
// that as the perceived origin of the sound. // 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 else
{ {
*x = sec->_f_centerspot().x; pos.X = float(sec->centerspot.X);
*y = sec->_f_centerspot().y; pos.Z = float(sec->centerspot.Y);
} }
// Set sound vertical position based on channel. // Set sound vertical position based on channel.
if (channum == CHAN_FLOOR) if (channum == CHAN_FLOOR)
{ {
*z = MIN(sec->floorplane.ZatPoint(*x, *y), *z); pos.Y = (float)MIN<double>(sec->floorplane.ZatPoint(listenpos), listenpos.Z);
} }
else if (channum == CHAN_CEILING) else if (channum == CHAN_CEILING)
{ {
*z = MAX(sec->ceilingplane.ZatPoint(*x, *y), *z); pos.Y = (float)MAX<double>(sec->ceilingplane.ZatPoint(listenpos), listenpos.Z);
} }
else if (channum == CHAN_INTERIOR) else if (channum == CHAN_INTERIOR)
{ {
*z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y)); pos.Y = (float)clamp<double>(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; side_t *side;
sector_t *sec; sector_t *sec;
DVector2 pos(FIXED2DBL(*x), FIXED2DBL(*y)); DVector2 ppos;
poly->ClosestPoint(pos, pos, &side); poly->ClosestPoint(listenpos, ppos, &side);
*x = FLOAT2FIXED(pos.X); pos.X = (float)ppos.X;
*y = FLOAT2FIXED(pos.Y); pos.Z = (float)ppos.Y;
sec = side->sector; sec = side->sector;
*z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y)); pos.Y = (float)clamp<double>(listenpos.Z, sec->floorplane.ZatPoint(listenpos), sec->ceilingplane.ZatPoint(listenpos));
} }
//========================================================================== //==========================================================================

View file

@ -46,7 +46,7 @@
#include "math/cmath.h" #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 // make this a local inline function to avoid any dependencies on other headers and not pollute the global namespace
namespace pi namespace pi
@ -493,6 +493,11 @@ struct TVector3
return TVector3(v3.X + v2.X, v3.Y + v2.Y, v3.Z); 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) friend Vector2 operator+ (const Vector2 &v2, const TVector3 &v3)
{ {
return Vector2(v2.X + v3.X, v2.Y + v3.Y); return Vector2(v2.X + v3.X, v2.Y + v3.Y);
@ -500,11 +505,6 @@ struct TVector3
// Subtract a 3D vector and a 2D vector. // Subtract a 3D vector and a 2D vector.
// Discards the Z component of the 3D vector and returns 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<vec_t> &v2, const TVector3 &v3) friend Vector2 operator- (const TVector2<vec_t> &v2, const TVector3 &v3)
{ {
return Vector2(v2.X - v3.X, v2.Y - v3.Y); return Vector2(v2.X - v3.X, v2.Y - v3.Y);