diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d0447963..b7d4e7a9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,7 +164,7 @@ if( MSVC ) string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ) else() set( REL_LINKER_FLAGS "" ) - set( ALL_C_FLAGS "" ) + set( ALL_C_FLAGS "-ffp-contract=off" ) set( REL_C_FLAGS "" ) set( DEB_C_FLAGS "" ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e53749904..9f1fb8a7d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1159,6 +1159,22 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE g_shared/sbar_mugshot.cpp g_shared/shared_hud.cpp g_shared/shared_sbar.cpp + math/asin.c + math/atan.c + math/const.c + math/cosh.c + math/exp.c + math/isnan.c + math/log.c + math/log10.c + math/mtherr.c + math/polevl.c + math/sin.c + math/sinh.c + math/sqrt.c + math/tan.c + math/tanh.c + math/fastsin.cpp resourcefiles/ancientzip.cpp resourcefiles/file_7z.cpp resourcefiles/file_grp.cpp @@ -1355,6 +1371,7 @@ source_group("Games\\Hexen Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR source_group("Games\\Raven Shared" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_raven/.+") source_group("Games\\Strife Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_strife/.+") source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+") +source_group("Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/math/.+") source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+") source_group("Render Core\\Render Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_.+\\.h$") source_group("Render Core\\Render Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_.+\\.cpp$") diff --git a/src/actor.h b/src/actor.h index 76301fb3d..539144ed9 100644 --- a/src/actor.h +++ b/src/actor.h @@ -25,6 +25,7 @@ // Basics. #include "tables.h" +#include "templates.h" // We need the thinker_t stuff. #include "dthinker.h" @@ -414,24 +415,12 @@ enum ActorRenderFlag RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting) }; -#define TRANSLUC25 (FRACUNIT/4) -#define TRANSLUC33 (FRACUNIT/3) -#define TRANSLUC50 (FRACUNIT/2) -#define TRANSLUC66 ((FRACUNIT*2)/3) -#define TRANSLUC75 ((FRACUNIT*3)/4) - -// also #defines OPAQUE -#ifndef OPAQUE -#define OPAQUE (FRACUNIT) -#endif - // This translucency value produces the closest match to Heretic's TINTTAB. // ~40% of the value of the overlaid image shows through. -#define HR_SHADOW (0x6800) - +const double HR_SHADOW = (0x6800 / 65536.); // Hexen's TINTTAB is the same as Heretic's, just reversed. -#define HX_SHADOW (0x9800) -#define HX_ALTSHADOW (0x6800) +const double HX_SHADOW = (0x9800 / 65536.); +const double HX_ALTSHADOW = (0x6800 / 65536.); // This could easily be a bool but then it'd be much harder to find later. ;) enum replace_t @@ -533,6 +522,10 @@ enum EThingSpecialActivationType THINGSPEC_Switch = 1<<10, // The thing is alternatively activated and deactivated when triggered }; +#define ONFLOORZ FIXED_MIN +#define ONCEILINGZ FIXED_MAX +#define FLOATRANDZ (FIXED_MAX-1) + class FDecalBase; class AInventory; @@ -568,9 +561,7 @@ public: int Amount; }; -fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); // since we cannot include p_local here... -angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); // same reason here with r_defs.h - +const double MinVel = EQUAL_EPSILON; // Map Object definition. class AActor : public DThinker @@ -586,7 +577,7 @@ public: void Serialize (FArchive &arc); - static AActor *StaticSpawn (PClassActor *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement, bool SpawningMapThing = false); + static AActor *StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false); inline AActor *GetDefault () const { @@ -596,11 +587,11 @@ public: DDropItem *GetDropItems() const; // Return true if the monster should use a missile attack, false for melee - bool SuggestMissileAttack (fixed_t dist); + bool SuggestMissileAttack (double dist); // Adjusts the angle for deflection/reflection of incoming missiles // Returns true if the missile should be allowed to explode anyway - bool AdjustReflectionAngle (AActor *thing, angle_t &angle); + bool AdjustReflectionAngle (AActor *thing, DAngle &angle); // Returns true if this actor is within melee range of its target bool CheckMeleeRange(); @@ -644,7 +635,7 @@ public: // Called when an actor is to be reflected by a disc of repulsion. // Returns true to continue normal blast processing. - virtual bool SpecialBlastHandling (AActor *source, fixed_t strength); + virtual bool SpecialBlastHandling (AActor *source, double strength); // Called by RoughBlockCheck bool IsOkayToAttack (AActor *target); @@ -743,18 +734,18 @@ public: inline bool IsNoClip2() const; void CheckPortalTransition(bool islinked); - fixedvec3 GetPortalTransition(fixed_t byoffset, sector_t **pSec = NULL); + DVector3 GetPortalTransition(double byoffset, sector_t **pSec = NULL); // What species am I? virtual FName GetSpecies(); - fixed_t GetBobOffset(fixed_t ticfrac=0) const + double GetBobOffset(double ticfrac = 0) const { - if (!(flags2 & MF2_FLOATBOB)) - { - return 0; - } - return finesine[MulScale22(((FloatBobPhase + level.maptime) << FRACBITS) + ticfrac, FINEANGLES) & FINEMASK] * 8; + if (!(flags2 & MF2_FLOATBOB)) + { + return 0; + } + return BobSin(FloatBobPhase + level.maptime + ticfrac); } // Enter the crash state @@ -763,7 +754,7 @@ public: // Return starting health adjusted by skill level int SpawnHealth() const; int GetGibHealth() const; - fixed_t GetCameraHeight() const; + double GetCameraHeight() const; inline bool isMissile(bool precise=true) { @@ -782,9 +773,9 @@ public: } // These also set CF_INTERPVIEW for players. - void SetPitch(int p, bool interpolate, bool forceclamp = false); - void SetAngle(angle_t ang, bool interpolate); - void SetRoll(angle_t roll, bool interpolate); + void SetPitch(DAngle p, bool interpolate, bool forceclamp = false); + void SetAngle(DAngle ang, bool interpolate); + void SetRoll(DAngle roll, bool interpolate); PClassActor *GetBloodType(int type = 0) const { @@ -813,142 +804,137 @@ public: return bloodcls; } - fixed_t AproxDistance(fixed_t otherx, fixed_t othery) + double Distance2D(AActor *other, bool absolute = false) { - return P_AproxDistance(X() - otherx, Y() - othery); + DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return (Pos().XY() - otherpos).Length(); } - fixed_t AngleTo(fixed_t otherx, fixed_t othery) + double Distance2D(double x, double y) const { - return R_PointToAngle2(X(), Y(), otherx, othery); + return DVector2(X() - x, Y() - y).Length(); } - fixed_t AngleTo(fixedvec2 other) + double Distance2D(AActor *other, double xadd, double yadd, bool absolute = false) { - return R_PointToAngle2(X(), Y(), other.x, other.y); + DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return DVector2(X() - otherpos.X + xadd, Y() - otherpos.Y + yadd).Length(); } - // 'absolute' is reserved for a linked portal implementation which needs - // to distinguish between portal-aware and portal-unaware distance calculation. - fixed_t AproxDistance(AActor *other, bool absolute = false) - { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return P_AproxDistance(X() - otherpos.x, Y() - otherpos.y); - } - - fixed_t AproxDistance(AActor *other, fixed_t xadd, fixed_t yadd, bool absolute = false) - { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return P_AproxDistance(X() - otherpos.x + xadd, Y() - otherpos.y + yadd); - } - - fixed_t AproxDistance3D(AActor *other, bool absolute = false) - { - return P_AproxDistance(AproxDistance(other), Z() - other->Z()); - } - - // more precise, but slower version, being used in a few places - fixed_t Distance2D(AActor *other, bool absolute = false) - { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return xs_RoundToInt(DVector2(X() - otherpos.x, Y() - otherpos.y).Length()); - } // a full 3D version of the above - fixed_t Distance3D(AActor *other, bool absolute = false) + double Distance3D(AActor *other, bool absolute = false) { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return xs_RoundToInt(DVector3(X() - otherpos.x, Y() - otherpos.y, Z() - otherpos.z).Length()); + DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return (Pos() - otherpos).Length(); } - angle_t AngleTo(AActor *other, bool absolute = false) + DAngle AngleTo(AActor *other, bool absolute = false) { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return R_PointToAngle2(X(), Y(), otherpos.x, otherpos.y); + DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return VecToAngle(otherpos - Pos().XY()); } - angle_t AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const + DAngle AngleTo(AActor *other, double oxofs, double oyofs, bool absolute = false) const { - return R_PointToAngle2(X(), Y(), other->X() + oxofs, other->Y() + oyofs); + DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return VecToAngle(otherpos - Pos() + DVector2(oxofs, oyofs)); } - fixedvec2 Vec2To(AActor *other) const + DVector2 Vec2To(AActor *other) const { - fixedvec3 otherpos = other->PosRelative(this); - fixedvec2 ret = { otherpos.x - X(), otherpos.y - Y() }; - return ret; + return other->PosRelative(this) - Pos(); } - fixedvec3 Vec3To(AActor *other) const + DVector3 Vec3To(AActor *other) const { - fixedvec3 otherpos = other->PosRelative(this); - fixedvec3 ret = { otherpos.x - X(), otherpos.y - Y(), otherpos.z - Z() }; - return ret; + return other->PosRelative(this) - Pos(); } - fixedvec2 Vec2Offset(fixed_t dx, fixed_t dy, bool absolute = false) + DVector2 Vec2Offset(double dx, double dy, bool absolute = false) { if (absolute) { - fixedvec2 ret = { X() + dx, Y() + dy }; - return ret; - } - else return P_GetOffsetPosition(X(), Y(), dx, dy); - } - - - fixedvec2 Vec2Angle(fixed_t length, angle_t angle, bool absolute = false) - { - if (absolute) - { - fixedvec2 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), - Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) }; - return ret; - } - else return P_GetOffsetPosition(X(), Y(), FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), FixedMul(length, finesine[angle >> ANGLETOFINESHIFT])); - } - - fixedvec3 Vec3Offset(fixed_t dx, fixed_t dy, fixed_t dz, bool absolute = false) - { - if (absolute) - { - fixedvec3 ret = { X() + dx, Y() + dy, Z() + dz }; - return ret; + return { X() + dx, Y() + dy }; } else { - fixedvec2 op = P_GetOffsetPosition(X(), Y(), dx, dy); - fixedvec3 pos = { op.x, op.y, Z() + dz }; - return pos; + return P_GetOffsetPosition(X(), Y(), dx, dy); } } - fixedvec3 Vec3Angle(fixed_t length, angle_t angle, fixed_t dz, bool absolute = false) + + DVector3 Vec2OffsetZ(double dx, double dy, double atz, bool absolute = false) { if (absolute) { - fixedvec3 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), - Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]), Z() + dz }; - return ret; + return{ X() + dx, Y() + dy, atz }; } else { - fixedvec2 op = P_GetOffsetPosition(X(), Y(), FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), FixedMul(length, finesine[angle >> ANGLETOFINESHIFT])); - fixedvec3 pos = { op.x, op.y, Z() + dz }; - return pos; + DVector2 v = P_GetOffsetPosition(X(), Y(), dx, dy); + return DVector3(v, atz); } } + DVector2 Vec2Angle(double length, DAngle angle, bool absolute = false) + { + if (absolute) + { + return{ X() + length * angle.Cos(), Y() + length * angle.Sin() }; + } + else + { + return P_GetOffsetPosition(X(), Y(), length*angle.Cos(), length*angle.Sin()); + } + } + + DVector3 Vec3Offset(double dx, double dy, double dz, bool absolute = false) + { + if (absolute) + { + return { X() + dx, Y() + dy, Z() + dz }; + } + else + { + DVector2 v = P_GetOffsetPosition(X(), Y(), dx, dy); + return DVector3(v, Z() + dz); + } + } + + DVector3 Vec3Offset(const DVector3 &ofs, bool absolute = false) + { + return Vec3Offset(ofs.X, ofs.Y, ofs.Z, absolute); + } + + DVector3 Vec3Angle(double length, DAngle angle, double dz, bool absolute = false) + { + if (absolute) + { + return{ X() + length * angle.Cos(), Y() + length * angle.Sin(), Z() + dz }; + } + else + { + DVector2 v = P_GetOffsetPosition(X(), Y(), length*angle.Cos(), length*angle.Sin()); + return DVector3(v, Z() + dz); + } + } + + double AccuracyFactor() + { + return 1. / (1 << (accuracy * 5 / 100)); + } + void ClearInterpolation(); - void Move(fixed_t dx, fixed_t dy, fixed_t dz) + void Move(const DVector3 &vel) { - SetOrigin(X() + dx, Y() + dy, Z() + dz, true); + SetOrigin(Pos() + vel, true); } - - void SetOrigin(const fixedvec3 & npos, bool moving) + virtual void SetOrigin(double x, double y, double z, bool moving); + void SetOrigin(const DVector3 & npos, bool moving) { - SetOrigin(npos.x, npos.y, npos.z, moving); + SetOrigin(npos.X, npos.Y, npos.Z, moving); } inline void SetFriendPlayer(player_t *player); @@ -960,7 +946,7 @@ public: bool CanSeek(AActor *target) const; - fixed_t GetGravity() const; + double GetGravity() const; bool IsSentient() const; const char *GetTag(const char *def = NULL) const; void SetTag(const char *def); @@ -971,36 +957,39 @@ public: // info for drawing // NOTE: The first member variable *must* be snext. AActor *snext, **sprev; // links in sector (if needed) - fixedvec3 __pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions. + DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions. + + DRotator Angles; + DVector3 Vel; + double Speed; + double FloatSpeed; - angle_t angle; WORD sprite; // used to find patch_t and flip value BYTE frame; // sprite frame to draw - fixed_t scaleX, scaleY; // Scaling values; FRACUNIT is normal size + DVector2 Scale; // Scaling values; 1 is normal size FRenderStyle RenderStyle; // Style to draw this actor with ActorRenderFlags renderflags; // Different rendering flags FTextureID picnum; // Draw this instead of sprite if valid DWORD effects; // [RH] see p_effect.h - fixed_t alpha; + double Alpha; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double. DWORD fillcolor; // Color to draw when STYLE_Shaded // interaction info - fixed_t pitch; - angle_t roll; // This was fixed_t before, which is probably wrong FBlockNode *BlockNode; // links in blocks (if needed) struct sector_t *Sector; subsector_t * subsector; - fixed_t floorz, ceilingz; // closest together of contacted secs - fixed_t dropoffz; // killough 11/98: the lowest floor over all contacted Sectors. + double floorz, ceilingz; // closest together of contacted secs + double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors. struct sector_t *floorsector; FTextureID floorpic; // contacted sec floorpic int floorterrain; struct sector_t *ceilingsector; FTextureID ceilingpic; // contacted sec ceilingpic - fixed_t radius, height; // for movement checking - fixed_t projectilepassheight; // height for clipping projectile movement against this actor - fixedvec3 vel; + double radius, Height; // for movement checking + + double projectilepassheight; // height for clipping projectile movement against this actor + SDWORD tics; // state tic counter FState *state; VMFunction *Damage; // For missiles and monster railgun @@ -1018,6 +1007,9 @@ public: int special1; // Special info int special2; // Special info + double specialf1; // With floats we cannot use the int versions for storing position or angle data without reverting to fixed point (which we do not want.) + double specialf2; + int weaponspecial; // Special info for weapons. int health; BYTE movedir; // 0-7 @@ -1035,7 +1027,7 @@ public: // no matter what (even if shot) player_t *player; // only valid if type of APlayerPawn TObjPtr LastLookActor; // Actor last looked for (if TIDtoHate != 0) - fixed_t SpawnPoint[3]; // For nightmare respawn + DVector3 SpawnPoint; // For nightmare respawn WORD SpawnAngle; int StartHealth; BYTE WeaveIndexXY; // Separated from special2 because it's used by globally accessible functions. @@ -1045,7 +1037,8 @@ public: FNameNoInit Species; // For monster families TObjPtr tracer; // Thing being chased/attacked for tracers TObjPtr master; // Thing which spawned this one (prevents mutual attacks) - fixed_t floorclip; // value to use for floor clipping + double Floorclip; // value to use for floor clipping + int tid; // thing identifier int special; // special int args[5]; // special arguments @@ -1060,18 +1053,18 @@ public: SBYTE LastLookPlayerNumber;// Player number last looked for (if TIDtoHate == 0) ActorBounceFlags BounceFlags; // which bouncing type? DWORD SpawnFlags; // Increased to DWORD because of Doom 64 - fixed_t meleerange; // specifies how far a melee attack reaches. - fixed_t meleethreshold; // Distance below which a monster doesn't try to shoot missiles anynore + double meleerange; // specifies how far a melee attack reaches. + double meleethreshold; // Distance below which a monster doesn't try to shoot missiles anynore // but instead tries to come closer for a melee attack. // This is not the same as meleerange - fixed_t maxtargetrange; // any target farther away cannot be attacked - fixed_t bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70. - fixed_t wallbouncefactor; // The bounce factor for walls can be different. + double maxtargetrange; // any target farther away cannot be attacked + double bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70. + double wallbouncefactor; // The bounce factor for walls can be different. int bouncecount; // Strife's grenades only bounce twice before exploding - fixed_t gravity; // [GRB] Gravity factor - fixed_t Friction; + double Gravity; // [GRB] Gravity factor + double Friction; int FastChaseStrafeCount; - fixed_t pushfactor; + double pushfactor; int lastpush; int activationtype; // How the thing behaves when activated with USESPECIAL or BUMPSPECIAL int lastbump; // Last time the actor was bumped, used to control BUMPSPECIAL @@ -1115,16 +1108,16 @@ public: FSoundIDNoInit WallBounceSound; FSoundIDNoInit CrushPainSound; - fixed_t Speed; - fixed_t FloatSpeed; - fixed_t MaxDropOffHeight, MaxStepHeight; + double MaxDropOffHeight; + double MaxStepHeight; + SDWORD Mass; SWORD PainChance; int PainThreshold; FNameNoInit DamageType; FNameNoInit DamageTypeReceived; - fixed_t DamageFactor; - fixed_t DamageMultiply; + double DamageFactor; + double DamageMultiply; FNameNoInit PainType; FNameNoInit DeathType; @@ -1147,8 +1140,8 @@ public: FDecalBase *DecalGenerator; // [RH] Used to interpolate the view to get >35 FPS - fixed_t PrevX, PrevY, PrevZ; - angle_t PrevAngle; + DVector3 Prev; + DRotator PrevAngles; int PrevPortalGroup; // ThingIDs @@ -1156,6 +1149,7 @@ public: void AddToHash (); void RemoveFromHash (); + private: static AActor *TIDHash[128]; static inline int TIDHASH (int key) { return key & 127; } @@ -1170,11 +1164,10 @@ public: void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL); void UnlinkFromWorld (); void AdjustFloorClip (); - void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false); bool InStateSequence(FState * newstate, FState * basestate); int GetTics(FState * newstate); bool SetState (FState *newstate, bool nofunction=false); - virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true); + virtual bool UpdateWaterLevel (bool splash=true); bool isFast(); bool isSlow(); void SetIdle(bool nofunction=false); @@ -1200,90 +1193,168 @@ public: bool HasSpecialDeathStates () const; - fixed_t X() const + double X() const { - return __pos.x; + return __Pos.X; } - fixed_t Y() const + double Y() const { - return __pos.y; + return __Pos.Y; } - fixed_t Z() const + double Z() const { - return __pos.z; + return __Pos.Z; } - fixedvec3 Pos() const + DVector3 Pos() const { - return __pos; + return __Pos; + } + // Note: Never compare z directly with a plane height if you want to know if the actor is *on* the plane. Some very minor inaccuracies may creep in. Always use these inline functions! + // Comparing with floorz is ok because those values come from the same calculations. + bool isAbove(double checkz) const + { + return Z() > checkz + EQUAL_EPSILON; + } + bool isBelow(double checkz) const + { + return Z() < checkz - EQUAL_EPSILON; + } + bool isAtZ(double checkz) const + { + return fabs(Z() - checkz) < EQUAL_EPSILON; } - fixedvec3 PosRelative(int grp) const; - fixedvec3 PosRelative(const AActor *other) const; - fixedvec3 PosRelative(sector_t *sec) const; - fixedvec3 PosRelative(line_t *line) const; + DVector3 PosRelative(int grp) const; + DVector3 PosRelative(const AActor *other) const; + DVector3 PosRelative(sector_t *sec) const; + DVector3 PosRelative(line_t *line) const; - fixed_t SoundX() const + FVector3 SoundPos() const { - return X(); + // the sound system switches y and z axes so this function must, too. + // fixme: This still needs portal handling + return{ float(X()), float(Z()), float(Y()) }; } - fixed_t SoundY() const + DVector3 InterpolatedPosition(double ticFrac) const { - return Y(); + return Prev + (ticFrac * (Pos() - Prev)); } - fixed_t SoundZ() const + DVector3 PosPlusZ(double zadd) const { - return Z(); + return { X(), Y(), Z() + zadd }; } - fixedvec3 InterpolatedPosition(fixed_t ticFrac) const + DVector3 PosAtZ(double zadd) const { - fixedvec3 ret; - - ret.x = PrevX + FixedMul (ticFrac, X() - PrevX); - ret.y = PrevY + FixedMul (ticFrac, Y() - PrevY); - ret.z = PrevZ + FixedMul (ticFrac, Z() - PrevZ); - return ret; + return{ X(), Y(), zadd }; } - fixedvec3 PosPlusZ(fixed_t zadd) const + double Top() const { - fixedvec3 ret = { X(), Y(), Z() + zadd }; - return ret; + return Z() + Height; } - fixed_t Top() const + double Center() const { - return Z() + height; + return Z() + Height/2; } - void SetZ(fixed_t newz, bool moving = true) + void SetZ(double newz, bool moving = true) { - __pos.z = newz; + __Pos.Z = newz; } - void AddZ(fixed_t newz, bool moving = true) + void AddZ(double newz, bool moving = true) { - __pos.z += newz; + __Pos.Z += newz; + if (!moving) Prev.Z = Z(); } - // These are not for general use as they do not link the actor into the world! - void SetXY(fixed_t xx, fixed_t yy) + void SetXY(const DVector2 &npos) { - __pos.x = xx; - __pos.y = yy; + __Pos.X = npos.X; + __Pos.Y = npos.Y; } - void SetXYZ(fixed_t xx, fixed_t yy, fixed_t zz) + void SetXYZ(double xx, double yy, double zz) { - __pos.x = xx; - __pos.y = yy; - __pos.z = zz; + __Pos = { xx,yy,zz }; } - void SetXY(const fixedvec2 &npos) + void SetXYZ(const DVector3 &npos) { - __pos.x = npos.x; - __pos.y = npos.y; + __Pos = npos; } - void SetXYZ(const fixedvec3 &npos) + + double VelXYToSpeed() const { - __pos.x = npos.x; - __pos.y = npos.y; - __pos.z = npos.z; + return DVector2(Vel.X, Vel.Y).Length(); } + + double VelToSpeed() const + { + return Vel.Length(); + } + + void AngleFromVel() + { + Angles.Yaw = VecToAngle(Vel.X, Vel.Y); + } + + void VelFromAngle() + { + Vel.X = Speed * Angles.Yaw.Cos(); + Vel.Y = Speed * Angles.Yaw.Sin(); + } + + void VelFromAngle(double speed) + { + Vel.X = speed * Angles.Yaw.Cos(); + Vel.Y = speed * Angles.Yaw.Sin(); + } + + void VelFromAngle(DAngle angle, double speed) + { + Vel.X = speed * angle.Cos(); + Vel.Y = speed * angle.Sin(); + } + + void Thrust() + { + Vel.X += Speed * Angles.Yaw.Cos(); + Vel.Y += Speed * Angles.Yaw.Sin(); + } + + void Thrust(double speed) + { + Vel.X += speed * Angles.Yaw.Cos(); + Vel.Y += speed * Angles.Yaw.Sin(); + } + + void Thrust(DAngle angle, double speed) + { + Vel.X += speed * angle.Cos(); + Vel.Y += speed * angle.Sin(); + } + + void Vel3DFromAngle(DAngle angle, DAngle pitch, double speed) + { + double cospitch = pitch.Cos(); + Vel.X = speed * cospitch * angle.Cos(); + Vel.Y = speed * cospitch * angle.Sin(); + Vel.Z = speed * -pitch.Sin(); + } + + void Vel3DFromAngle(DAngle pitch, double speed) + { + double cospitch = pitch.Cos(); + Vel.X = speed * cospitch * Angles.Yaw.Cos(); + Vel.Y = speed * cospitch * Angles.Yaw.Sin(); + Vel.Z = speed * -pitch.Sin(); + } + + // This is used by many vertical velocity calculations. + // Better have it in one place, if something needs to be changed about the formula. + double DistanceBySpeed(AActor *dest, double speed) + { + return MAX(1., Distance2D(dest) / speed); + } + + int ApplyDamageFactor(FName damagetype, int damage) const; + }; class FActorIterator @@ -1352,56 +1423,46 @@ public: bool P_IsTIDUsed(int tid); int P_FindUniqueTID(int start_tid, int limit); -inline AActor *Spawn (PClassActor *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) +PClassActor *ClassForSpawn(FName classname); + +inline AActor *Spawn(PClassActor *type) { - return AActor::StaticSpawn (type, x, y, z, allowreplacement); -} -inline AActor *Spawn (PClassActor *type, const fixedvec3 &pos, replace_t allowreplacement) -{ - return AActor::StaticSpawn (type, pos.x, pos.y, pos.z, allowreplacement); + return AActor::StaticSpawn(type, DVector3(0, 0, 0), NO_REPLACE); } -AActor *Spawn (const char *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement); -AActor *Spawn (FName classname, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement); - -inline AActor *Spawn (const char *type, const fixedvec3 &pos, replace_t allowreplacement) +inline AActor *Spawn(PClassActor *type, const DVector3 &pos, replace_t allowreplacement) { - return Spawn (type, pos.x, pos.y, pos.z, allowreplacement); + return AActor::StaticSpawn(type, pos, allowreplacement); } -inline AActor *Spawn (FName classname, const fixedvec3 &pos, replace_t allowreplacement) +inline AActor *Spawn(FName type) { - return Spawn (classname, pos.x, pos.y, pos.z, allowreplacement); + return AActor::StaticSpawn(ClassForSpawn(type), DVector3(0, 0, 0), NO_REPLACE); } - -template -inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) +inline AActor *Spawn(FName type, const DVector3 &pos, replace_t allowreplacement) { - return static_cast(AActor::StaticSpawn (RUNTIME_TEMPLATE_CLASS(T), x, y, z, allowreplacement)); + return AActor::StaticSpawn(ClassForSpawn(type), pos, allowreplacement); } -template -inline T *Spawn (const fixedvec3 &pos, replace_t allowreplacement) +template inline T *Spawn(const DVector3 &pos, replace_t allowreplacement) { - return static_cast(AActor::StaticSpawn (RUNTIME_TEMPLATE_CLASS(T), pos.x, pos.y, pos.z, allowreplacement)); + return static_cast(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), pos, allowreplacement)); } -inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle) +template inline T *Spawn() // for inventory items we do not need coordinates and replacement info. { - fixedvec2 ret = { FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), - FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) }; - return ret; + return static_cast(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), DVector3(0, 0, 0), NO_REPLACE)); } void PrintMiscActorInfo(AActor * query); -AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask); +AActor *P_LinePickActor(AActor *t1, DAngle angle, double distance, DAngle pitch, ActorFlags actorMask, DWORD wallMask); // If we want to make P_AimLineAttack capable of handling arbitrary portals, it needs to pass a lot more info than just the linetarget actor. struct FTranslatedLineTarget { AActor *linetarget; - angle_t angleFromSource; + DAngle angleFromSource; bool unlinked; // found by a trace that went through an unlinked portal. }; diff --git a/src/am_map.cpp b/src/am_map.cpp index 8fab7e5ac..d84da2ebd 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -558,32 +558,24 @@ void FMapInfoParser::ParseAMColors(bool overlay) // //============================================================================= -#define MAPBITS 12 -#define MapDiv SafeDivScale12 -#define MapMul MulScale12 -#define MAPUNIT (1< CheatMapArrow; static TArray CheatKey; static TArray EasyKey; -#define R (MAPUNIT) -// [RH] Avoid lots of warnings without compiler-specific #pragmas -#define L(a,b,c,d) { {(fixed_t)((a)*R),(fixed_t)((b)*R)}, {(fixed_t)((c)*R),(fixed_t)((d)*R)} } +#define L(a,b,c,d) { {(a), (b)}, {(c), (d)} } static mline_t triangle_guy[] = { L (-.867,-.5, .867,-.5), L (.867,-.5, 0,1), @@ -730,10 +720,6 @@ static mline_t square_guy[] = { }; #define NUMSQUAREGUYLINES (sizeof(square_guy)/sizeof(mline_t)) -#undef R - - - //============================================================================= // // @@ -756,35 +742,35 @@ static int f_p; // [RH] # of bytes from start of a line to start of next static int amclock; static mpoint_t m_paninc; // how far the window pans each tic (map coords) -static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords) -static float am_zoomdir; +static double mtof_zoommul; // how far the window zooms in each tic (map coords) +static double am_zoomdir; -static fixed_t m_x, m_y; // LL x,y where the window is on the map (map coords) -static fixed_t m_x2, m_y2; // UR x,y where the window is on the map (map coords) +static double m_x, m_y; // LL x,y where the window is on the map (map coords) +static double m_x2, m_y2; // UR x,y where the window is on the map (map coords) // // width/height of window on map (map coords) // -static fixed_t m_w; -static fixed_t m_h; +static double m_w; +static double m_h; // based on level size -static fixed_t min_x, min_y, max_x, max_y; +static double min_x, min_y, max_x, max_y; -static fixed_t max_w; // max_x-min_x, -static fixed_t max_h; // max_y-min_y +static double max_w; // max_x-min_x, +static double max_h; // max_y-min_y // based on player size -static fixed_t min_w; -static fixed_t min_h; +static double min_w; +static double min_h; -static fixed_t min_scale_mtof; // used to tell when to stop zooming out -static fixed_t max_scale_mtof; // used to tell when to stop zooming in +static double min_scale_mtof; // used to tell when to stop zooming out +static double max_scale_mtof; // used to tell when to stop zooming in // old stuff for recovery later -static fixed_t old_m_w, old_m_h; -static fixed_t old_m_x, old_m_y; +static double old_m_w, old_m_h; +static double old_m_x, old_m_y; // old location used by the Follower routine static mpoint_t f_oldloc; @@ -794,18 +780,18 @@ static mpoint_t markpoints[AM_NUMMARKPOINTS]; // where the points are static int markpointnum = 0; // next point to be assigned static FTextureID mapback; // the automap background -static fixed_t mapystart=0; // y-value for the start of the map bitmap...used in the parallax stuff. -static fixed_t mapxstart=0; //x-value for the bitmap. +static double mapystart=0; // y-value for the start of the map bitmap...used in the parallax stuff. +static double mapxstart=0; //x-value for the bitmap. static bool stopped = true; static void AM_calcMinMaxMtoF(); -static void DrawMarker (FTexture *tex, fixed_t x, fixed_t y, int yadjust, - INTBOOL flip, fixed_t xscale, fixed_t yscale, int translation, fixed_t alpha, DWORD fillcolor, FRenderStyle renderstyle); +static void DrawMarker (FTexture *tex, double x, double y, int yadjust, + INTBOOL flip, double xscale, double yscale, int translation, double alpha, DWORD fillcolor, FRenderStyle renderstyle); -void AM_rotatePoint (fixed_t *x, fixed_t *y); -void AM_rotate (fixed_t *x, fixed_t *y, angle_t an); +void AM_rotatePoint (double *x, double *y); +void AM_rotate (double *x, double *y, DAngle an); void AM_doFollowPlayer (); @@ -814,6 +800,7 @@ void AM_doFollowPlayer (); // map functions // //============================================================================= + bool AM_addMark (); bool AM_clearMarks (); void AM_saveScaleAndLoc (); @@ -828,7 +815,7 @@ CVAR(Bool, am_portaloverlay, true, CVAR_ARCHIVE) CCMD(am_togglefollow) { am_followplayer = !am_followplayer; - f_oldloc.x = FIXED_MAX; + f_oldloc.x = FLT_MAX; Printf ("%s\n", GStrings(am_followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF")); } @@ -875,29 +862,15 @@ CCMD(am_gobig) AM_restoreScaleAndLoc(); } -// Calculates the slope and slope according to the x-axis of a line -// segment in map coordinates (with the upright y-axis n' all) so -// that it can be used with the brain-dead drawing stuff. - -// Ripped out for Heretic -/* -void AM_getIslope (mline_t *ml, islope_t *is) -{ - int dx, dy; - - dy = ml->a.y - ml->b.y; - dx = ml->b.x - ml->a.x; - if (!dy) is->islp = (dx<0?-MAXINT:MAXINT); - else is->islp = FixedDiv(dx, dy); - if (!dx) is->slp = (dy<0?-MAXINT:MAXINT); - else is->slp = FixedDiv(dy, dx); -} -*/ - +//============================================================================= +// +// vector graphics +// +//============================================================================= void AM_ParseArrow(TArray &Arrow, const char *lumpname) { - const int R = ((8*PLAYERRADIUS)/7); + const int R = int((8*PLAYERRADIUS)/7); FScanner sc; int lump = Wads.CheckNumForFullName(lumpname, true); if (lump >= 0) @@ -909,18 +882,18 @@ void AM_ParseArrow(TArray &Arrow, const char *lumpname) mline_t line; sc.TokenMustBe('('); sc.MustGetFloat(); - line.a.x = xs_RoundToInt(sc.Float*R); + line.a.x = sc.Float*R; sc.MustGetToken(','); sc.MustGetFloat(); - line.a.y = xs_RoundToInt(sc.Float*R); + line.a.y = sc.Float*R; sc.MustGetToken(')'); sc.MustGetToken(','); sc.MustGetToken('('); sc.MustGetFloat(); - line.b.x = xs_RoundToInt(sc.Float*R); + line.b.x = sc.Float*R; sc.MustGetToken(','); sc.MustGetFloat(); - line.b.y = xs_RoundToInt(sc.Float*R); + line.b.y = sc.Float*R; sc.MustGetToken(')'); Arrow.Push(line); } @@ -957,10 +930,9 @@ void AM_StaticInit() // //============================================================================= -void AM_GetPosition(fixed_t &x, fixed_t &y) +DVector2 AM_GetPosition() { - x = (m_x + m_w/2) << FRACTOMAPBITS; - y = (m_y + m_h/2) << FRACTOMAPBITS; + return DVector2((m_x + m_w / 2), (m_y + m_h / 2)); } //============================================================================= @@ -1012,15 +984,15 @@ void AM_restoreScaleAndLoc () } else { - m_x = (players[consoleplayer].camera->X() >> FRACTOMAPBITS) - m_w/2; - m_y = (players[consoleplayer].camera->Y() >> FRACTOMAPBITS)- m_h/2; + m_x = players[consoleplayer].camera->X() - m_w/2; + m_y = players[consoleplayer].camera->Y() - m_h/2; } m_x2 = m_x + m_w; m_y2 = m_y + m_h; // Change the scaling multipliers - scale_mtof = MapDiv(f_w< max_x) - max_x = vertexes[i].x; + if (vertexes[i].fX() < min_x) + min_x = vertexes[i].fX(); + else if (vertexes[i].fX() > max_x) + max_x = vertexes[i].fX(); - if (vertexes[i].y < min_y) - min_y = vertexes[i].y; - else if (vertexes[i].y > max_y) - max_y = vertexes[i].y; + if (vertexes[i].fY() < min_y) + min_y = vertexes[i].fY(); + else if (vertexes[i].fY() > max_y) + max_y = vertexes[i].fY(); } - max_w = (max_x >>= FRACTOMAPBITS) - (min_x >>= FRACTOMAPBITS); - max_h = (max_y >>= FRACTOMAPBITS) - (min_y >>= FRACTOMAPBITS); + max_w = max_x - min_x; + max_h = max_y - min_y; min_w = 2*PLAYERRADIUS; // const? never changed? min_h = 2*PLAYERRADIUS; @@ -1083,11 +1055,11 @@ static void AM_findMinMaxBoundaries () static void AM_calcMinMaxMtoF() { - fixed_t a = MapDiv (SCREENWIDTH << MAPBITS, max_w); - fixed_t b = MapDiv (::ST_Y << MAPBITS, max_h); + double a = SCREENWIDTH / max_w; + double b = ::ST_Y / max_h; min_scale_mtof = a < b ? a : b; - max_scale_mtof = MapDiv (SCREENHEIGHT << MAPBITS, 2*PLAYERRADIUS); + max_scale_mtof = SCREENHEIGHT / (2*PLAYERRADIUS); } //============================================================================= @@ -1096,7 +1068,7 @@ static void AM_calcMinMaxMtoF() // //============================================================================= -static void AM_ClipRotatedExtents (fixed_t pivotx, fixed_t pivoty) +static void AM_ClipRotatedExtents (double pivotx, double pivoty) { if (am_rotate == 0 || (am_rotate == 2 && !viewactive)) { @@ -1113,8 +1085,8 @@ static void AM_ClipRotatedExtents (fixed_t pivotx, fixed_t pivoty) else { #if 0 - fixed_t rmin_x, rmin_y, rmax_x, rmax_y; - fixed_t xs[5], ys[5]; + double rmin_x, rmin_y, rmax_x, rmax_y; + double xs[5], ys[5]; int i; xs[0] = min_x; ys[0] = min_y; @@ -1122,14 +1094,14 @@ static void AM_ClipRotatedExtents (fixed_t pivotx, fixed_t pivoty) xs[2] = max_x; ys[2] = max_y; xs[3] = min_x; ys[3] = max_y; xs[4] = m_x + m_w/2; ys[4] = m_y + m_h/2; - rmin_x = rmin_y = FIXED_MAX; + rmin_x = rmin_y = FLT_MAX; rmax_x = rmax_y = FIXED_MIN; for (i = 0; i < 5; ++i) { xs[i] -= pivotx; ys[i] -= pivoty; - AM_rotate (&xs[i], &ys[i], ANG90 - players[consoleplayer].camera->angle); + AM_rotate (&xs[i], &ys[i], 90. - players[consoleplayer].camera->Angles.Yaw); if (i == 5) break; @@ -1150,7 +1122,7 @@ static void AM_ClipRotatedExtents (fixed_t pivotx, fixed_t pivoty) // ys[4] = rmax_y; // else if (ys[4] < rmin_y) // ys[4] = rmin_y; - AM_rotate (&xs[4], &ys[4], ANG270 - players[consoleplayer].camera->angle); + AM_rotate (&xs[4], &ys[4], 270. - players[consoleplayer].camera->Angles.Yaw); m_x = xs[4] + pivotx - m_w/2; m_y = ys[4] + pivoty - m_h/2; #endif @@ -1166,10 +1138,13 @@ static void AM_ClipRotatedExtents (fixed_t pivotx, fixed_t pivoty) // //============================================================================= -static void AM_ScrollParchment (fixed_t dmapx, fixed_t dmapy) +static void AM_ScrollParchment (double dmapx, double dmapy) { - mapxstart -= MulScale12 (dmapx, scale_mtof); - mapystart -= MulScale12 (dmapy, scale_mtof); + mapxstart = mapxstart - dmapx * scale_mtof; + mapystart = mapystart - dmapy * scale_mtof; + + mapxstart = clamp(mapxstart, -40000., 40000.); + mapystart = clamp(mapxstart, -40000., 40000.); if (mapback.isValid()) { @@ -1177,8 +1152,8 @@ static void AM_ScrollParchment (fixed_t dmapx, fixed_t dmapy) if (backtex != NULL) { - int pwidth = backtex->GetWidth() << MAPBITS; - int pheight = backtex->GetHeight() << MAPBITS; + int pwidth = backtex->GetWidth(); + int pheight = backtex->GetHeight(); while(mapxstart > 0) mapxstart -= pwidth; @@ -1200,23 +1175,23 @@ static void AM_ScrollParchment (fixed_t dmapx, fixed_t dmapy) void AM_changeWindowLoc () { - if (0 != (m_paninc.x | m_paninc.y)) + if (m_paninc.x || m_paninc.y) { am_followplayer = false; - f_oldloc.x = FIXED_MAX; + f_oldloc.x = FLT_MAX; } - int oldmx = m_x, oldmy = m_y; - fixed_t incx, incy, oincx, oincy; + double oldmx = m_x, oldmy = m_y; + double incx, incy, oincx, oincy; incx = m_paninc.x; incy = m_paninc.y; - oincx = incx = Scale(m_paninc.x, SCREENWIDTH, 320); - oincy = incy = Scale(m_paninc.y, SCREENHEIGHT, 200); + oincx = incx = m_paninc.x * SCREENWIDTH / 320; + oincy = incy = m_paninc.y * SCREENHEIGHT / 200; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - AM_rotate(&incx, &incy, players[consoleplayer].camera->angle - ANG90); + AM_rotate(&incx, &incy, players[consoleplayer].camera->Angles.Yaw - 90.); } m_x += incx; @@ -1248,11 +1223,11 @@ void AM_initVariables () Button_AM_ZoomOut.Reset(); - f_oldloc.x = FIXED_MAX; + f_oldloc.x = FLT_MAX; amclock = 0; m_paninc.x = m_paninc.y = 0; - mtof_zoommul = MAPUNIT; + mtof_zoommul = 1.; m_w = FTOM(SCREENWIDTH); m_h = FTOM(SCREENHEIGHT); @@ -1263,8 +1238,8 @@ void AM_initVariables () if (playeringame[pnum]) break; assert(pnum >= 0 && pnum < MAXPLAYERS); - m_x = (players[pnum].camera->X() >> FRACTOMAPBITS) - m_w/2; - m_y = (players[pnum].camera->Y() >> FRACTOMAPBITS) - m_h/2; + m_x = players[pnum].camera->X() - m_w/2; + m_y = players[pnum].camera->Y() - m_h/2; AM_changeWindowLoc(); // for saving & restoring @@ -1356,10 +1331,10 @@ void AM_LevelInit () AM_clearMarks(); AM_findMinMaxBoundaries(); - scale_mtof = MapDiv(min_scale_mtof, (int) (0.7*MAPUNIT)); + scale_mtof = min_scale_mtof / 0.7; if (scale_mtof > max_scale_mtof) scale_mtof = min_scale_mtof; - scale_ftom = MapDiv(MAPUNIT, scale_mtof); + scale_ftom = 1 / scale_mtof; am_showalllines.Callback(); } @@ -1402,7 +1377,7 @@ void AM_Start () void AM_minOutWindowScale () { scale_mtof = min_scale_mtof; - scale_ftom = MapDiv(MAPUNIT, scale_mtof); + scale_ftom = 1/ scale_mtof; } //============================================================================= @@ -1414,7 +1389,7 @@ void AM_minOutWindowScale () void AM_maxOutWindowScale () { scale_mtof = max_scale_mtof; - scale_ftom = MapDiv(MAPUNIT, scale_mtof); + scale_ftom = 1 / scale_mtof; } //============================================================================= @@ -1425,15 +1400,15 @@ void AM_maxOutWindowScale () void AM_NewResolution() { - fixed_t oldmin = min_scale_mtof; + double oldmin = min_scale_mtof; if ( oldmin == 0 ) { return; // [SP] Not in a game, exit! } AM_calcMinMaxMtoF(); - scale_mtof = Scale(scale_mtof, min_scale_mtof, oldmin); - scale_ftom = MapDiv(MAPUNIT, scale_mtof); + scale_mtof = scale_mtof * min_scale_mtof / oldmin; + scale_ftom = 1 / scale_mtof; if (scale_mtof < min_scale_mtof) AM_minOutWindowScale(); else if (scale_mtof > max_scale_mtof) @@ -1532,33 +1507,33 @@ bool AM_Responder (event_t *ev, bool last) void AM_changeWindowScale () { - int mtof_zoommul; + double mtof_zoommul; if (am_zoomdir > 0) { - mtof_zoommul = int(M_ZOOMIN * am_zoomdir); + mtof_zoommul = M_ZOOMIN * am_zoomdir; } else if (am_zoomdir < 0) { - mtof_zoommul = int(M_ZOOMOUT / -am_zoomdir); + mtof_zoommul = M_ZOOMOUT / -am_zoomdir; } else if (Button_AM_ZoomIn.bDown) { - mtof_zoommul = int(M_ZOOMIN); + mtof_zoommul = M_ZOOMIN; } else if (Button_AM_ZoomOut.bDown) { - mtof_zoommul = int(M_ZOOMOUT); + mtof_zoommul = M_ZOOMOUT; } else { - mtof_zoommul = MAPUNIT; + mtof_zoommul = 1; } am_zoomdir = 0; // Change the scaling multipliers - scale_mtof = MapMul(scale_mtof, mtof_zoommul); - scale_ftom = MapDiv(MAPUNIT, scale_mtof); + scale_mtof = scale_mtof * mtof_zoommul; + scale_ftom = 1 / scale_mtof; if (scale_mtof < min_scale_mtof) AM_minOutWindowScale(); @@ -1570,7 +1545,7 @@ CCMD(am_zoom) { if (argv.argc() >= 2) { - am_zoomdir = (float)atof(argv[1]); + am_zoomdir = atof(argv[1]); } } @@ -1582,23 +1557,23 @@ CCMD(am_zoom) void AM_doFollowPlayer () { - fixed_t sx, sy; + double sx, sy; if (players[consoleplayer].camera != NULL && (f_oldloc.x != players[consoleplayer].camera->X() || f_oldloc.y != players[consoleplayer].camera->Y())) { - m_x = (players[consoleplayer].camera->X() >> FRACTOMAPBITS) - m_w/2; - m_y = (players[consoleplayer].camera->Y() >> FRACTOMAPBITS) - m_h/2; + m_x = players[consoleplayer].camera->X() - m_w/2; + m_y = players[consoleplayer].camera->Y() - m_h/2; m_x2 = m_x + m_w; m_y2 = m_y + m_h; // do the parallax parchment scrolling. - sx = (players[consoleplayer].camera->X() - f_oldloc.x) >> FRACTOMAPBITS; - sy = (f_oldloc.y - players[consoleplayer].camera->Y()) >> FRACTOMAPBITS; + sx = (players[consoleplayer].camera->X() - f_oldloc.x); + sy = (f_oldloc.y - players[consoleplayer].camera->Y()); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - AM_rotate (&sx, &sy, players[consoleplayer].camera->angle - ANG90); + AM_rotate (&sx, &sy, players[consoleplayer].camera->Angles.Yaw - 90); } AM_ScrollParchment (sx, sy); @@ -1675,9 +1650,9 @@ void AM_clearFB (const AMColor &color) int x, y; //blit the automap background to the screen. - for (y = mapystart >> MAPBITS; y < f_h; y += pheight) + for (y = int(mapystart); y < f_h; y += pheight) { - for (x = mapxstart >> MAPBITS; x < f_w; x += pwidth) + for (x = int(mapxstart); x < f_w; x += pwidth) { screen->DrawTexture (backtex, x, y, DTA_ClipBottom, f_h, DTA_TopOffset, 0, DTA_LeftOffset, 0, TAG_DONE); } @@ -1847,15 +1822,15 @@ inline void AM_drawMline (mline_t *ml, int colorindex) void AM_drawGrid (int color) { - fixed_t x, y; - fixed_t start, end; + double x, y; + double start, end; mline_t ml; - fixed_t minlen, extx, exty; - fixed_t minx, miny; + double minlen, extx, exty; + double minx, miny; // [RH] Calculate a minimum for how long the grid lines should be so that // they cover the screen at any rotation. - minlen = (fixed_t)sqrt ((double)m_w*(double)m_w + (double)m_h*(double)m_h); + minlen = sqrt (m_w*m_w + m_h*m_h); extx = (minlen - m_w) / 2; exty = (minlen - m_h) / 2; @@ -1864,13 +1839,12 @@ void AM_drawGrid (int color) // Figure out start of vertical gridlines start = minx - extx; - if ((start-bmaporgx)%(MAPBLOCKUNITS< points; - float scale = float(scale_mtof); - angle_t rotation; + double scale = scale_mtof; + DAngle rotation; sector_t tempsec; int floorlight, ceilinglight; - fixed_t scalex, scaley; + double scalex, scaley; double originx, originy; FDynamicColormap *colormap; mpoint_t originpt; @@ -1946,28 +1918,28 @@ void AM_drawSubsectors() points.Resize(subsectors[i].numlines); for (DWORD j = 0; j < subsectors[i].numlines; ++j) { - mpoint_t pt = { subsectors[i].firstline[j].v1->x >> FRACTOMAPBITS, - subsectors[i].firstline[j].v1->y >> FRACTOMAPBITS }; + mpoint_t pt = { subsectors[i].firstline[j].v1->fX(), + subsectors[i].firstline[j].v1->fY() }; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { AM_rotatePoint(&pt.x, &pt.y); } - points[j].X = f_x + ((pt.x - m_x) * scale / float(1 << 24)); - points[j].Y = f_y + (f_h - (pt.y - m_y) * scale / float(1 << 24)); + points[j].X = float(f_x + ((pt.x - m_x) * scale)); + points[j].Y = float(f_y + (f_h - (pt.y - m_y) * scale)); } // For lighting and texture determination - sector_t *sec = Renderer->FakeFlat (subsectors[i].render_sector, &tempsec, &floorlight, &ceilinglight, false); + sector_t *sec = Renderer->FakeFlat(subsectors[i].render_sector, &tempsec, &floorlight, &ceilinglight, false); // Find texture origin. - originpt.x = -sec->GetXOffset(sector_t::floor) >> FRACTOMAPBITS; - originpt.y = sec->GetYOffset(sector_t::floor) >> FRACTOMAPBITS; - rotation = 0 - sec->GetAngle(sector_t::floor); + originpt.x = -sec->GetXOffsetF(sector_t::floor); + originpt.y = sec->GetYOffsetF(sector_t::floor); + rotation = -sec->GetAngleF(sector_t::floor); // Coloring for the polygon colormap = sec->ColorMap; FTextureID maptex = sec->GetTexture(sector_t::floor); - scalex = sec->GetXScale(sector_t::floor); - scaley = sec->GetYScale(sector_t::floor); + scalex = sec->GetXScaleF(sector_t::floor); + scaley = sec->GetYScaleF(sector_t::floor); if (sec->e->XFloor.ffloors.Size()) { @@ -1981,22 +1953,22 @@ void AM_drawSubsectors() double secx; double secy; double seczb, seczt; - double cmpz = FIXED2DBL(viewz); + double cmpz = ViewPos.Z; if (players[consoleplayer].camera && sec == players[consoleplayer].camera->Sector) { // For the actual camera sector use the current viewpoint as reference. - secx = FIXED2DBL(viewx); - secy = FIXED2DBL(viewy); + secx = ViewPos.X; + secy = ViewPos.Y; } else { - secx = FIXED2DBL(sec->centerspot.x); - secy = FIXED2DBL(sec->centerspot.y); + secx = sec->centerspot.X; + secy = sec->centerspot.Y; } seczb = floorplane->ZatPoint(secx, secy); seczt = sec->ceilingplane.ZatPoint(secx, secy); - + for (unsigned int i = 0; i < sec->e->XFloor.ffloors.Size(); ++i) { F3DFloor *rover = sec->e->XFloor.ffloors[i]; @@ -2016,11 +1988,11 @@ void AM_drawSubsectors() floorplane = rover->top.plane; sector_t *model = rover->top.model; int selector = (rover->flags & FF_INVERTPLANES) ? sector_t::floor : sector_t::ceiling; - rotation = 0 - model->GetAngle(selector); - scalex = model->GetXScale(selector); - scaley = model->GetYScale(selector); - originpt.x = -model->GetXOffset(selector) >> FRACTOMAPBITS; - originpt.y = model->GetYOffset(selector) >> FRACTOMAPBITS; + rotation = -model->GetAngleF(selector); + scalex = model->GetXScaleF(selector); + scaley = model->GetYScaleF(selector); + originpt.x = -model->GetXOffsetF(selector); + originpt.y = model->GetYOffsetF(selector); break; } } @@ -2042,11 +2014,11 @@ void AM_drawSubsectors() // Apply the automap's rotation to the texture origin. if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - rotation += ANG90 - players[consoleplayer].camera->angle; + rotation = rotation + 90. - players[consoleplayer].camera->Angles.Yaw; AM_rotatePoint(&originpt.x, &originpt.y); } - originx = f_x + ((originpt.x - m_x) * scale / float(1 << 24)); - originy = f_y + (f_h - (originpt.y - m_y) * scale / float(1 << 24)); + originx = f_x + ((originpt.x - m_x) * scale); + originy = f_y + (f_h - (originpt.y - m_y) * scale); // If this subsector has not actually been seen yet (because you are cheating // to see it on the map), tint and desaturate it. @@ -2059,7 +2031,7 @@ void AM_drawSubsectors() (colormap->Color.b + 160) / 2), colormap->Fade, 255 - (255 - colormap->Desaturate) / 4); - floorlight = (floorlight + 200*15) / 16; + floorlight = (floorlight + 200 * 15) / 16; } // Draw the polygon. @@ -2069,8 +2041,8 @@ void AM_drawSubsectors() screen->FillSimplePoly(TexMan(maptex), &points[0], points.Size(), originx, originy, - scale / (FIXED2DBL(scalex) * float(1 << MAPBITS)), - scale / (FIXED2DBL(scaley) * float(1 << MAPBITS)), + scale / scalex, + scale / scaley, rotation, colormap, floorlight @@ -2119,10 +2091,10 @@ static bool AM_CheckSecret(line_t *line) void AM_drawSeg(seg_t *seg, const AMColor &color) { mline_t l; - l.a.x = seg->v1->x >> FRACTOMAPBITS; - l.a.y = seg->v1->y >> FRACTOMAPBITS; - l.b.x = seg->v2->x >> FRACTOMAPBITS; - l.b.y = seg->v2->y >> FRACTOMAPBITS; + l.a.x = seg->v1->fX(); + l.a.y = seg->v1->fY(); + l.b.x = seg->v2->fX(); + l.b.y = seg->v2->fY(); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { @@ -2135,10 +2107,10 @@ void AM_drawSeg(seg_t *seg, const AMColor &color) void AM_drawPolySeg(FPolySeg *seg, const AMColor &color) { mline_t l; - l.a.x = seg->v1.x >> FRACTOMAPBITS; - l.a.y = seg->v1.y >> FRACTOMAPBITS; - l.b.x = seg->v2.x >> FRACTOMAPBITS; - l.b.y = seg->v2.y >> FRACTOMAPBITS; + l.a.x = seg->v1.pos.X; + l.a.y = seg->v1.pos.Y; + l.b.x = seg->v2.pos.X; + l.b.y = seg->v2.pos.Y; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { @@ -2420,13 +2392,13 @@ void AM_drawWalls (bool allmap) if (lines[i].sidedef[0]->Flags & WALLF_POLYOBJ) { // For polyobjects we must test the surrounding sector to get the proper group. - pg = P_PointInSector(lines[i].v1->x + lines[i].dx / 2, lines[i].v1->y + lines[i].dy / 2)->PortalGroup; + pg = P_PointInSector(lines[i].v1->fX() + lines[i].Delta().X / 2, lines[i].v1->fY() + lines[i].Delta().Y / 2)->PortalGroup; } else { pg = lines[i].frontsector->PortalGroup; } - fixedvec2 offset; + DVector2 offset; bool portalmode = numportalgroups > 0 && pg != MapPortalGroup; if (pg == p) { @@ -2438,10 +2410,10 @@ void AM_drawWalls (bool allmap) } else continue; - l.a.x = (lines[i].v1->x + offset.x) >> FRACTOMAPBITS; - l.a.y = (lines[i].v1->y + offset.y) >> FRACTOMAPBITS; - l.b.x = (lines[i].v2->x + offset.x) >> FRACTOMAPBITS; - l.b.y = (lines[i].v2->y + offset.y) >> FRACTOMAPBITS; + l.a.x = (lines[i].v1->fX() + offset.X); + l.a.y = (lines[i].v1->fY() + offset.Y); + l.b.x = (lines[i].v2->fX() + offset.X); + l.b.y = (lines[i].v2->fY() + offset.Y); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { @@ -2553,27 +2525,26 @@ void AM_drawWalls (bool allmap) // //============================================================================= -void AM_rotate(fixed_t *xp, fixed_t *yp, angle_t a) +void AM_rotate(double *xp, double *yp, DAngle a) { - static angle_t angle_saved = 0; + static DAngle angle_saved = 0.; static double sinrot = 0; static double cosrot = 1; if (angle_saved != a) { angle_saved = a; - double rot = (double)a / (double)(1u << 31) * (double)M_PI; - sinrot = sin(rot); - cosrot = cos(rot); + sinrot = sin(a.Radians()); + cosrot = cos(a.Radians()); } - double x = FIXED2DBL(*xp); - double y = FIXED2DBL(*yp); + double x = *xp; + double y = *yp; double tmpx = (x * cosrot) - (y * sinrot); y = (x * sinrot) + (y * cosrot); x = tmpx; - *xp = FLOAT2FIXED(x); - *yp = FLOAT2FIXED(y); + *xp = x; + *yp = y; } //============================================================================= @@ -2582,13 +2553,13 @@ void AM_rotate(fixed_t *xp, fixed_t *yp, angle_t a) // //============================================================================= -void AM_rotatePoint (fixed_t *x, fixed_t *y) +void AM_rotatePoint (double *x, double *y) { - fixed_t pivotx = m_x + m_w/2; - fixed_t pivoty = m_y + m_h/2; + double pivotx = m_x + m_w/2; + double pivoty = m_y + m_h/2; *x -= pivotx; *y -= pivoty; - AM_rotate (x, y, ANG90 - players[consoleplayer].camera->angle); + AM_rotate (x, y, -players[consoleplayer].camera->Angles.Yaw - 90.); *x += pivotx; *y += pivoty; } @@ -2603,11 +2574,11 @@ void AM_drawLineCharacter ( const mline_t *lineguy, int lineguylines, - fixed_t scale, - angle_t angle, + double scale, + DAngle angle, const AMColor &color, - fixed_t x, - fixed_t y ) + double x, + double y ) { int i; mline_t l; @@ -2617,11 +2588,11 @@ AM_drawLineCharacter l.a.y = lineguy[i].a.y; if (scale) { - l.a.x = MapMul(scale, l.a.x); - l.a.y = MapMul(scale, l.a.y); + l.a.x *= scale; + l.a.y *= scale; } - if (angle) + if (angle != 0) AM_rotate(&l.a.x, &l.a.y, angle); l.a.x += x; @@ -2631,11 +2602,11 @@ AM_drawLineCharacter l.b.y = lineguy[i].b.y; if (scale) { - l.b.x = MapMul(scale, l.b.x); - l.b.y = MapMul(scale, l.b.y); + l.b.x *= scale; + l.b.y *= scale; } - if (angle) + if (angle != 0) AM_rotate(&l.b.x, &l.b.y, angle); l.b.x += x; @@ -2660,7 +2631,7 @@ void AM_drawPlayers () } mpoint_t pt; - angle_t angle; + DAngle angle; int i; if (!multiplayer) @@ -2668,17 +2639,18 @@ void AM_drawPlayers () mline_t *arrow; int numarrowlines; - fixedvec2 pos = am_portaloverlay? players[consoleplayer].camera->GetPortalTransition(players[consoleplayer].viewheight) : (fixedvec2)players[consoleplayer].camera->Pos(); - pt.x = pos.x >> FRACTOMAPBITS; - pt.y = pos.y >> FRACTOMAPBITS; + double vh = players[consoleplayer].viewheight; + DVector2 pos = am_portaloverlay? players[consoleplayer].camera->GetPortalTransition(vh) : players[consoleplayer].camera->Pos(); + pt.x = pos.X; + pt.y = pos.Y; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - angle = ANG90; + angle = 90.; AM_rotatePoint (&pt.x, &pt.y); } else { - angle = players[consoleplayer].camera->angle; + angle = players[consoleplayer].camera->Angles.Yaw; } if (am_cheat != 0 && CheatMapArrow.Size() > 0) @@ -2716,7 +2688,7 @@ void AM_drawPlayers () continue; } - if (p->mo->alpha < OPAQUE) + if (p->mo->Alpha < 1.) { color = AMColors[AMColors.AlmostBackgroundColor]; } @@ -2732,16 +2704,16 @@ void AM_drawPlayers () if (p->mo != NULL) { - fixedvec3 pos = p->mo->PosRelative(MapPortalGroup); - pt.x = pos.x >> FRACTOMAPBITS; - pt.y = pos.y >> FRACTOMAPBITS; + DVector3 pos = p->mo->PosRelative(MapPortalGroup); + pt.x = pos.X; + pt.y = pos.Y; - angle = p->mo->angle; + angle = p->mo->Angles.Yaw; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { AM_rotatePoint (&pt.x, &pt.y); - angle -= players[consoleplayer].camera->angle - ANG90; + angle -= players[consoleplayer].camera->Angles.Yaw - 90.; } AM_drawLineCharacter(&MapArrow[0], MapArrow.Size(), 0, angle, color, pt.x, pt.y); @@ -2759,23 +2731,23 @@ void AM_drawKeys () { AMColor color; mpoint_t p; - angle_t angle; + DAngle angle; TThinkerIterator it; AKey *key; while ((key = it.Next()) != NULL) { - fixedvec3 pos = key->PosRelative(MapPortalGroup); - p.x = pos.x >> FRACTOMAPBITS; - p.y = pos.y >> FRACTOMAPBITS; + DVector3 pos = key->PosRelative(MapPortalGroup); + p.x = pos.X; + p.y = pos.Y; - angle = key->angle; + angle = key->Angles.Yaw; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { AM_rotatePoint (&p.x, &p.y); - angle += ANG90 - players[consoleplayer].camera->angle; + angle += -players[consoleplayer].camera->Angles.Yaw + 90.; } if (key->flags & MF_SPECIAL) @@ -2788,7 +2760,7 @@ void AM_drawKeys () if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c)); else color = AMColors[AMColors.ThingColor_CountItem]; - AM_drawLineCharacter(&EasyKey[0], EasyKey.Size(), 0, 0, color, p.x, p.y); + AM_drawLineCharacter(&EasyKey[0], EasyKey.Size(), 0, 0., color, p.x, p.y); } } } @@ -2804,7 +2776,7 @@ void AM_drawThings () int i; AActor* t; mpoint_t p; - angle_t angle; + DAngle angle; for (i=0;i 0 || !(t->flags6 & MF6_NOTONAUTOMAP)) { - fixedvec3 pos = t->PosRelative(MapPortalGroup); - p.x = pos.x >> FRACTOMAPBITS; - p.y = pos.y >> FRACTOMAPBITS; + DVector3 pos = t->PosRelative(MapPortalGroup); + p.x = pos.X; + p.y = pos.Y; if (am_showthingsprites > 0 && t->sprite > 0) { FTexture *texture = NULL; spriteframe_t *frame; - angle_t rotation = 0; + int rotation = 0; // try all modes backwards until a valid texture has been found. for(int show = am_showthingsprites; show > 0 && texture == NULL; show--) @@ -2830,13 +2802,13 @@ void AM_drawThings () const size_t spriteIndex = sprite.spriteframes + (show > 1 ? t->frame : 0); frame = &SpriteFrames[spriteIndex]; - angle_t angle = ANGLE_270 - t->angle; - if (frame->Texture[0] != frame->Texture[1]) angle += (ANGLE_180 / 16); + DAngle angle = -t->Angles.Yaw + 270.; + if (frame->Texture[0] != frame->Texture[1]) angle += 180. / 16; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - angle += players[consoleplayer].camera->angle - ANGLE_90; + angle += players[consoleplayer].camera->Angles.Yaw - 90.; } - rotation = angle >> 28; + rotation = int((angle.Normalized360() * (16. / 360.)).Degrees); const FTextureID textureID = frame->Texture[show > 2 ? rotation : 0]; texture = TexMan(textureID); @@ -2844,21 +2816,21 @@ void AM_drawThings () if (texture == NULL) goto drawTriangle; // fall back to standard display if no sprite can be found. - const fixed_t spriteXScale = FixedMul(t->scaleX, 10 * scale_mtof); - const fixed_t spriteYScale = FixedMul(t->scaleY, 10 * scale_mtof); + const double spriteXScale = (t->Scale.X * 10 * scale_mtof); + const double spriteYScale = (t->Scale.Y * 10 * scale_mtof); DrawMarker (texture, p.x, p.y, 0, !!(frame->Flip & (1 << rotation)), - spriteXScale, spriteYScale, t->Translation, FRACUNIT, 0, LegacyRenderStyles[STYLE_Normal]); + spriteXScale, spriteYScale, t->Translation, 1., 0, LegacyRenderStyles[STYLE_Normal]); } else { drawTriangle: - angle = t->angle; + angle = t->Angles.Yaw; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { AM_rotatePoint (&p.x, &p.y); - angle += ANG90 - players[consoleplayer].camera->angle; + angle += -players[consoleplayer].camera->Angles.Yaw + 90.; } color = AMColors[AMColors.ThingColor]; @@ -2889,7 +2861,7 @@ void AM_drawThings () if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c)); else color = AMColors[AMColors.ThingColor_CountItem]; - AM_drawLineCharacter(&CheatKey[0], CheatKey.Size(), 0, 0, color, p.x, p.y); + AM_drawLineCharacter(&CheatKey[0], CheatKey.Size(), 0, 0., color, p.x, p.y); color.Index = -1; } else @@ -2905,22 +2877,20 @@ void AM_drawThings () if (color.Index != -1) { - AM_drawLineCharacter - (thintriangle_guy, NUMTHINTRIANGLEGUYLINES, - 16<radius >> FRACTOMAPBITS, angle - t->angle, color, p.x, p.y); + AM_drawLineCharacter (box, 4, t->radius, angle - t->Angles.Yaw, color, p.x, p.y); } } } @@ -2935,8 +2905,8 @@ void AM_drawThings () // //============================================================================= -static void DrawMarker (FTexture *tex, fixed_t x, fixed_t y, int yadjust, - INTBOOL flip, fixed_t xscale, fixed_t yscale, int translation, fixed_t alpha, DWORD fillcolor, FRenderStyle renderstyle) +static void DrawMarker (FTexture *tex, double x, double y, int yadjust, + INTBOOL flip, double xscale, double yscale, int translation, double alpha, DWORD fillcolor, FRenderStyle renderstyle) { if (tex == NULL || tex->UseType == FTexture::TEX_Null) { @@ -2947,15 +2917,15 @@ static void DrawMarker (FTexture *tex, fixed_t x, fixed_t y, int yadjust, AM_rotatePoint (&x, &y); } screen->DrawTexture (tex, CXMTOF(x) + f_x, CYMTOF(y) + yadjust + f_y, - DTA_DestWidth, MulScale16 (tex->GetScaledWidth() * CleanXfac, xscale), - DTA_DestHeight, MulScale16 (tex->GetScaledHeight() * CleanYfac, yscale), + DTA_DestWidthF, tex->GetScaledWidthDouble() * CleanXfac * xscale / 16, + DTA_DestHeightF, tex->GetScaledHeightDouble() * CleanYfac * yscale / 16, DTA_ClipTop, f_y, DTA_ClipBottom, f_y + f_h, DTA_ClipLeft, f_x, DTA_ClipRight, f_x + f_w, DTA_FlipX, flip, DTA_Translation, TranslationToTable(translation), - DTA_Alpha, alpha, + DTA_AlphaF, alpha, DTA_FillColor, fillcolor, DTA_RenderStyle, DWORD(renderstyle), TAG_DONE); @@ -2974,7 +2944,7 @@ void AM_drawMarks () if (markpoints[i].x != -1) { DrawMarker (TexMan(marknums[i]), markpoints[i].x, markpoints[i].y, -3, 0, - FRACUNIT, FRACUNIT, 0, FRACUNIT, 0, LegacyRenderStyles[STYLE_Normal]); + 1, 1, 0, 1, 0, LegacyRenderStyles[STYLE_Normal]); } } } @@ -3041,9 +3011,8 @@ void AM_drawAuthorMarkers () marked->subsector->flags & SSECF_DRAWN : marked->Sector->MoreFlags & SECF_DRAWN))) { - DrawMarker (tex, marked->X() >> FRACTOMAPBITS, marked->Y() >> FRACTOMAPBITS, 0, - flip, mark->scaleX, mark->scaleY, mark->Translation, - mark->alpha, mark->fillcolor, mark->RenderStyle); + DrawMarker (tex, marked->X(), marked->Y(), 0, flip, mark->Scale.X*16, mark->Scale.Y*16, mark->Translation, + mark->Alpha, mark->fillcolor, mark->RenderStyle); } marked = mark->args[0] != 0 ? it.Next() : NULL; } @@ -3078,7 +3047,8 @@ void AM_Drawer () if (am_portaloverlay) { sector_t *sec; - players[consoleplayer].camera->GetPortalTransition(players[consoleplayer].viewheight, &sec); + double vh = players[consoleplayer].viewheight; + players[consoleplayer].camera->GetPortalTransition(vh, &sec); MapPortalGroup = sec->PortalGroup; } else MapPortalGroup = 0; diff --git a/src/b_bot.cpp b/src/b_bot.cpp index 89b7b9471..a4160b92c 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -33,7 +33,7 @@ DBot::DBot () void DBot::Clear () { player = NULL; - angle = 0; + Angle = 0.; dest = NULL; prev = NULL; enemy = NULL; @@ -52,27 +52,15 @@ void DBot::Clear () sleft = false; allround = false; increase = false; - oldx = 0; - oldy = 0; + old = { 0, 0 }; } void DBot::Serialize (FArchive &arc) { Super::Serialize (arc); - if (SaveVersion < 4515) - { - angle_t savedyaw; - int savedpitch; - arc << savedyaw - << savedpitch; - } - else - { - arc << player; - } - - arc << angle + arc << player + << Angle << dest << prev << enemy @@ -91,8 +79,7 @@ void DBot::Serialize (FArchive &arc) << sleft << allround << increase - << oldx - << oldy; + << old; } void DBot::Tick () @@ -269,7 +256,7 @@ void InitBotStuff() AWeapon *w = (AWeapon*)GetDefaultByType(cls); if (w != NULL) { - w->MoveCombatDist = botinits[i].movecombatdist; + w->MoveCombatDist = botinits[i].movecombatdist/65536.; w->WeaponFlags |= botinits[i].weaponflags; w->ProjectileType = PClass::FindActor(botinits[i].projectile); } diff --git a/src/b_bot.h b/src/b_bot.h index 1e8a0e341..9f9fe55ba 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -31,18 +31,18 @@ #define BOTFILENAME "bots.cfg" -#define MAX_TRAVERSE_DIST 100000000 //10 meters, used within b_func.c -#define AVOID_DIST 45000000 //Try avoid incoming missiles once they reached this close -#define SAFE_SELF_MISDIST (140*FRACUNIT) //Distance from self to target where it's safe to pull a rocket. -#define FRIEND_DIST 15000000 //To friend. -#define DARK_DIST 5000000 //Distance that bot can see enemies in the dark from. +#define MAX_TRAVERSE_DIST (100000000/65536.) //10 meters, used within b_func.c +#define AVOID_DIST (45000000/65536.) //Try avoid incoming missiles once they reached this close +#define SAFE_SELF_MISDIST (140.) //Distance from self to target where it's safe to pull a rocket. +#define FRIEND_DIST (15000000/65536.) //To friend. +#define DARK_DIST (5000000/65536.) //Distance that bot can see enemies in the dark from. #define WHATS_DARK 50 //light value thats classed as dark. -#define MAX_MONSTER_TARGET_DIST 50000000 //Too high can slow down the performance, see P_mobj.c -#define ENEMY_SCAN_FOV (120*ANGLE_1) +#define MAX_MONSTER_TARGET_DIST (50000000/65536.) //Too high can slow down the performance, see P_mobj.c +#define ENEMY_SCAN_FOV (120.) #define THINGTRYTICK 1000 -#define MAXMOVEHEIGHT (32*FRACUNIT) //MAXSTEPMOVE but with jumping counted in. -#define GETINCOMBAT 35000000 //Max distance to item. if it's due to be icked up in a combat situation. -#define SHOOTFOV (60*ANGLE_1) +#define MAXMOVEHEIGHT (32) //MAXSTEPMOVE but with jumping counted in. +#define GETINCOMBAT (35000000/65536.) //Max distance to item. if it's due to be icked up in a combat situation. +#define SHOOTFOV (60.) #define AFTERTICS (2*TICRATE) //Seconds that bot will be alert on an recent enemy. Ie not looking the other way #define MAXROAM (4*TICRATE) //When this time is elapsed the bot will roam after something else. //monster mod @@ -103,12 +103,13 @@ public: void StartTravel (); void FinishTravel (); bool IsLeader (player_t *player); - void SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum); - fixed_t FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd); - bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm); + void SetBodyAt (const DVector3 &pos, int hostnum); + double FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd); + bool SafeCheckPosition (AActor *actor, double x, double y, FCheckPosition &tm); + void BotTick(AActor *mo); //(b_move.cpp) - bool CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cmd); + bool CleanAhead (AActor *thing, double x, double y, ticcmd_t *cmd); bool IsDangerous (sector_t *sec); TArray getspawned; //Array of bots (their names) which should be spawned when starting a game. @@ -149,10 +150,10 @@ public: void WhatToGet (AActor *item); //(b_func.cpp) - bool Check_LOS (AActor *to, angle_t vangle); + bool Check_LOS (AActor *to, DAngle vangle); player_t *player; - angle_t angle; // The wanted angle that the bot try to get every tic. + DAngle Angle; // The wanted angle that the bot try to get every tic. // (used to get a smooth view movement) TObjPtr dest; // Move Destination. TObjPtr prev; // Previous move destination. @@ -183,8 +184,7 @@ public: bool allround; bool increase; - fixed_t oldx; - fixed_t oldy; + DVector2 old; private: //(b_think.cpp) @@ -197,7 +197,7 @@ private: void Dofire (ticcmd_t *cmd); AActor *Choose_Mate (); AActor *Find_enemy (); - angle_t FireRox (AActor *enemy, ticcmd_t *cmd); + DAngle FireRox (AActor *enemy, ticcmd_t *cmd); //(b_move.cpp) void Roam (ticcmd_t *cmd); diff --git a/src/b_func.cpp b/src/b_func.cpp index 70ffadce8..acd3077e6 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -36,30 +36,30 @@ bool DBot::Reachable (AActor *rtarget) if ((rtarget->Sector->ceilingplane.ZatPoint (rtarget) - rtarget->Sector->floorplane.ZatPoint (rtarget)) - < player->mo->height) //Where rtarget is, player->mo can't be. + < player->mo->Height) //Where rtarget is, player->mo can't be. return false; sector_t *last_s = player->mo->Sector; - fixed_t last_z = last_s->floorplane.ZatPoint (player->mo); - fixed_t estimated_dist = player->mo->AproxDistance(rtarget); + double last_z = last_s->floorplane.ZatPoint (player->mo); + double estimated_dist = player->mo->Distance2D(rtarget); bool reachable = true; - FPathTraverse it(player->mo->X()+player->mo->vel.x, player->mo->Y()+player->mo->vel.y, rtarget->X(), rtarget->Y(), PT_ADDLINES|PT_ADDTHINGS); + FPathTraverse it(player->mo->X()+player->mo->Vel.X, player->mo->Y()+player->mo->Vel.Y, rtarget->X(), rtarget->Y(), PT_ADDLINES|PT_ADDTHINGS); intercept_t *in; while ((in = it.Next())) { - fixed_t hitx, hity; - fixed_t frac; + double hitx, hity; + double frac; line_t *line; AActor *thing; - fixed_t dist; + double dist; sector_t *s; - frac = in->frac - FixedDiv (4*FRACUNIT, MAX_TRAVERSE_DIST); - dist = FixedMul (frac, MAX_TRAVERSE_DIST); + frac = in->frac - 4 /MAX_TRAVERSE_DIST; + dist = frac * MAX_TRAVERSE_DIST; - hitx = it.Trace().x + FixedMul (player->mo->vel.x, frac); - hity = it.Trace().y + FixedMul (player->mo->vel.y, frac); + hitx = it.Trace().x + player->mo->Vel.X * frac; + hity = it.Trace().y + player->mo->Vel.Y * frac; if (in->isaline) { @@ -73,13 +73,13 @@ bool DBot::Reachable (AActor *rtarget) { //Determine if going to use backsector/frontsector. s = (line->backsector == last_s) ? line->frontsector : line->backsector; - fixed_t ceilingheight = s->ceilingplane.ZatPoint (hitx, hity); - fixed_t floorheight = s->floorplane.ZatPoint (hitx, hity); + double ceilingheight = s->ceilingplane.ZatPoint (hitx, hity); + double floorheight = s->floorplane.ZatPoint (hitx, hity); if (!bglobal.IsDangerous (s) && //Any nukage/lava? (floorheight <= (last_z+MAXMOVEHEIGHT) && ((ceilingheight == floorheight && line->special) - || (ceilingheight - floorheight) >= player->mo->height))) //Does it fit? + || (ceilingheight - floorheight) >= player->mo->Height))) //Does it fit? { last_z = floorheight; last_s = s; @@ -118,16 +118,16 @@ bool DBot::Reachable (AActor *rtarget) //if these conditions are true, the function returns true. //GOOD TO KNOW is that the player's view angle //in doom is 90 degrees infront. -bool DBot::Check_LOS (AActor *to, angle_t vangle) +bool DBot::Check_LOS (AActor *to, DAngle vangle) { if (!P_CheckSight (player->mo, to, SF_SEEPASTBLOCKEVERYTHING)) return false; // out of sight - if (vangle == ANGLE_MAX) + if (vangle >= 360.) return true; if (vangle == 0) return false; //Looker seems to be blind. - return absangle(player->mo->AngleTo(to) - player->mo->angle) <= vangle/2; + return absangle(player->mo->AngleTo(to), player->mo->Angles.Yaw) <= (vangle/2); } //------------------------------------- @@ -140,9 +140,10 @@ void DBot::Dofire (ticcmd_t *cmd) bool no_fire; //used to prevent bot from pumping rockets into nearby walls. int aiming_penalty=0; //For shooting at shading target, if screen is red, MAKEME: When screen red. int aiming_value; //The final aiming value. - fixed_t dist; - angle_t an; - int m; + double Dist; + DAngle an; + DAngle m; + double fm; if (!enemy || !(enemy->flags & MF_SHOOTABLE) || enemy->health <= 0) return; @@ -170,7 +171,7 @@ void DBot::Dofire (ticcmd_t *cmd) no_fire = true; //Distance to enemy. - dist = player->mo->AproxDistance(enemy, player->mo->vel.x - enemy->vel.x, player->mo->vel.y - enemy->vel.y); + Dist = player->mo->Distance2D(enemy, player->mo->Vel.X - enemy->Vel.X, player->mo->Vel.Y - enemy->Vel.Y); //FIRE EACH TYPE OF WEAPON DIFFERENT: Here should all the different weapons go. if (player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON) @@ -192,7 +193,7 @@ void DBot::Dofire (ticcmd_t *cmd) else { //*4 is for atmosphere, the chainsaws sounding and all.. - no_fire = (dist > (MELEERANGE*4)); + no_fire = (Dist > MELEERANGE*4); } } else if (player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG) @@ -208,11 +209,11 @@ void DBot::Dofire (ticcmd_t *cmd) { //Special rules for RL an = FireRox (enemy, cmd); - if(an) + if(an != 0) { - angle = an; + Angle = an; //have to be somewhat precise. to avoid suicide. - if (absangle(angle - player->mo->angle) < 12*ANGLE_1) + if (absangle(an, player->mo->Angles.Yaw) < 12.) { t_rocket = 9; no_fire = false; @@ -221,17 +222,17 @@ void DBot::Dofire (ticcmd_t *cmd) } // prediction aiming shootmissile: - dist = player->mo->AproxDistance (enemy); - m = dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed; - bglobal.SetBodyAt (enemy->X() + enemy->vel.x*m*2, enemy->Y() + enemy->vel.y*m*2, enemy->Z(), 1); - angle = player->mo->AngleTo(bglobal.body1); + Dist = player->mo->Distance2D(enemy); + fm = Dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed; + bglobal.SetBodyAt(enemy->Pos() + enemy->Vel.XY() * fm * 2, 1); + Angle = player->mo->AngleTo(bglobal.body1); if (Check_LOS (enemy, SHOOTFOV)) no_fire = false; } else { //Other weapons, mostly instant hit stuff. - angle = player->mo->AngleTo(enemy); + Angle = player->mo->AngleTo(enemy); aiming_penalty = 0; if (enemy->flags & MF_SHADOW) aiming_penalty += (pr_botdofire()%25)+10; @@ -244,17 +245,17 @@ shootmissile: aiming_value = 1; m = ((SHOOTFOV/2)-(aiming_value*SHOOTFOV/200)); //Higher skill is more accurate if (m <= 0) - m = 1; //Prevents lock. + m = 1.; //Prevents lock. - if (m) + if (m != 0) { if (increase) - angle += m; + Angle += m; else - angle -= m; + Angle -= m; } - if (absangle(angle - player->mo->angle) < 4*ANGLE_1) + if (absangle(Angle, player->mo->Angles.Yaw) < 4.) { increase = !increase; } @@ -283,13 +284,55 @@ bool FCajunMaster::IsLeader (player_t *player) return false; } +extern int BotWTG; + +void FCajunMaster::BotTick(AActor *mo) +{ + BotSupportCycles.Clock(); + bglobal.m_Thinking = true; + for (int i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].Bot == NULL) + continue; + + if (mo->flags3 & MF3_ISMONSTER) + { + if (mo->health > 0 + && !players[i].Bot->enemy + && mo->player ? !mo->IsTeammate(players[i].mo) : true + && mo->Distance2D(players[i].mo) < MAX_MONSTER_TARGET_DIST + && P_CheckSight(players[i].mo, mo, SF_SEEPASTBLOCKEVERYTHING)) + { //Probably a monster, so go kill it. + players[i].Bot->enemy = mo; + } + } + else if (mo->flags & MF_SPECIAL) + { //Item pickup time + //clock (BotWTG); + players[i].Bot->WhatToGet(mo); + //unclock (BotWTG); + BotWTG++; + } + else if (mo->flags & MF_MISSILE) + { + if (!players[i].Bot->missile && (mo->flags3 & MF3_WARNBOT)) + { //warn for incoming missiles. + if (mo->target != players[i].mo && players[i].Bot->Check_LOS(mo, 90.)) + players[i].Bot->missile = mo; + } + } + } + bglobal.m_Thinking = false; + BotSupportCycles.Unclock(); +} + //This function is called every //tick (for each bot) to set //the mate (teammate coop mate). AActor *DBot::Choose_Mate () { int count; - fixed_t closest_dist, test; + double closest_dist, test; AActor *target; AActor *observer; @@ -310,7 +353,7 @@ AActor *DBot::Choose_Mate () last_mate = NULL; target = NULL; - closest_dist = FIXED_MAX; + closest_dist = FLT_MAX; if (bot_observer) observer = players[consoleplayer].mo; else @@ -332,7 +375,7 @@ AActor *DBot::Choose_Mate () { if (P_CheckSight (player->mo, client->mo, SF_IGNOREVISIBILITY)) { - test = client->mo->AproxDistance(player->mo); + test = client->mo->Distance2D(player->mo); if (test < closest_dist) { @@ -366,9 +409,9 @@ AActor *DBot::Choose_Mate () AActor *DBot::Find_enemy () { int count; - fixed_t closest_dist, temp; //To target. + double closest_dist, temp; //To target. AActor *target; - angle_t vangle; + DAngle vangle; AActor *observer; if (!deathmatch) @@ -378,13 +421,13 @@ AActor *DBot::Find_enemy () //Note: It's hard to ambush a bot who is not alone if (allround || mate) - vangle = ANGLE_MAX; + vangle = 360.; else vangle = ENEMY_SCAN_FOV; allround = false; target = NULL; - closest_dist = FIXED_MAX; + closest_dist = FLT_MAX; if (bot_observer) observer = players[consoleplayer].mo; else @@ -402,7 +445,7 @@ AActor *DBot::Find_enemy () if (Check_LOS (client->mo, vangle)) //Here's a strange one, when bot is standing still, the P_CheckSight within Check_LOS almost always returns false. tought it should be the same checksight as below but.. (below works) something must be fuckin wierd screded up. //if(P_CheckSight(player->mo, players[count].mo)) { - temp = client->mo->AproxDistance(player->mo); + temp = client->mo->Distance2D(player->mo); //Too dark? if (temp > DARK_DIST && @@ -425,28 +468,28 @@ AActor *DBot::Find_enemy () //Creates a temporary mobj (invisible) at the given location. -void FCajunMaster::SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum) +void FCajunMaster::SetBodyAt (const DVector3 &pos, int hostnum) { if (hostnum == 1) { if (body1) { - body1->SetOrigin (x, y, z, false); + body1->SetOrigin (pos, false); } else { - body1 = Spawn ("CajunBodyNode", x, y, z, NO_REPLACE); + body1 = Spawn ("CajunBodyNode", pos, NO_REPLACE); } } else if (hostnum == 2) { if (body2) { - body2->SetOrigin (x, y, z, false); + body2->SetOrigin (pos, false); } else { - body2 = Spawn ("CajunBodyNode", x, y, z, NO_REPLACE); + body2 = Spawn ("CajunBodyNode", pos, NO_REPLACE); } } } @@ -461,27 +504,21 @@ void FCajunMaster::SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum) //Emulates missile travel. Returns distance travelled. -fixed_t FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd) +double FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd) { - AActor *th = Spawn ("CajunTrace", source->PosPlusZ(4*8*FRACUNIT), NO_REPLACE); + AActor *th = Spawn ("CajunTrace", source->PosPlusZ(4*8.), NO_REPLACE); th->target = source; // where it came from - float speed = (float)th->Speed; - fixedvec3 fixvel = source->Vec3To(dest); - DVector3 velocity(fixvel.x, fixvel.y, fixvel.z); - velocity.MakeUnit(); - th->vel.x = FLOAT2FIXED(velocity[0] * speed); - th->vel.y = FLOAT2FIXED(velocity[1] * speed); - th->vel.z = FLOAT2FIXED(velocity[2] * speed); + th->Vel = source->Vec3To(dest).Resized(th->Speed); - fixed_t dist = 0; + double dist = 0; while (dist < SAFE_SELF_MISDIST) { dist += th->Speed; - th->Move(th->vel.x, th->vel.y, th->vel.z); + th->Move(th->Vel); if (!CleanAhead (th, th->X(), th->Y(), cmd)) break; } @@ -489,27 +526,23 @@ fixed_t FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd) return dist; } -angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) +DAngle DBot::FireRox (AActor *enemy, ticcmd_t *cmd) { - fixed_t dist; - angle_t ang; + double dist; AActor *actor; - int m; + double m; - bglobal.SetBodyAt (player->mo->X() + FixedMul(player->mo->vel.x, 5*FRACUNIT), - player->mo->Y() + FixedMul(player->mo->vel.y, 5*FRACUNIT), - player->mo->Z() + (player->mo->height / 2), 2); + bglobal.SetBodyAt(player->mo->PosPlusZ(player->mo->Height / 2) + player->mo->Vel.XY() * 5, 2); actor = bglobal.body2; - dist = actor->AproxDistance (enemy); + dist = actor->Distance2D (enemy); if (dist < SAFE_SELF_MISDIST) - return 0; + return 0.; //Predict. - m = (((dist+1)/FRACUNIT) / GetDefaultByName("Rocket")->Speed); + m = ((dist+1) / GetDefaultByName("Rocket")->Speed); - bglobal.SetBodyAt (enemy->X() + FixedMul(enemy->vel.x, (m+2*FRACUNIT)), - enemy->Y() + FixedMul(enemy->vel.y, (m+2*FRACUNIT)), ONFLOORZ, 1); + bglobal.SetBodyAt(DVector3((enemy->Pos() + enemy->Vel * (m + 2)), ONFLOORZ), 1); //try the predicted location if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile @@ -519,8 +552,7 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) { if (bglobal.FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST) { - ang = actor->AngleTo(bglobal.body1); - return ang; + return actor->AngleTo(bglobal.body1); } } } @@ -529,21 +561,20 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) { if (bglobal.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST) { - ang = player->mo->AngleTo(enemy); - return ang; + return player->mo->AngleTo(enemy); } } - return 0; + return 0.; } // [RH] We absolutely do not want to pick things up here. The bot code is // executed apart from all the other simulation code, so we don't want it // creating side-effects during gameplay. -bool FCajunMaster::SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm) +bool FCajunMaster::SafeCheckPosition (AActor *actor, double x, double y, FCheckPosition &tm) { ActorFlags savedFlags = actor->flags; actor->flags &= ~MF_PICKUP; - bool res = P_CheckPosition (actor, x, y, tm); + bool res = P_CheckPosition (actor, DVector2(x, y), tm); actor->flags = savedFlags; return res; } diff --git a/src/b_move.cpp b/src/b_move.cpp index 6138ba3ad..b31e4acbe 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -21,6 +21,7 @@ #include "d_player.h" #include "p_spec.h" #include "p_checkposition.h" +#include "math/cmath.h" static FRandom pr_botopendoor ("BotOpenDoor"); static FRandom pr_bottrywalk ("BotTryWalk"); @@ -34,21 +35,21 @@ extern dirtype_t diags[4]; //which can be a weapon/enemy/item whatever. void DBot::Roam (ticcmd_t *cmd) { - int delta; if (Reachable(dest)) { // Straight towards it. - angle = player->mo->AngleTo(dest); + Angle = player->mo->AngleTo(dest); } else if (player->mo->movedir < 8) // turn towards movement direction if not there yet { - angle &= (angle_t)(7<<29); - delta = angle - (player->mo->movedir << 29); + // no point doing this with floating point angles... + unsigned angle = Angle.BAMs() & (unsigned)(7 << 29); + int delta = angle - (player->mo->movedir << 29); if (delta > 0) - angle -= ANG45; + Angle -= 45; else if (delta < 0) - angle += ANG45; + Angle += 45; } // chase towards destination. @@ -60,7 +61,7 @@ void DBot::Roam (ticcmd_t *cmd) bool DBot::Move (ticcmd_t *cmd) { - fixed_t tryx, tryy; + double tryx, tryy; bool try_ok; int good; @@ -147,18 +148,18 @@ void DBot::NewChaseDir (ticcmd_t *cmd) olddir = (dirtype_t)player->mo->movedir; turnaround = opposite[olddir]; - fixedvec2 delta = player->mo->Vec2To(dest); + DVector2 delta = player->mo->Vec2To(dest); - if (delta.x > 10*FRACUNIT) + if (delta.X > 10) d[1] = DI_EAST; - else if (delta.x < -10*FRACUNIT) + else if (delta.X < -10) d[1] = DI_WEST; else d[1] = DI_NODIR; - if (delta.y < -10*FRACUNIT) + if (delta.Y < -10) d[2] = DI_SOUTH; - else if (delta.y > 10*FRACUNIT) + else if (delta.Y > 10) d[2] = DI_NORTH; else d[2] = DI_NODIR; @@ -166,19 +167,19 @@ void DBot::NewChaseDir (ticcmd_t *cmd) // try direct route if (d[1] != DI_NODIR && d[2] != DI_NODIR) { - player->mo->movedir = diags[((delta.y<0)<<1)+(delta.x>0)]; + player->mo->movedir = diags[((delta.Y < 0) << 1) + (delta.X > 0)]; if (player->mo->movedir != turnaround && TryWalk(cmd)) return; } // try other directions - if (pr_botnewchasedir() > 200 - || abs(delta.y)>abs(delta.x)) - { - tdir=d[1]; - d[1]=d[2]; - d[2]=(dirtype_t)tdir; - } + if (pr_botnewchasedir() > 200 + || fabs(delta.Y) > fabs(delta.X)) + { + tdir = d[1]; + d[1] = d[2]; + d[2] = (dirtype_t)tdir; + } if (d[1]==turnaround) d[1]=DI_NODIR; @@ -259,7 +260,7 @@ void DBot::NewChaseDir (ticcmd_t *cmd) // This is also a traverse function for // bots pre-rocket fire (preventing suicide) // -bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cmd) +bool FCajunMaster::CleanAhead (AActor *thing, double x, double y, ticcmd_t *cmd) { FCheckPosition tm; @@ -268,30 +269,30 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm if (!(thing->flags & MF_NOCLIP) ) { - fixed_t maxstep = thing->MaxStepHeight; - if (tm.ceilingz - tm.floorz < thing->height) + if (tm.ceilingz - tm.floorz < thing->Height) return false; // doesn't fit + double maxmove = MAXMOVEHEIGHT; if (!(thing->flags&MF_MISSILE)) { - if(tm.floorz > (thing->Sector->floorplane.ZatPoint (x, y)+MAXMOVEHEIGHT)) //Too high wall + if(tm.floorz > (thing->Sector->floorplane.ZatPoint(x, y)+maxmove)) //Too high wall return false; //Jumpable - if(tm.floorz>(thing->Sector->floorplane.ZatPoint (x, y)+thing->MaxStepHeight)) + if(tm.floorz > (thing->Sector->floorplane.ZatPoint(x, y)+thing->MaxStepHeight)) cmd->ucmd.buttons |= BT_JUMP; if ( !(thing->flags & MF_TELEPORT) && - tm.ceilingz - thing->Z() < thing->height) + tm.ceilingz < thing->Top()) return false; // mobj must lower itself to fit // jump out of water // if((thing->eflags & (MF_UNDERWATER|MF_TOUCHWATER))==(MF_UNDERWATER|MF_TOUCHWATER)) -// maxstep=37*FRACUNIT; +// maxstep=37; if ( !(thing->flags & MF_TELEPORT) && - (tm.floorz - thing->Z() > maxstep ) ) + (tm.floorz - thing->Z() > thing->MaxStepHeight) ) return false; // too big a step up @@ -304,13 +305,13 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm return true; } -#define OKAYRANGE (5*ANGLE_1) //counts *2, when angle is in range, turning is not executed. -#define MAXTURN (15*ANGLE_1) //Max degrees turned in one tic. Lower is smother but may cause the bot not getting where it should = crash +#define OKAYRANGE (5) //counts *2, when angle is in range, turning is not executed. +#define MAXTURN (15) //Max degrees turned in one tic. Lower is smother but may cause the bot not getting where it should = crash #define TURNSENS 3 //Higher is smoother but slower turn. void DBot::TurnToAng () { - int maxturn = MAXTURN; + double maxturn = MAXTURN; if (player->ReadyWeapon != NULL) { @@ -326,20 +327,20 @@ void DBot::TurnToAng () if(enemy) if(!dest) //happens when running after item in combat situations, or normal, prevents weak turns if(player->ReadyWeapon->ProjectileType == NULL && !(player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON)) - if(Check_LOS(enemy, SHOOTFOV+5*ANGLE_1)) + if(Check_LOS(enemy, SHOOTFOV+5)) maxturn = 3; } - int distance = angle - player->mo->angle; + DAngle distance = deltaangle(player->mo->Angles.Yaw, Angle); - if (abs (distance) < OKAYRANGE && !enemy) + if (fabs (distance) < OKAYRANGE && !enemy) return; distance /= TURNSENS; - if (abs (distance) > maxturn) + if (fabs (distance) > maxturn) distance = distance < 0 ? -maxturn : maxturn; - player->mo->angle += distance; + player->mo->Angles.Yaw += distance; } void DBot::Pitch (AActor *target) @@ -348,8 +349,8 @@ void DBot::Pitch (AActor *target) double diff; diff = target->Z() - player->mo->Z(); - aim = atan(diff / (double)player->mo->AproxDistance(target)); - player->mo->pitch = -(int)(aim * ANGLE_180/M_PI); + aim = g_atan(diff / player->mo->Distance2D(target)); + player->mo->Angles.Pitch = DAngle::ToDegrees(aim); } //Checks if a sector is dangerous. diff --git a/src/b_think.cpp b/src/b_think.cpp index 88c17fd87..0ff75722a 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -20,6 +20,7 @@ #include "d_net.h" #include "d_event.h" #include "d_player.h" +#include "vectors.h" static FRandom pr_botmove ("BotMove"); @@ -39,20 +40,21 @@ void DBot::Think () if (teamplay || !deathmatch) mate = Choose_Mate (); - angle_t oldyaw = player->mo->angle; - int oldpitch = player->mo->pitch; + AActor *actor = player->mo; + DAngle oldyaw = actor->Angles.Yaw; + DAngle oldpitch = actor->Angles.Pitch; Set_enemy (); ThinkForMove (cmd); TurnToAng (); - cmd->ucmd.yaw = (short)((player->mo->angle - oldyaw) >> 16) / ticdup; - cmd->ucmd.pitch = (short)((oldpitch - player->mo->pitch) >> 16); + cmd->ucmd.yaw = (short)((actor->Angles.Yaw - oldyaw).Degrees * (65536 / 360.f)) / ticdup; + cmd->ucmd.pitch = (short)((oldpitch - actor->Angles.Pitch).Degrees * (65536 / 360.f)); if (cmd->ucmd.pitch == -32768) cmd->ucmd.pitch = -32767; cmd->ucmd.pitch /= ticdup; - player->mo->angle = oldyaw + (cmd->ucmd.yaw << 16) * ticdup; - player->mo->pitch = oldpitch - (cmd->ucmd.pitch << 16) * ticdup; + actor->Angles.Yaw = oldyaw + DAngle(cmd->ucmd.yaw * ticdup * (360 / 65536.f)); + actor->Angles.Pitch = oldpitch - DAngle(cmd->ucmd.pitch * ticdup * (360 / 65536.f)); } if (t_active) t_active--; @@ -73,38 +75,41 @@ void DBot::Think () } } +#define THINKDISTSQ (50000.*50000./(65536.*65536.)) //how the bot moves. //MAIN movement function. void DBot::ThinkForMove (ticcmd_t *cmd) { - fixed_t dist; + double dist; bool stuck; int r; stuck = false; - dist = dest ? player->mo->AproxDistance(dest) : 0; + dist = dest ? player->mo->Distance2D(dest) : 0; if (missile && - ((!missile->vel.x || !missile->vel.y) || !Check_LOS(missile, SHOOTFOV*3/2))) + (!missile->Vel.X || !missile->Vel.Y || !Check_LOS(missile, SHOOTFOV*3/2))) { sleft = !sleft; missile = NULL; //Probably ended its travel. } - if (player->mo->pitch > 0) - player->mo->pitch -= 80; - else if (player->mo->pitch <= -60) - player->mo->pitch += 80; +#if 0 // this has always been broken and without any reference it cannot be fixed. + if (player->mo->Angles.Pitch > 0) + player->mo->Angles.Pitch -= 80; + else if (player->mo->Angles.Pitch <= -60) + player->mo->Angles.Pitch += 80; +#endif //HOW TO MOVE: - if (missile && (player->mo->AproxDistance(missile)mo->Distance2D(missile)mo->AngleTo(missile); + Angle = player->mo->AngleTo(missile); cmd->ucmd.sidemove = sleft ? -SIDERUN : SIDERUN; cmd->ucmd.forwardmove = -FORWARDRUN; //Back IS best. - if ((player->mo->AproxDistance(oldx, oldy)<50000) + if ((player->mo->Pos() - old).LengthSquared() < THINKDISTSQ && t_strafe<=0) { t_strafe = 5; @@ -157,7 +162,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) t_fight = AFTERTICS; if (t_strafe <= 0 && - (player->mo->AproxDistance(oldx, oldy)<50000 + ((player->mo->Pos() - old).LengthSquared() < THINKDISTSQ || ((pr_botmove()%30)==10)) ) { @@ -166,10 +171,10 @@ void DBot::ThinkForMove (ticcmd_t *cmd) sleft = !sleft; } - angle = player->mo->AngleTo(enemy); + Angle = player->mo->AngleTo(enemy); if (player->ReadyWeapon == NULL || - player->mo->AproxDistance(enemy) > + player->mo->Distance2D(enemy) > player->ReadyWeapon->MoveCombatDist) { // If a monster, use lower speed (just for cooler apperance while strafing down doomed monster) @@ -194,7 +199,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) } else if (mate && !enemy && (!dest || dest==mate)) //Follow mate move. { - fixed_t matedist; + double matedist; Pitch (mate); @@ -207,9 +212,9 @@ void DBot::ThinkForMove (ticcmd_t *cmd) goto roam; } - angle = player->mo->AngleTo(mate); + Angle = player->mo->AngleTo(mate); - matedist = player->mo->AproxDistance(mate); + matedist = player->mo->Distance2D(mate); if (matedist > (FRIEND_DIST*2)) cmd->ucmd.forwardmove = FORWARDRUN; else if (matedist > FRIEND_DIST) @@ -242,7 +247,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) (pr_botmove()%100)>skill.isp) && player->ReadyWeapon != NULL && !(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)) dest = enemy;//Dont let enemy kill the bot by supressive fire. So charge enemy. else //hide while t_fight, but keep view at enemy. - angle = player->mo->AngleTo(enemy); + Angle = player->mo->AngleTo(enemy); } //Just a monster, so kill it. else dest = enemy; @@ -304,8 +309,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) if (t_fight<(AFTERTICS/2)) player->mo->flags |= MF_DROPOFF; - oldx = player->mo->X(); - oldy = player->mo->Y(); + old = player->mo->Pos(); } //BOT_WhatToGet diff --git a/src/basictypes.h b/src/basictypes.h index 6c71fce9b..7816fa557 100644 --- a/src/basictypes.h +++ b/src/basictypes.h @@ -1,16 +1,6 @@ #ifndef __BASICTYPES_H #define __BASICTYPES_H -#ifdef _MSC_VER -typedef __int8 SBYTE; -typedef unsigned __int8 BYTE; -typedef __int16 SWORD; -typedef unsigned __int16 WORD; -typedef __int32 SDWORD; -typedef unsigned __int32 uint32; -typedef __int64 SQWORD; -typedef unsigned __int64 QWORD; -#else #include typedef int8_t SBYTE; @@ -21,11 +11,6 @@ typedef int32_t SDWORD; typedef uint32_t uint32; typedef int64_t SQWORD; typedef uint64_t QWORD; -#endif - -typedef SDWORD int32; -typedef float real32; -typedef double real64; // windef.h, included by windows.h, has its own incompatible definition // of DWORD as a long. In files that mix Doom and Windows code, you @@ -73,7 +58,7 @@ union QWORD_UNION }; // -// Fixed point, 32bit as 16.16. +// fixed point, 32bit as 16.16. // #define FRACBITS 16 #define FRACUNIT (1<angle,MISSILERANGE, &t, 0); + P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->Angles.Yaw, MISSILERANGE, &t, 0.); if (t.linetarget) { Printf("Target=%s, Health=%d, Spawnhealth=%d\n", @@ -892,8 +892,8 @@ CCMD(info) FTranslatedLineTarget t; if (CheckCheatmode () || players[consoleplayer].mo == NULL) return; - P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, - &t, 0, ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART); + P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->Angles.Yaw, MISSILERANGE, + &t, 0., ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART); if (t.linetarget) { Printf("Target=%s, Health=%d, Spawnhealth=%d\n", @@ -943,9 +943,8 @@ static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const cha { if ((FilterClass == NULL || mo->IsA(FilterClass)) && IsActorType(mo)) { - Printf ("%s at (%d,%d,%d)\n", - mo->GetClass()->TypeName.GetChars(), - mo->X() >> FRACBITS, mo->Y() >> FRACBITS, mo->Z() >> FRACBITS); + Printf ("%s at (%f,%f,%f)\n", + mo->GetClass()->TypeName.GetChars(), mo->X(), mo->Y(), mo->Z()); } } } @@ -1087,7 +1086,7 @@ CCMD(currentpos) if(mo) { Printf("Current player position: (%1.3f,%1.3f,%1.3f), angle: %1.3f, floorheight: %1.3f, sector:%d, lightlevel: %d\n", - FIXED2DBL(mo->X()), FIXED2DBL(mo->Y()), FIXED2DBL(mo->Z()), ANGLE2DBL(mo->angle), FIXED2DBL(mo->floorz), mo->Sector->sectornum, mo->Sector->lightlevel); + mo->X(), mo->Y(), mo->Z(), mo->Angles.Yaw.Normalized360().Degrees, mo->floorz, mo->Sector->sectornum, mo->Sector->lightlevel); } else { @@ -1245,9 +1244,9 @@ CCMD(angleconvtest) Printf("Testing degrees to angle conversion:\n"); for (double ang = -5 * 180.; ang < 5 * 180.; ang += 45.) { - angle_t ang1 = FLOAT2ANGLE(ang); - angle_t ang2 = (angle_t)(ang * (ANGLE_90 / 90.)); - angle_t ang3 = (angle_t)(int)(ang * (ANGLE_90 / 90.)); + unsigned ang1 = DAngle(ang).BAMs(); + unsigned ang2 = (unsigned)(ang * (0x40000000 / 90.)); + unsigned ang3 = (unsigned)(int)(ang * (0x40000000 / 90.)); Printf("Angle = %.5f: xs_RoundToInt = %08x, unsigned cast = %08x, signed cast = %08x\n", ang, ang1, ang2, ang3); } diff --git a/src/c_console.cpp b/src/c_console.cpp index 5c4b6e441..b86ea0b2c 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -732,15 +732,15 @@ static void C_DrawNotifyText () if (!show_messages && NotifyStrings[i].PrintLevel != 128) continue; - fixed_t alpha; + double alpha; if (j < NOTIFYFADETIME) { - alpha = OPAQUE * j / NOTIFYFADETIME; + alpha = 1. * j / NOTIFYFADETIME; } else { - alpha = OPAQUE; + alpha = 1; } if (NotifyStrings[i].PrintLevel >= PRINTLEVELS) @@ -752,23 +752,23 @@ static void C_DrawNotifyText () { if (!center) screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text, - DTA_CleanNoMove, true, DTA_Alpha, alpha, TAG_DONE); + DTA_CleanNoMove, true, DTA_AlphaF, alpha, TAG_DONE); else screen->DrawText (SmallFont, color, (SCREENWIDTH - SmallFont->StringWidth (NotifyStrings[i].Text)*CleanXfac)/2, line, NotifyStrings[i].Text, DTA_CleanNoMove, true, - DTA_Alpha, alpha, TAG_DONE); + DTA_AlphaF, alpha, TAG_DONE); } else if (con_scaletext == 0) { if (!center) screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text, - DTA_Alpha, alpha, TAG_DONE); + DTA_AlphaF, alpha, TAG_DONE); else screen->DrawText (SmallFont, color, (SCREENWIDTH - SmallFont->StringWidth (NotifyStrings[i].Text))/2, line, NotifyStrings[i].Text, - DTA_Alpha, alpha, TAG_DONE); + DTA_AlphaF, alpha, TAG_DONE); } else { @@ -777,7 +777,7 @@ static void C_DrawNotifyText () DTA_VirtualWidth, screen->GetWidth() / 2, DTA_VirtualHeight, screen->GetHeight() / 2, DTA_KeepRatio, true, - DTA_Alpha, alpha, TAG_DONE); + DTA_AlphaF, alpha, TAG_DONE); else screen->DrawText (SmallFont, color, (screen->GetWidth() / 2 - SmallFont->StringWidth (NotifyStrings[i].Text))/2, @@ -785,7 +785,7 @@ static void C_DrawNotifyText () DTA_VirtualWidth, screen->GetWidth() / 2, DTA_VirtualHeight, screen->GetHeight() / 2, DTA_KeepRatio, true, - DTA_Alpha, alpha, TAG_DONE); + DTA_AlphaF, alpha, TAG_DONE); } line += lineadv; canskip = false; @@ -865,7 +865,7 @@ void C_DrawConsole (bool hw2d) DTA_DestWidth, screen->GetWidth(), DTA_DestHeight, screen->GetHeight(), DTA_ColorOverlay, conshade, - DTA_Alpha, (hw2d && gamestate != GS_FULLCONSOLE) ? FLOAT2FIXED(con_alpha) : FRACUNIT, + DTA_AlphaF, (hw2d && gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1., DTA_Masked, false, TAG_DONE); if (conline && visheight < screen->GetHeight()) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index a440ac088..e7121da8b 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -290,7 +290,7 @@ void ParseCompatibility() sc.MustGetNumber(); CompatParams.Push(sc.Number); sc.MustGetFloat(); - CompatParams.Push(FLOAT2FIXED(sc.Float)); + CompatParams.Push(int(sc.Float*65536.)); } else if (sc.Compare("setwallyscale")) { @@ -303,7 +303,7 @@ void ParseCompatibility() sc.MustGetString(); CompatParams.Push(sc.MustMatchString(WallTiers)); sc.MustGetFloat(); - CompatParams.Push(FLOAT2FIXED(sc.Float)); + CompatParams.Push(int(sc.Float*65536.)); } else if (sc.Compare("setthingz")) { @@ -312,7 +312,7 @@ void ParseCompatibility() sc.MustGetNumber(); CompatParams.Push(sc.Number); sc.MustGetFloat(); - CompatParams.Push(FLOAT2FIXED(sc.Float)); + CompatParams.Push(int(sc.Float*256)); // do not use full fixed here so that it can eventually handle larger levels } else if (sc.Compare("setsectortag")) { @@ -522,7 +522,7 @@ void SetCompatibilityParams() { sector_t *sec = §ors[CompatParams[i+1]]; sec->floorplane.ChangeHeight(CompatParams[i+2]); - sec->ChangePlaneTexZ(sector_t::floor, CompatParams[i+2]); + sec->ChangePlaneTexZ(sector_t::floor, CompatParams[i+2] / 65536.); } i += 3; break; @@ -534,7 +534,7 @@ void SetCompatibilityParams() side_t *side = lines[CompatParams[i+1]].sidedef[CompatParams[i+2]]; if (side != NULL) { - side->SetTextureYScale(CompatParams[i+3], CompatParams[i+4]); + side->SetTextureYScale(CompatParams[i+3], CompatParams[i+4] / 65536.); } } i += 5; @@ -545,7 +545,7 @@ void SetCompatibilityParams() // When this is called, the things haven't been spawned yet so we can alter the position inside the MapThings array. if ((unsigned)CompatParams[i+1] < MapThingsConverted.Size()) { - MapThingsConverted[CompatParams[i+1]].z = CompatParams[i+2]; + MapThingsConverted[CompatParams[i+1]].pos.Z = CompatParams[i+2]/256.; } i += 3; break; diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 8c456517e..a7a378375 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -215,7 +215,7 @@ DehInfo deh = 2, // .KFAAC "PLAY", // Name of player sprite 255, // Rocket explosion style, 255=use cvar - FRACUNIT*2/3, // Rocket explosion alpha + 2./3., // Rocket explosion alpha false, // .NoAutofreeze 40, // BFG cells per shot }; @@ -353,6 +353,11 @@ static bool ReadChars (char **stuff, int size); static char *igets (void); static int GetLine (void); +inline double DEHToDouble(int acsval) +{ + return acsval / 65536.; +} + static void PushTouchedActor(PClassActor *cls) { for(unsigned i = 0; i < TouchedActors.Size(); i++) @@ -647,7 +652,7 @@ static int CreateMushroomFunc(VMFunctionBuilder &buildit, int value1, int value2 } else { - buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(FIXED2DBL(value1))); + buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(DEHToDouble(value1))); } // hrange if (value2 == 0) @@ -656,7 +661,7 @@ static int CreateMushroomFunc(VMFunctionBuilder &buildit, int value1, int value2 } else { - buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(FIXED2DBL(value2))); + buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(DEHToDouble(value2))); } return 5; } @@ -896,14 +901,14 @@ static int PatchThing (int thingy) } else if (linelen == 12 && stricmp (Line1, "Translucency") == 0) { - info->alpha = val; + info->Alpha = DEHToDouble(val); info->RenderStyle = STYLE_Translucent; hadTranslucency = true; hadStyle = true; } else if (linelen == 6 && stricmp (Line1, "Height") == 0) { - info->height = val; + info->Height = DEHToDouble(val); info->projectilepassheight = 0; // needs to be disabled hadHeight = true; } @@ -915,20 +920,20 @@ static int PatchThing (int thingy) { if (stricmp (Line1, "Speed") == 0) { - info->Speed = val; + info->Speed = val; // handle fixed point later. } else if (stricmp (Line1, "Width") == 0) { - info->radius = val; + info->radius = DEHToDouble(val); } else if (stricmp (Line1, "Alpha") == 0) { - info->alpha = (fixed_t)(atof (Line2) * FRACUNIT); + info->Alpha = atof (Line2); hadTranslucency = true; } else if (stricmp (Line1, "Scale") == 0) { - info->scaleY = info->scaleX = clamp (FLOAT2FIXED(atof (Line2)), 1, 256*FRACUNIT); + info->Scale.Y = info->Scale.X = clamp(atof (Line2), 1./65536, 256.); } else if (stricmp (Line1, "Decal") == 0) { @@ -1141,14 +1146,12 @@ static int PatchThing (int thingy) } // MBF bounce factors depend on flag combos: - enum - { - MBF_BOUNCE_NOGRAVITY = FRACUNIT, // With NOGRAVITY: full momentum - MBF_BOUNCE_FLOATDROPOFF = (FRACUNIT * 85) / 100,// With FLOAT and DROPOFF: 85% - MBF_BOUNCE_FLOAT = (FRACUNIT * 70) / 100,// With FLOAT alone: 70% - MBF_BOUNCE_DEFAULT = (FRACUNIT * 45) / 100,// Without the above flags: 45% - MBF_BOUNCE_WALL = (FRACUNIT * 50) / 100,// Bouncing off walls: 50% - }; + const double MBF_BOUNCE_NOGRAVITY = 1; // With NOGRAVITY: full momentum + const double MBF_BOUNCE_FLOATDROPOFF = 0.85; // With FLOAT and DROPOFF: 85% + const double MBF_BOUNCE_FLOAT = 0.7; // With FLOAT alone: 70% + const double MBF_BOUNCE_DEFAULT = 0.45; // Without the above flags: 45% + const double MBF_BOUNCE_WALL = 0.5; // Bouncing off walls: 50% + info->bouncefactor = ((value[0] & MF_NOGRAVITY) ? MBF_BOUNCE_NOGRAVITY : (value[0] & MF_FLOAT) ? (value[0] & MF_DROPOFF) ? MBF_BOUNCE_FLOATDROPOFF : MBF_BOUNCE_FLOAT : MBF_BOUNCE_DEFAULT); @@ -1215,7 +1218,7 @@ static int PatchThing (int thingy) } if (value[1] & 0x00000001) { - info->gravity = FRACUNIT/4; + info->Gravity = 1./4; value[1] &= ~0x00000001; } info->flags2 = ActorFlags2::FromInt (value[1]); @@ -1226,11 +1229,11 @@ static int PatchThing (int thingy) { hadTranslucency = true; if (value[2] & 1) - info->alpha = TRANSLUC25; + info->Alpha = 0.25; else if (value[2] & 2) - info->alpha = TRANSLUC50; + info->Alpha = 0.5; else if (value[2] & 4) - info->alpha = TRANSLUC75; + info->Alpha = 0.75; info->RenderStyle = STYLE_Translucent; } if (value[2] & 8) @@ -1257,7 +1260,7 @@ static int PatchThing (int thingy) !hadHeight && thingy <= (int)OrgHeights.Size() && thingy > 0) { - info->height = OrgHeights[thingy - 1] * FRACUNIT; + info->Height = OrgHeights[thingy - 1]; info->projectilepassheight = 0; } // If the thing's shadow changed, change its fuzziness if not already specified @@ -1268,7 +1271,7 @@ static int PatchThing (int thingy) if (!hadStyle) info->RenderStyle = STYLE_OptFuzzy; if (!hadTranslucency) - info->alpha = FRACUNIT/5; + info->Alpha = 0.5; } else { // changed from shadow @@ -1276,11 +1279,11 @@ static int PatchThing (int thingy) info->RenderStyle = STYLE_Normal; } } - // If this thing's speed is really low (i.e. meant to be a monster), - // bump it up, because all speeds are fixed point now. - if (abs(info->Speed) < 256) + // Speed could be either an int of fixed value, depending on its use + // If this value is very large it needs to be rescaled. + if (fabs(info->Speed) >= 256) { - info->Speed <<= FRACBITS; + info->Speed /= 65536; } if (info->flags & MF_SPECIAL) @@ -1853,7 +1856,7 @@ static int PatchMisc (int dummy) } else if (stricmp (Line1, "Rocket Explosion Alpha") == 0) { - deh.ExplosionAlpha = (fixed_t)(atof (Line2) * FRACUNIT); + deh.ExplosionAlpha = atof (Line2); } else if (stricmp (Line1, "Monsters Infight") == 0) { @@ -1940,13 +1943,13 @@ static int PatchMisc (int dummy) if (armor!=NULL) { armor->SaveAmount = 100 * deh.GreenAC; - armor->SavePercent = deh.GreenAC == 1 ? FRACUNIT/3 : FRACUNIT/2; + armor->SavePercent = deh.GreenAC == 1 ? 0.33335 : 0.5; } armor = static_cast (GetDefaultByName ("BlueArmor")); if (armor!=NULL) { armor->SaveAmount = 100 * deh.BlueAC; - armor->SavePercent = deh.BlueAC == 1 ? FRACUNIT/3 : FRACUNIT/2; + armor->SavePercent = deh.BlueAC == 1 ? 0.33335 : 0.5; } ABasicArmorBonus *barmor; diff --git a/src/d_net.cpp b/src/d_net.cpp index 4d8e33d3d..0758ebe38 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2203,7 +2203,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) x = ReadWord (stream); y = ReadWord (stream); z = ReadWord (stream); - P_TeleportMove (players[player].mo, x * 65536, y * 65536, z * 65536, true); + P_TeleportMove (players[player].mo, DVector3(x, y, z), true); } break; @@ -2321,7 +2321,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) else { const AActor *def = GetDefaultByType (typeinfo); - fixedvec3 spawnpos = source->Vec3Angle(def->radius * 2 + source->radius, source->angle, 8 * FRACUNIT); + DVector3 spawnpos = source->Vec3Angle(def->radius * 2 + source->radius, source->Angles.Yaw, 8.); AActor *spawned = Spawn (typeinfo, spawnpos, ALLOW_REPLACE); if (spawned != NULL) @@ -2348,7 +2348,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) } if (type >= DEM_SUMMON2 && type <= DEM_SUMMONFOE2) { - spawned->angle = source->angle - (ANGLE_1 * angle); + spawned->Angles.Yaw = source->Angles.Yaw - angle; spawned->tid = tid; spawned->special = special; for(i = 0; i < 5; i++) { @@ -2366,19 +2366,15 @@ void Net_DoCommand (int type, BYTE **stream, int player) { FTraceResults trace; - angle_t ang = players[player].mo->angle >> ANGLETOFINESHIFT; - angle_t pitch = (angle_t)(players[player].mo->pitch) >> ANGLETOFINESHIFT; - fixed_t vx = FixedMul (finecosine[pitch], finecosine[ang]); - fixed_t vy = FixedMul (finecosine[pitch], finesine[ang]); - fixed_t vz = -finesine[pitch]; + DAngle ang = players[player].mo->Angles.Yaw; + DAngle pitch = players[player].mo->Angles.Pitch; + double c = pitch.Cos(); + DVector3 vec(c * ang.Cos(), c * ang.Sin(), -pitch.Sin()); s = ReadString (stream); - if (Trace (players[player].mo->X(), players[player].mo->Y(), - players[player].mo->Top() - (players[player].mo->height>>2), - players[player].mo->Sector, - vx, vy, vz, 172*FRACUNIT, 0, ML_BLOCKEVERYTHING, players[player].mo, - trace, TRACE_NoSky)) + if (Trace (players[player].mo->PosPlusZ(players[player].mo->Height/2), players[player].mo->Sector, + vec, 172., 0, ML_BLOCKEVERYTHING, players[player].mo, trace, TRACE_NoSky)) { if (trace.HitType == TRACE_HitWall) { @@ -2656,8 +2652,8 @@ void Net_DoCommand (int type, BYTE **stream, int player) break; case DEM_SETPITCHLIMIT: - players[player].MinPitch = ReadByte(stream) * -ANGLE_1; // up - players[player].MaxPitch = ReadByte(stream) * ANGLE_1; // down + players[player].MinPitch = -(double)ReadByte(stream); // up + players[player].MaxPitch = (double)ReadByte(stream); // down break; case DEM_ADVANCEINTER: diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 3cf40e932..c20b2aff6 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -878,33 +878,6 @@ void D_ReadUserInfoStrings (int pnum, BYTE **stream, bool update) *stream += strlen (*((char **)stream)) + 1; } -void ReadCompatibleUserInfo(FArchive &arc, userinfo_t &info) -{ - char netname[MAXPLAYERNAME + 1]; - BYTE team; - int aimdist, color, colorset, skin, gender; - bool neverswitch; - //fixed_t movebob, stillbob; These were never serialized! - //int playerclass; " - - info.Reset(); - - arc.Read(&netname, sizeof(netname)); - arc << team << aimdist << color << skin << gender << neverswitch << colorset; - - *static_cast(info[NAME_Name]) = netname; - *static_cast(info[NAME_Team]) = team; - *static_cast(info[NAME_Autoaim]) = ANGLE2FLOAT(aimdist); - *static_cast(info[NAME_Skin]) = skin; - *static_cast(info[NAME_Gender]) = gender; - *static_cast(info[NAME_NeverSwitchOnPickup]) = neverswitch; - *static_cast(info[NAME_ColorSet]) = colorset; - - UCVarValue val; - val.Int = color; - static_cast(info[NAME_Color])->SetGenericRep(val, CVAR_Int); -} - void WriteUserInfo(FArchive &arc, userinfo_t &info) { TMapIterator it(info); @@ -945,12 +918,6 @@ void ReadUserInfo(FArchive &arc, userinfo_t &info, FString &skin) char *str = NULL; UCVarValue val; - if (SaveVersion < 4253) - { - ReadCompatibleUserInfo(arc, info); - return; - } - info.Reset(); skin = NULL; for (arc << name; name != NAME_None; arc << name) diff --git a/src/d_player.h b/src/d_player.h index 749736996..40178dac1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -89,7 +89,7 @@ public: FString Slot[10]; FName InvulMode; FName HealingRadiusType; - fixed_t HexenArmor[5]; + double HexenArmor[5]; BYTE ColorRangeStart; // Skin color range BYTE ColorRangeEnd; FPlayerColorSetMap ColorSets; @@ -114,7 +114,7 @@ public: virtual void PlayIdle (); virtual void PlayRunning (); virtual void ThrowPoisonBag (); - virtual void TweakSpeeds (int &forwardmove, int &sidemove); + virtual void TweakSpeeds (double &forwardmove, double &sidemove); virtual void MorphPlayerThink (); virtual void ActivateMorphWeapon (); AWeapon *PickNewWeapon (PClassAmmo *ammotype); @@ -149,25 +149,25 @@ public: TObjPtr InvSel; // selected inventory item // [GRB] Player class properties - fixed_t JumpZ; - fixed_t GruntSpeed; - fixed_t FallingScreamMinSpeed, FallingScreamMaxSpeed; - fixed_t ViewHeight; - fixed_t ForwardMove1, ForwardMove2; - fixed_t SideMove1, SideMove2; + double JumpZ; + double GruntSpeed; + double FallingScreamMinSpeed, FallingScreamMaxSpeed; + double ViewHeight; + double ForwardMove1, ForwardMove2; + double SideMove1, SideMove2; FTextureID ScoreIcon; int SpawnMask; FNameNoInit MorphWeapon; - fixed_t AttackZOffset; // attack height, relative to player center - fixed_t UseRange; // [NS] Distance at which player can +use - fixed_t AirCapacity; // Multiplier for air supply underwater. + double AttackZOffset; // attack height, relative to player center + double UseRange; // [NS] Distance at which player can +use + double AirCapacity; // Multiplier for air supply underwater. PClassActor *FlechetteType; // [CW] Fades for when you are being damaged. PalEntry DamageFade; - bool UpdateWaterLevel (fixed_t oldz, bool splash); + bool UpdateWaterLevel (bool splash); bool ResetAirSupply (bool playgasp = true); int GetMaxHealth() const; @@ -292,7 +292,7 @@ struct userinfo_t : TMap { ~userinfo_t(); - int GetAimDist() const + double GetAimDist() const { if (dmflags2 & DF2_NOAUTOAIM) { @@ -302,11 +302,11 @@ struct userinfo_t : TMap float aim = *static_cast(*CheckKey(NAME_Autoaim)); if (aim > 35 || aim < 0) { - return ANGLE_1*35; + return 35.; } else { - return xs_RoundToInt(fabs(aim * ANGLE_1)); + return aim; } } const char *GetName() const @@ -329,13 +329,13 @@ struct userinfo_t : TMap { return *static_cast(*CheckKey(NAME_NeverSwitchOnPickup)); } - fixed_t GetMoveBob() const + double GetMoveBob() const { - return FLOAT2FIXED(*static_cast(*CheckKey(NAME_MoveBob))); + return *static_cast(*CheckKey(NAME_MoveBob)); } - fixed_t GetStillBob() const + double GetStillBob() const { - return FLOAT2FIXED(*static_cast(*CheckKey(NAME_StillBob))); + return *static_cast(*CheckKey(NAME_StillBob)); } int GetPlayerClassNum() const { @@ -402,16 +402,16 @@ public: float DesiredFOV; // desired field of vision float FOV; // current field of vision - fixed_t viewz; // focal origin above r.z - fixed_t viewheight; // base height above floor for viewz - fixed_t deltaviewheight; // squat speed. - fixed_t bob; // bounded/scaled total velocity + double viewz; // focal origin above r.z + double viewheight; // base height above floor for viewz + double deltaviewheight; // squat speed. + double bob; // bounded/scaled total velocity // killough 10/98: used for realistic bobbing (i.e. not simply overall speed) - // mo->vel.x and mo->vel.y represent true velocity experienced by player. + // mo->velx and mo->vely represent true velocity experienced by player. // This only represents the thrust that the player applies himself. // This avoids anomalies with such things as Boom ice and conveyors. - fixedvec2 vel; + DVector2 Vel; bool centering; BYTE turnticks; @@ -488,30 +488,30 @@ public: FString LogText; // [RH] Log for Strife - int MinPitch; // Viewpitch limits (negative is up, positive is down) - int MaxPitch; + DAngle MinPitch; // Viewpitch limits (negative is up, positive is down) + DAngle MaxPitch; - fixed_t crouchfactor; - fixed_t crouchoffset; - fixed_t crouchviewdelta; + double crouchfactor; + double crouchoffset; + double crouchviewdelta; FWeaponSlots weapons; // [CW] I moved these here for multiplayer conversation support. TObjPtr ConversationNPC, ConversationPC; - angle_t ConversationNPCAngle; + DAngle ConversationNPCAngle; bool ConversationFaceTalker; - fixed_t GetDeltaViewHeight() const + double GetDeltaViewHeight() const { - return (mo->ViewHeight + crouchviewdelta - viewheight) >> 3; + return (mo->ViewHeight + crouchviewdelta - viewheight) / 8; } void Uncrouch() { - if (crouchfactor != FRACUNIT) + if (crouchfactor != 1) { - crouchfactor = FRACUNIT; + crouchfactor = 1; crouchoffset = 0; crouchdir = 0; crouching = 0; @@ -533,7 +533,7 @@ extern player_t players[MAXPLAYERS]; FArchive &operator<< (FArchive &arc, player_t *&p); -void P_CheckPlayerSprite(AActor *mo, int &spritenum, fixed_t &scalex, fixed_t &scaley); +void P_CheckPlayerSprite(AActor *mo, int &spritenum, DVector2 &scale); inline void AActor::SetFriendPlayer(player_t *player) { @@ -556,7 +556,7 @@ inline bool AActor::IsNoClip2() const return false; } -#define CROUCHSPEED (FRACUNIT/12) +#define CROUCHSPEED (1./12) bool P_IsPlayerTotallyFrozen(const player_t *player); diff --git a/src/d_protocol.h b/src/d_protocol.h index 02212efe7..61f7377e3 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -50,9 +50,6 @@ #define NETD_ID BIGE_ID('N','E','T','D') #define WEAP_ID BIGE_ID('W','E','A','P') -#define ANGLE2SHORT(x) ((((x)/360) & 65535) -#define SHORT2ANGLE(x) ((x)*360) - struct zdemoheader_s { BYTE demovermajor; diff --git a/src/decallib.cpp b/src/decallib.cpp index 8f6678eff..fe8de4d0a 100644 --- a/src/decallib.cpp +++ b/src/decallib.cpp @@ -52,7 +52,7 @@ FDecalLib DecalLibrary; -static fixed_t ReadScale (FScanner &sc); +static double ReadScale (FScanner &sc); static TArray DecalTranslations; // A decal group holds multiple decals and returns one randomly @@ -148,7 +148,7 @@ public: int TimeToStartDecay; int TimeToEndDecay; - fixed_t StartTrans; + double StartTrans; private: DDecalFader () {} }; @@ -186,7 +186,7 @@ struct FDecalStretcherAnim : public FDecalAnimator int StretchStart; int StretchTime; - fixed_t GoalX, GoalY; + double GoalX, GoalY; }; class DDecalStretcher : public DDecalThinker @@ -199,10 +199,10 @@ public: int TimeToStart; int TimeToStop; - fixed_t GoalX; - fixed_t StartX; - fixed_t GoalY; - fixed_t StartY; + double GoalX; + double StartX; + double GoalY; + double StartY; bool bStretchX; bool bStretchY; bool bStarted; @@ -217,7 +217,7 @@ struct FDecalSliderAnim : public FDecalAnimator int SlideStart; int SlideTime; - fixed_t /*DistX,*/ DistY; + double /*DistX,*/ DistY; }; class DDecalSlider : public DDecalThinker @@ -230,10 +230,10 @@ public: int TimeToStart; int TimeToStop; -/* fixed_t DistX; */ - fixed_t DistY; - fixed_t StartX; - fixed_t StartY; +/* double DistX; */ + double DistY; + double StartX; + double StartY; bool bStarted; private: DDecalSlider () {} @@ -453,10 +453,10 @@ void FDecalLib::ParseDecal (FScanner &sc) memset ((void *)&newdecal, 0, sizeof(newdecal)); newdecal.PicNum.SetInvalid(); - newdecal.ScaleX = newdecal.ScaleY = FRACUNIT; + newdecal.ScaleX = newdecal.ScaleY = 1.; newdecal.RenderFlags = RF_WALLSPRITE; newdecal.RenderStyle = STYLE_Normal; - newdecal.Alpha = 0x8000; + newdecal.Alpha = 1.; for (;;) { @@ -492,13 +492,13 @@ void FDecalLib::ParseDecal (FScanner &sc) case DECAL_ADD: sc.MustGetFloat (); - newdecal.Alpha = (WORD)(32768.f * sc.Float); + newdecal.Alpha = sc.Float; newdecal.RenderStyle = STYLE_Add; break; case DECAL_TRANSLUCENT: sc.MustGetFloat (); - newdecal.Alpha = (WORD)(32768.f * sc.Float); + newdecal.Alpha = sc.Float; newdecal.RenderStyle = STYLE_Translucent; break; @@ -681,7 +681,7 @@ void FDecalLib::ParseFader (FScanner &sc) void FDecalLib::ParseStretcher (FScanner &sc) { FString stretcherName; - fixed_t goalX = -1, goalY = -1; + double goalX = -1, goalY = -1; int startTime = 0, takeTime = 0; sc.MustGetString (); @@ -732,7 +732,7 @@ void FDecalLib::ParseStretcher (FScanner &sc) void FDecalLib::ParseSlider (FScanner &sc) { FString sliderName; - fixed_t distX = 0, distY = 0; + double distX = 0, distY = 0; int startTime = 0, takeTime = 0; sc.MustGetString (); @@ -773,7 +773,7 @@ void FDecalLib::ParseSlider (FScanner &sc) else if (sc.Compare ("DistY")) { sc.MustGetFloat (); - distY = (fixed_t)(sc.Float * FRACUNIT); + distY = sc.Float; } else { @@ -1046,7 +1046,7 @@ void FDecalTemplate::ApplyToDecal (DBaseDecal *decal, side_t *wall) const decal->ScaleX = ScaleX; decal->ScaleY = ScaleY; decal->PicNum = PicNum; - decal->Alpha = Alpha << 1; + decal->Alpha = Alpha; decal->RenderStyle = RenderStyle; decal->RenderFlags = (RenderFlags & ~(DECAL_RandomFlipX|DECAL_RandomFlipY)) | (decal->RenderFlags & (RF_RELMASK|RF_CLIPMASK|RF_INVISIBLE|RF_ONESIDED)); @@ -1184,7 +1184,7 @@ void DDecalFader::Tick () int distanceToEnd = TimeToEndDecay - level.maptime; int fadeDistance = TimeToEndDecay - TimeToStartDecay; - TheDecal->Alpha = Scale (StartTrans, distanceToEnd, fadeDistance); + TheDecal->Alpha = StartTrans * distanceToEnd / fadeDistance; } } @@ -1278,11 +1278,11 @@ void DDecalStretcher::Tick () int maxDistance = TimeToStop - TimeToStart; if (bStretchX) { - TheDecal->ScaleX = StartX + Scale (GoalX - StartX, distance, maxDistance); + TheDecal->ScaleX = StartX + (GoalX - StartX) * distance / maxDistance; } if (bStretchY) { - TheDecal->ScaleY = StartY + Scale (GoalY - StartY, distance, maxDistance); + TheDecal->ScaleY = StartY + (GoalY - StartY) * distance / maxDistance; } } @@ -1339,8 +1339,8 @@ void DDecalSlider::Tick () int distance = level.maptime - TimeToStart; int maxDistance = TimeToStop - TimeToStart; - /*TheDecal->LeftDistance = StartX + Scale (DistX, distance, maxDistance);*/ - TheDecal->Z = StartY + Scale (DistY, distance, maxDistance); + /*TheDecal->LeftDistance = StartX + DistX * distance / maxDistance);*/ + TheDecal->Z = StartY + DistY * distance / maxDistance; } DThinker *FDecalCombinerAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const @@ -1428,8 +1428,8 @@ DThinker *FDecalColorerAnim::CreateThinker (DBaseDecal *actor, side_t *wall) con return Colorer; } -static fixed_t ReadScale (FScanner &sc) +static double ReadScale (FScanner &sc) { sc.MustGetFloat (); - return fixed_t(clamp (sc.Float * FRACUNIT, 256.0, 256.0*FRACUNIT)); + return clamp (sc.Float, 1/256.0, 256.0); } diff --git a/src/decallib.h b/src/decallib.h index 6375c90ee..5f08bdfd1 100644 --- a/src/decallib.h +++ b/src/decallib.h @@ -74,13 +74,13 @@ public: const FDecalTemplate *GetDecal () const; void ReplaceDecalRef (FDecalBase *from, FDecalBase *to); - fixed_t ScaleX, ScaleY; + double ScaleX, ScaleY; DWORD ShadeColor; DWORD Translation; FRenderStyle RenderStyle; FTextureID PicNum; WORD RenderFlags; - WORD Alpha; // same as (actor->alpha >> 1) + double Alpha; // same as actor->alpha const FDecalAnimator *Animator; const FDecalBase *LowerDecal; diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 030016e46..d2df43fde 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -80,8 +80,6 @@ PName *TypeName; PSound *TypeSound; PColor *TypeColor; PStatePointer *TypeState; -PFixed *TypeFixed; -PAngle *TypeAngle; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -663,9 +661,7 @@ void PType::StaticInit() RUNTIME_CLASS(PPrototype)->TypeTableType = RUNTIME_CLASS(PPrototype); RUNTIME_CLASS(PClass)->TypeTableType = RUNTIME_CLASS(PClass); RUNTIME_CLASS(PStatePointer)->TypeTableType = RUNTIME_CLASS(PStatePointer); - RUNTIME_CLASS(PFixed)->TypeTableType = RUNTIME_CLASS(PFixed); - RUNTIME_CLASS(PAngle)->TypeTableType = RUNTIME_CLASS(PAngle); - + // Create types and add them type the type table. TypeTable.AddType(TypeError = new PErrorType); TypeTable.AddType(TypeVoid = new PVoidType); @@ -683,8 +679,6 @@ void PType::StaticInit() TypeTable.AddType(TypeSound = new PSound); TypeTable.AddType(TypeColor = new PColor); TypeTable.AddType(TypeState = new PStatePointer); - TypeTable.AddType(TypeFixed = new PFixed); - TypeTable.AddType(TypeAngle = new PAngle); GlobalSymbols.AddSymbol(new PSymbolType(NAME_sByte, TypeSInt8)); GlobalSymbols.AddSymbol(new PSymbolType(NAME_Byte, TypeUInt8)); @@ -702,8 +696,6 @@ void PType::StaticInit() GlobalSymbols.AddSymbol(new PSymbolType(NAME_Sound, TypeSound)); GlobalSymbols.AddSymbol(new PSymbolType(NAME_Color, TypeColor)); GlobalSymbols.AddSymbol(new PSymbolType(NAME_State, TypeState)); - GlobalSymbols.AddSymbol(new PSymbolType(NAME_Fixed, TypeFixed)); - GlobalSymbols.AddSymbol(new PSymbolType(NAME_Angle, TypeAngle)); } @@ -1694,242 +1686,6 @@ PColor::PColor() assert(sizeof(PalEntry) == __alignof(PalEntry)); } -/* PFixed *****************************************************************/ - -IMPLEMENT_CLASS(PFixed) - -//========================================================================== -// -// PFixed Default Constructor -// -//========================================================================== - -PFixed::PFixed() -: PFloat(sizeof(fixed_t)) -{ -} - -//========================================================================== -// -// PFixed :: WriteValue -// -//========================================================================== - -void PFixed::WriteValue(FArchive &ar, const void *addr) const -{ - ar.WriteByte(VAL_Fixed); - ar << *(fixed_t *)addr; -} - -//========================================================================== -// -// PFixed :: ReadValue -// -//========================================================================== - -bool PFixed::ReadValue(FArchive &ar, void *addr) const -{ - BYTE tag; - ar << tag; - if (tag == VAL_Fixed) - { - ar << *(fixed_t *)addr; - return true; - } - else - { - double val; - if (ReadValueDbl(ar, &val, tag)) - { - *(fixed_t *)addr = FLOAT2FIXED(val); - return true; - } - return false; - } -} - -//========================================================================== -// -// PFixed :: SetValue -// -//========================================================================== - -void PFixed::SetValue(void *addr, int val) -{ - assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address"); - *(fixed_t *)addr = val << FRACBITS; -} - -void PFixed::SetValue(void *addr, double val) -{ - assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address"); - *(fixed_t *)addr = FLOAT2FIXED(val); -} - -//========================================================================== -// -// PFixed :: GetValueInt -// -//========================================================================== - -int PFixed::GetValueInt(void *addr) const -{ - assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address"); - return *(fixed_t *)addr >> FRACBITS; -} - -//========================================================================== -// -// PFixed :: GetValueFloat -// -//========================================================================== - -double PFixed::GetValueFloat(void *addr) const -{ - assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address"); - return FIXED2DBL(*(fixed_t *)addr); -} - -//========================================================================== -// -// PFixed :: GetStoreOp -// -//========================================================================== - -int PFixed::GetStoreOp() const -{ - return OP_SX; -} - -//========================================================================== -// -// PFixed :: GetLoadOp -// -//========================================================================== - -int PFixed::GetLoadOp() const -{ - return OP_LX; -} - -/* PAngle *****************************************************************/ - -IMPLEMENT_CLASS(PAngle) - -//========================================================================== -// -// PAngle Default Constructor -// -//========================================================================== - -PAngle::PAngle() -: PFloat(sizeof(angle_t)) -{ -} - -//========================================================================== -// -// PAngle :: WriteValue -// -//========================================================================== - -void PAngle::WriteValue(FArchive &ar, const void *addr) const -{ - ar.WriteByte(VAL_BAM); - ar.WriteInt32(*(angle_t *)addr); -} - -//========================================================================== -// -// PAngle :: ReadValue -// -//========================================================================== - -bool PAngle::ReadValue(FArchive &ar, void *addr) const -{ - BYTE tag; - ar << tag; - if (tag == VAL_BAM) - { - ar << *(angle_t *)addr; - return true; - } - else - { - double val; - if (ReadValueDbl(ar, &val, tag)) - { - *(angle_t *)addr = FLOAT2ANGLE(val); - return true; - } - return false; - } -} - -//========================================================================== -// -// PAngle :: SetValue -// -//========================================================================== - -void PAngle::SetValue(void *addr, int val) -{ - assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address"); - *(angle_t *)addr = Scale(val, ANGLE_90, 90); -} - -void PAngle::SetValue(void *addr, double val) -{ - assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address"); - *(angle_t *)addr = (angle_t)(val * ANGLE_90 / 90); -} - -//========================================================================== -// -// PAngle :: GetValueInt -// -//========================================================================== - -int PAngle::GetValueInt(void *addr) const -{ - assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address"); - return *(angle_t *)addr / ANGLE_1; -} - -//========================================================================== -// -// PAngle :: GetValueFloat -// -//========================================================================== - -double PAngle::GetValueFloat(void *addr) const -{ - assert(((intptr_t)addr & (Align - 1)) == 0 && "unaligned address"); - return (double)(*(angle_t *)addr) / ANGLE_1; -} - -//========================================================================== -// -// PAngle :: GetStoreOp -// -//========================================================================== - -int PAngle::GetStoreOp() const -{ - return OP_SANG; -} - -//========================================================================== -// -// PAngle :: GetLoadOp -// -//========================================================================== - -int PAngle::GetLoadOp() const -{ - return OP_LANG; -} - /* PStatePointer **********************************************************/ IMPLEMENT_CLASS(PStatePointer) @@ -3537,8 +3293,8 @@ PField *PClass::AddField(FName name, PType *type, DWORD flags) PField *field = Super::AddField(name, type, flags); if (field != NULL) { - Defaults = (BYTE *)M_Realloc(Defaults, Size); - memset(Defaults + oldsize, 0, Size - oldsize); + Defaults = (BYTE *)M_Realloc(Defaults, Size); + memset(Defaults + oldsize, 0, Size - oldsize); // If this is a native class, then we must not initialize and // destroy any of its members. We do, however, initialize the // default instance since it's not a normal instance of the class. diff --git a/src/dobjtype.h b/src/dobjtype.h index fe04bc634..3c7481751 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -456,43 +456,6 @@ public: PColor(); }; -// Variations of floating point types --------------------------------------- -// These get converted to floats when they're loaded from memory. - -class PFixed : public PFloat -{ - DECLARE_CLASS(PFixed, PFloat); -public: - PFixed(); - - void WriteValue(FArchive &ar, const void *addr) const override; - bool ReadValue(FArchive &ar, void *addr) const override; - - virtual void SetValue(void *addr, int val); - virtual void SetValue(void *addr, double val); - virtual int GetValueInt(void *addr) const; - virtual double GetValueFloat(void *addr) const; - virtual int GetStoreOp() const; - virtual int GetLoadOp() const; -}; - -class PAngle : public PFloat -{ - DECLARE_CLASS(PAngle, PFloat); -public: - PAngle(); - - void WriteValue(FArchive &ar, const void *addr) const override; - bool ReadValue(FArchive &ar, void *addr) const override; - - virtual void SetValue(void *addr, int val); - virtual void SetValue(void *addr, double val); - virtual int GetValueInt(void *addr) const; - virtual double GetValueFloat(void *addr) const; - virtual int GetStoreOp() const; - virtual int GetLoadOp() const; -}; - // Pointers ----------------------------------------------------------------- class PStatePointer : public PBasicType @@ -878,8 +841,6 @@ extern PName *TypeName; extern PSound *TypeSound; extern PColor *TypeColor; extern PStatePointer *TypeState; -extern PFixed *TypeFixed; -extern PAngle *TypeAngle; // A constant value --------------------------------------------------------- diff --git a/src/doomdata.h b/src/doomdata.h index 4d8254757..4e4976800 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -26,6 +26,7 @@ // The most basic types we use, portability. #include "doomtype.h" +#include "vectors.h" // Some global defines, that configure the game. #include "doomdef.h" @@ -345,9 +346,7 @@ struct FDoomEdEntry; struct FMapThing { int thingid; - fixed_t x; - fixed_t y; - fixed_t z; + DVector3 pos; short angle; WORD SkillFilter; WORD ClassFilter; @@ -357,11 +356,10 @@ struct FMapThing int special; int args[5]; int Conversation; - fixed_t gravity; - fixed_t alpha; + double Gravity; + double Alpha; DWORD fillcolor; - fixed_t scaleX; - fixed_t scaleY; + DVector2 Scale; int health; int score; short pitch; @@ -428,12 +426,12 @@ enum EMapThingFlags // A simplified mapthing for player starts struct FPlayerStart { - fixed_t x, y, z; + DVector3 pos; short angle, type; FPlayerStart() { } FPlayerStart(const FMapThing *mthing, int pnum) - : x(mthing->x), y(mthing->y), z(mthing->z), + : pos(mthing->pos), angle(mthing->angle), type(pnum) { } diff --git a/src/doomdef.h b/src/doomdef.h index 627efe391..56b69fe7c 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -340,7 +340,7 @@ enum : unsigned int COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW. COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom. COMPATF2_SOUNDCUTOFF = 1 << 2, // Cut off sounds when an actor vanishes instead of making it owner-less - COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSide() + COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSideCompat() COMPATF2_MULTIEXIT = 1 << 4, // Level exit can be triggered multiple times (required by Daedalus's travel tubes, thanks to a faulty script) }; @@ -365,11 +365,11 @@ enum // linedefs. More friction can create mud, sludge, // magnetized floors, etc. Less friction can create ice. -#define MORE_FRICTION_VELOCITY 15000 // mud factor based on velocity -#define ORIG_FRICTION 0xE800 // original value -#define ORIG_FRICTION_FACTOR 2048 // original value -#define FRICTION_LOW 0xf900 -#define FRICTION_FLY 0xeb00 +#define MORE_FRICTION_VELOCITY (15000/65536.) // mud factor based on velocity +#define ORIG_FRICTION (0xE800/65536.) // original value +#define ORIG_FRICTION_FACTOR (2048/65536.) // original value +#define FRICTION_LOW (0xf900/65536.) +#define FRICTION_FLY (0xeb00/65536.) #define BLINKTHRESHOLD (4*32) diff --git a/src/doomstat.h b/src/doomstat.h index e762b07dc..b7b922aca 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -233,7 +233,7 @@ struct DehInfo int KFAAC; char PlayerSprite[5]; BYTE ExplosionStyle; - fixed_t ExplosionAlpha; + double ExplosionAlpha; int NoAutofreeze; int BFGCells; }; diff --git a/src/doomtype.h b/src/doomtype.h index db4bc7e5d..fa84824f2 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -44,7 +44,6 @@ #include "tarray.h" #include "name.h" #include "zstring.h" -#include "vectors.h" class PClassActor; typedef TMap FClassMap; @@ -252,10 +251,13 @@ enum ESSType SS_BGRA }; -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h +// always use our own definition for consistency. +#ifdef M_PI +#undef M_PI #endif +const double M_PI = 3.14159265358979323846; // matches value in gcc v2 math.h + template char ( &_ArraySizeHelper( T (&array)[N] ))[N]; diff --git a/src/dsectoreffect.cpp b/src/dsectoreffect.cpp index 8e5ced065..50909764f 100644 --- a/src/dsectoreffect.cpp +++ b/src/dsectoreffect.cpp @@ -133,7 +133,7 @@ DMovingCeiling::DMovingCeiling (sector_t *sector) interpolation = sector->SetInterpolation(sector_t::CeilingMove, true); } -bool DMover::MoveAttached(int crush, fixed_t move, int floorOrCeiling, bool resetfailed) +bool DMover::MoveAttached(int crush, double move, int floorOrCeiling, bool resetfailed) { if (!P_Scroll3dMidtex(m_Sector, crush, move, !!floorOrCeiling) && resetfailed) { @@ -155,20 +155,20 @@ bool DMover::MoveAttached(int crush, fixed_t move, int floorOrCeiling, bool rese // (Use -1 to prevent it from trying to crush) // dest is the desired d value for the plane // -DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, +DMover::EResult DMover::MovePlane (double speed, double dest, int crush, int floorOrCeiling, int direction, bool hexencrush) { bool flag; - fixed_t lastpos; - fixed_t movedest; - fixed_t move; - //fixed_t destheight; //jff 02/04/98 used to keep floors/ceilings + double lastpos; + double movedest; + double move; + //double destheight; //jff 02/04/98 used to keep floors/ceilings // from moving thru each other switch (floorOrCeiling) { case 0: // FLOOR - lastpos = m_Sector->floorplane.d; + lastpos = m_Sector->floorplane.fD(); switch (direction) { case -1: @@ -180,11 +180,11 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, if (!MoveAttached(crush, move, 0, true)) return crushed; - m_Sector->floorplane.d = dest; + m_Sector->floorplane.setD(dest); flag = P_ChangeSector (m_Sector, crush, move, 0, false); if (flag) { - m_Sector->floorplane.d = lastpos; + m_Sector->floorplane.setD(lastpos); P_ChangeSector (m_Sector, crush, -move, 0, true); MoveAttached(crush, -move, 0, false); } @@ -199,12 +199,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, { if (!MoveAttached(crush, -speed, 0, true)) return crushed; - m_Sector->floorplane.d = movedest; + m_Sector->floorplane.setD(movedest); flag = P_ChangeSector (m_Sector, crush, -speed, 0, false); if (flag) { - m_Sector->floorplane.d = lastpos; + m_Sector->floorplane.setD(lastpos); P_ChangeSector (m_Sector, crush, speed, 0, true); MoveAttached(crush, speed, 0, false); return crushed; @@ -222,11 +222,10 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, // jff 02/04/98 keep floor from moving thru ceilings // [RH] not so easy with arbitrary planes //destheight = (dest < m_Sector->ceilingheight) ? dest : m_Sector->ceilingheight; - if ((m_Sector->ceilingplane.a | m_Sector->ceilingplane.b | - m_Sector->floorplane.a | m_Sector->floorplane.b) == 0 && - (!(i_compatflags2 & COMPATF2_FLOORMOVE) && -dest > m_Sector->ceilingplane.d)) + if (!m_Sector->ceilingplane.isSlope() && !m_Sector->floorplane.isSlope() && + (!(i_compatflags2 & COMPATF2_FLOORMOVE) && -dest > m_Sector->ceilingplane.fD())) { - dest = -m_Sector->ceilingplane.d; + dest = -m_Sector->ceilingplane.fD(); } movedest = m_Sector->floorplane.GetChangedHeight (speed); @@ -237,12 +236,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, if (!MoveAttached(crush, move, 0, true)) return crushed; - m_Sector->floorplane.d = dest; + m_Sector->floorplane.setD(dest); flag = P_ChangeSector (m_Sector, crush, move, 0, false); if (flag) { - m_Sector->floorplane.d = lastpos; + m_Sector->floorplane.setD(lastpos); P_ChangeSector (m_Sector, crush, -move, 0, true); MoveAttached(crush, -move, 0, false); } @@ -257,7 +256,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, { if (!MoveAttached(crush, speed, 0, true)) return crushed; - m_Sector->floorplane.d = movedest; + m_Sector->floorplane.setD(movedest); // COULD GET CRUSHED flag = P_ChangeSector (m_Sector, crush, speed, 0, false); @@ -269,7 +268,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, m_Sector->AdjustFloorClip (); return crushed; } - m_Sector->floorplane.d = lastpos; + m_Sector->floorplane.setD(lastpos); P_ChangeSector (m_Sector, crush, -speed, 0, true); MoveAttached(crush, -speed, 0, false); return crushed; @@ -283,7 +282,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, case 1: // CEILING - lastpos = m_Sector->ceilingplane.d; + lastpos = m_Sector->ceilingplane.fD(); switch (direction) { case -1: @@ -291,11 +290,10 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, // jff 02/04/98 keep ceiling from moving thru floors // [RH] not so easy with arbitrary planes //destheight = (dest > m_Sector->floorheight) ? dest : m_Sector->floorheight; - if ((m_Sector->ceilingplane.a | m_Sector->ceilingplane.b | - m_Sector->floorplane.a | m_Sector->floorplane.b) == 0 && - (!(i_compatflags2 & COMPATF2_FLOORMOVE) && dest < -m_Sector->floorplane.d)) + if (!m_Sector->ceilingplane.isSlope() && !m_Sector->floorplane.isSlope() && + (!(i_compatflags2 & COMPATF2_FLOORMOVE) && dest < -m_Sector->floorplane.fD())) { - dest = -m_Sector->floorplane.d; + dest = -m_Sector->floorplane.fD(); } movedest = m_Sector->ceilingplane.GetChangedHeight (-speed); if (movedest <= dest) @@ -304,12 +302,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, if (!MoveAttached(crush, move, 1, true)) return crushed; - m_Sector->ceilingplane.d = dest; + m_Sector->ceilingplane.setD(dest); flag = P_ChangeSector (m_Sector, crush, move, 1, false); if (flag) { - m_Sector->ceilingplane.d = lastpos; + m_Sector->ceilingplane.setD(lastpos); P_ChangeSector (m_Sector, crush, -move, 1, true); MoveAttached(crush, -move, 1, false); } @@ -323,7 +321,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, { if (!MoveAttached(crush, -speed, 1, true)) return crushed; - m_Sector->ceilingplane.d = movedest; + m_Sector->ceilingplane.setD(movedest); // COULD GET CRUSHED flag = P_ChangeSector (m_Sector, crush, -speed, 1, false); @@ -334,7 +332,7 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, m_Sector->ChangePlaneTexZ(sector_t::ceiling, m_Sector->ceilingplane.HeightDiff (lastpos)); return crushed; } - m_Sector->ceilingplane.d = lastpos; + m_Sector->ceilingplane.setD(lastpos); P_ChangeSector (m_Sector, crush, speed, 1, true); MoveAttached(crush, speed, 1, false); return crushed; @@ -352,12 +350,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, if (!MoveAttached(crush, move, 1, true)) return crushed; - m_Sector->ceilingplane.d = dest; + m_Sector->ceilingplane.setD(dest); flag = P_ChangeSector (m_Sector, crush, move, 1, false); if (flag) { - m_Sector->ceilingplane.d = lastpos; + m_Sector->ceilingplane.setD(lastpos); P_ChangeSector (m_Sector, crush, move, 1, true); MoveAttached(crush, move, 1, false); } @@ -371,12 +369,12 @@ DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, int crush, { if (!MoveAttached(crush, speed, 1, true)) return crushed; - m_Sector->ceilingplane.d = movedest; + m_Sector->ceilingplane.setD(movedest); flag = P_ChangeSector (m_Sector, crush, speed, 1, false); if (flag) { - m_Sector->ceilingplane.d = lastpos; + m_Sector->ceilingplane.setD(lastpos); P_ChangeSector (m_Sector, crush, -speed, 1, true); MoveAttached(crush, -speed, 1, false); return crushed; diff --git a/src/dsectoreffect.h b/src/dsectoreffect.h index 9aa3ccb50..bbafd898d 100644 --- a/src/dsectoreffect.h +++ b/src/dsectoreffect.h @@ -30,26 +30,26 @@ protected: enum EResult { ok, crushed, pastdest }; TObjPtr interpolation; private: - bool MoveAttached(int crush, fixed_t move, int floorOrCeiling, bool resetfailed); - EResult MovePlane (fixed_t speed, fixed_t dest, int crush, int floorOrCeiling, int direction, bool hexencrush); + bool MoveAttached(int crush, double move, int floorOrCeiling, bool resetfailed); + EResult MovePlane (double speed, double dest, int crush, int floorOrCeiling, int direction, bool hexencrush); protected: DMover (); void Serialize (FArchive &arc); void Destroy(); void StopInterpolation(bool force = false); - inline EResult MoveFloor (fixed_t speed, fixed_t dest, int crush, int direction, bool hexencrush) + inline EResult MoveFloor (double speed, double dest, int crush, int direction, bool hexencrush) { return MovePlane (speed, dest, crush, 0, direction, hexencrush); } - inline EResult MoveFloor (fixed_t speed, fixed_t dest, int direction) + inline EResult MoveFloor (double speed, double dest, int direction) { return MovePlane (speed, dest, -1, 0, direction, false); } - inline EResult MoveCeiling (fixed_t speed, fixed_t dest, int crush, int direction, bool hexencrush) + inline EResult MoveCeiling (double speed, double dest, int crush, int direction, bool hexencrush) { return MovePlane (speed, dest, crush, 1, direction, hexencrush); } - inline EResult MoveCeiling (fixed_t speed, fixed_t dest, int direction) + inline EResult MoveCeiling (double speed, double dest, int direction) { return MovePlane (speed, dest, -1, 1, direction, false); } diff --git a/src/edata.cpp b/src/edata.cpp index 82260ca80..034c45086 100644 --- a/src/edata.cpp +++ b/src/edata.cpp @@ -92,7 +92,7 @@ struct EDMapthing int recordnum; int tid; int type; - fixed_t height; + double height; int args[5]; WORD skillfilter; DWORD flags; @@ -105,7 +105,7 @@ struct EDLinedef int tag; int id; int args[5]; - fixed_t alpha; + double alpha; DWORD flags; DWORD activation; }; @@ -140,10 +140,10 @@ struct EDSector bool colorSet; // colormaptop//bottom cannot be used because ZDoom has no corresponding properties. - - FTransform planexform[2]; + double xoffs[2], yoffs[2]; + DAngle angle[2]; DWORD portalflags[2]; - fixed_t overlayalpha[2]; + double Overlayalpha[2]; }; static FString EDMap; @@ -158,7 +158,7 @@ static void parseLinedef(FScanner &sc) bool argsset = false; memset(&ld, 0, sizeof(ld)); - ld.alpha = FRACUNIT; + ld.alpha = 1.; sc.MustGetStringName("{"); while (!sc.CheckString("}")) @@ -216,7 +216,7 @@ static void parseLinedef(FScanner &sc) { sc.CheckString("="); sc.MustGetFloat(); - ld.alpha = FLOAT2FIXED(sc.Float); + ld.alpha = sc.Float; } else if (sc.Compare("extflags")) { @@ -275,7 +275,7 @@ static void parseSector(FScanner &sc) EDSector sec; memset(&sec, 0, sizeof(sec)); - sec.overlayalpha[sector_t::floor] = sec.overlayalpha[sector_t::ceiling] = FRACUNIT; + sec.Overlayalpha[sector_t::floor] = sec.Overlayalpha[sector_t::ceiling] = 1.; sec.floorterrain = sec.ceilingterrain = -1; sc.MustGetStringName("{"); @@ -398,19 +398,19 @@ static void parseSector(FScanner &sc) { sc.CheckString("="); sc.MustGetFloat(); - sec.planexform[sector_t::floor].angle = FLOAT2ANGLE(sc.Float); + sec.angle[sector_t::floor] = sc.Float; } else if (sc.Compare("flooroffsetx")) { sc.CheckString("="); sc.MustGetFloat(); - sec.planexform[sector_t::floor].xoffs = FLOAT2FIXED(sc.Float); + sec.xoffs[sector_t::floor] = sc.Float; } else if (sc.Compare("flooroffsety")) { sc.CheckString("="); sc.MustGetFloat(); - sec.planexform[sector_t::floor].yoffs = FLOAT2FIXED(sc.Float); + sec.yoffs[sector_t::floor] = sc.Float; } else if (sc.Compare("ceilingterrain")) { @@ -422,19 +422,19 @@ static void parseSector(FScanner &sc) { sc.CheckString("="); sc.MustGetFloat(); - sec.planexform[sector_t::ceiling].angle = FLOAT2ANGLE(sc.Float); + sec.angle[sector_t::ceiling] = sc.Float; } else if (sc.Compare("ceilingoffsetx")) { sc.CheckString("="); sc.MustGetFloat(); - sec.planexform[sector_t::ceiling].xoffs = FLOAT2FIXED(sc.Float); + sec.xoffs[sector_t::ceiling] = sc.Float; } else if (sc.Compare("ceilingoffsety")) { sc.CheckString("="); sc.MustGetFloat(); - sec.planexform[sector_t::ceiling].yoffs = FLOAT2FIXED(sc.Float); + sec.yoffs[sector_t::ceiling] = sc.Float; } else if (sc.Compare("colormaptop") || sc.Compare("colormapbottom")) { @@ -464,14 +464,14 @@ static void parseSector(FScanner &sc) sc.MustGetNumber(); if (sc.CheckString("%")) sc.Float = sc.Number / 100.f; else sc.Float = sc.Number / 255.f; - sec.overlayalpha[sector_t::floor] = FLOAT2FIXED(sc.Float); + sec.Overlayalpha[sector_t::floor] = sc.Float; } else if (sc.Compare("ceiling")) { sc.MustGetFloat(); if (sc.CheckString("%")) sc.Float = sc.Number / 100.f; else sc.Float = sc.Number / 255.f; - sec.overlayalpha[sector_t::floor] = FLOAT2FIXED(sc.Float); + sec.Overlayalpha[sector_t::floor] = sc.Float; } } else if (sc.Compare("portalflags")) @@ -585,7 +585,7 @@ static void parseMapthing(FScanner &sc) { sc.CheckString("="); sc.MustGetFloat(); // no idea if Eternity allows fractional numbers. Better be safe and do it anyway. - mt.height = FLOAT2FIXED(sc.Float); + mt.height = sc.Float; } else if (sc.Compare("options")) { @@ -682,7 +682,7 @@ void ProcessEDMapthing(FMapThing *mt, int recordnum) mt->thingid = emt->tid; mt->EdNum = emt->type; mt->info = DoomEdMap.CheckKey(mt->EdNum); - mt->z = emt->height; + mt->pos.Z = emt->height; memcpy(mt->args, emt->args, sizeof(mt->args)); mt->SkillFilter = emt->skillfilter; mt->flags = emt->flags; @@ -703,7 +703,7 @@ void ProcessEDLinedef(line_t *ld, int recordnum) ld->special = eld->special; ld->activation = eld->activation; ld->flags = (ld->flags&~fmask) | eld->flags; - ld->Alpha = eld->alpha; + ld->setAlpha(eld->alpha); memcpy(ld->args, eld->args, sizeof(ld->args)); tagManager.AddLineID(int(ld - lines), eld->tag); } @@ -742,10 +742,10 @@ void ProcessEDSector(sector_t *sec, int recordnum) const DWORD pflagmask = PLANEF_DISABLED | PLANEF_NORENDER | PLANEF_NOPASS | PLANEF_BLOCKSOUND | PLANEF_ADDITIVE; for (int i = 0; i < 2; i++) { - sec->planes[i].xform.xoffs = esec->planexform[i].xoffs; - sec->planes[i].xform.yoffs = esec->planexform[i].yoffs; - sec->planes[i].xform.angle = esec->planexform[i].angle; - sec->planes[i].alpha = esec->overlayalpha[i]; + sec->SetXOffset(i, esec->xoffs[i]); + sec->SetYOffset(i, esec->yoffs[i]); + sec->SetAngle(i, esec->angle[i]); + sec->SetAlpha(i, esec->Overlayalpha[i]); sec->planes[i].Flags = (sec->planes[i].Flags & ~pflagmask) | esec->portalflags[i]; } } diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index b81aecb38..a3ceb8d50 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -269,12 +269,13 @@ bool wipe_doBurn (int ticks) } // Draw the screen - fixed_t xstep, ystep, firex, firey; + int xstep, ystep, firex, firey; int x, y; BYTE *to, *fromold, *fromnew; + const int SHIFT = 16; - xstep = (FIREWIDTH * FRACUNIT) / SCREENWIDTH; - ystep = (FIREHEIGHT * FRACUNIT) / SCREENHEIGHT; + xstep = (FIREWIDTH << SHIFT) / SCREENWIDTH; + ystep = (FIREHEIGHT << SHIFT) / SCREENHEIGHT; to = screen->GetBuffer(); fromold = (BYTE *)wipe_scr_start; fromnew = (BYTE *)wipe_scr_end; @@ -285,7 +286,7 @@ bool wipe_doBurn (int ticks) { int fglevel; - fglevel = burnarray[(firex>>FRACBITS)+(firey>>FRACBITS)*FIREWIDTH] / 2; + fglevel = burnarray[(firex>>SHIFT)+(firey>>SHIFT)*FIREWIDTH] / 2; if (fglevel >= 63) { to[x] = fromnew[x]; @@ -340,7 +341,7 @@ bool wipe_doFade (int ticks) else { int x, y; - fixed_t bglevel = 64 - fade; + int bglevel = 64 - fade; DWORD *fg2rgb = Col2RGB8[fade]; DWORD *bg2rgb = Col2RGB8[bglevel]; BYTE *fromnew = (BYTE *)wipe_scr_end; diff --git a/src/farchive.cpp b/src/farchive.cpp index 1f805ae8e..1780f862a 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -1562,3 +1562,21 @@ FArchive &operator<< (FArchive &arc, side_t *&side) { return arc.SerializePointer (sides, (BYTE **)&side, sizeof(*sides)); } + +FArchive &operator<<(FArchive &arc, DAngle &ang) +{ + arc << ang.Degrees; + return arc; +} + +FArchive &operator<<(FArchive &arc, DVector3 &vec) +{ + arc << vec.X << vec.Y << vec.Z; + return arc; +} + +FArchive &operator<<(FArchive &arc, DVector2 &vec) +{ + arc << vec.X << vec.Y; + return arc; +} diff --git a/src/farchive.h b/src/farchive.h index 2324c6b2a..4a1715344 100644 --- a/src/farchive.h +++ b/src/farchive.h @@ -331,6 +331,10 @@ FArchive &operator<< (FArchive &arc, line_t *&line); FArchive &operator<< (FArchive &arc, vertex_t *&vert); FArchive &operator<< (FArchive &arc, side_t *&side); +FArchive &operator<<(FArchive &arc, DAngle &ang); +FArchive &operator<<(FArchive &arc, DVector3 &vec); +FArchive &operator<<(FArchive &arc, DVector2 &vec); + template diff --git a/src/files.h b/src/files.h index c417afa09..5889eb6fe 100644 --- a/src/files.h +++ b/src/files.h @@ -46,7 +46,7 @@ public: return *this; } - FileReaderBase &operator>> (fixed_t &v) + FileReaderBase &operator>> (int &v) { Read (&v, 4); v = LittleLong(v); @@ -171,7 +171,7 @@ public: return *this; } - FileReaderZ &operator>> (fixed_t &v) + FileReaderZ &operator>> (int &v) { Read (&v, 4); v = LittleLong(v); @@ -233,7 +233,7 @@ public: return *this; } - FileReaderBZ2 &operator>> (fixed_t &v) + FileReaderBZ2 &operator>> (int &v) { Read (&v, 4); v = LittleLong(v); @@ -297,7 +297,7 @@ public: return *this; } - FileReaderLZMA &operator>> (fixed_t &v) + FileReaderLZMA &operator>> (int &v) { Read (&v, 4); v = LittleLong(v); diff --git a/src/fragglescript/t_cmd.cpp b/src/fragglescript/t_cmd.cpp index 7398558bb..1434870d1 100644 --- a/src/fragglescript/t_cmd.cpp +++ b/src/fragglescript/t_cmd.cpp @@ -165,7 +165,7 @@ void FS_EmulateCmd(char * string) else if (sc.Compare("viewheight")) { sc.MustGetFloat(); - fixed_t playerviewheight = (fixed_t)(sc.Float*FRACUNIT); + double playerviewheight = sc.Float; for(int i=0;iDrawTexture(tex, piclist[i].xpos, piclist[i].ypos, DTA_320x200, true, - DTA_Alpha, (fixed_t)(translucent*basetrans*FRACUNIT), TAG_DONE); + DTA_AlphaF, translucent*basetrans, TAG_DONE); } } diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index bfda35ad4..41f740dda 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -68,13 +68,11 @@ #include "farchive.h" #include "p_setup.h" #include "p_spec.h" +#include "r_utility.h" +#include "math/cmath.h" static FRandom pr_script("FScript"); - -#define AngleToFixed(x) ((((double) x) / ((double) ANG45/45)) * FRACUNIT) -#define FixedToAngle(x) ((((double) x) / FRACUNIT) * ANG45/45) - // functions. FParser::SF_ means Script Function not, well.. heh, me /////////// actually running a function ///////////// @@ -860,43 +858,43 @@ void FParser::SF_Player(void) void FParser::SF_Spawn(void) { - int x, y, z; + DVector3 pos; PClassActor *pclass; - angle_t angle = 0; + DAngle angle = 0.; if (CheckArgs(3)) { if (!(pclass=T_GetMobjType(t_argv[0]))) return; - x = fixedvalue(t_argv[1]); - y = fixedvalue(t_argv[2]); + pos.X = floatvalue(t_argv[1]); + pos.Y = floatvalue(t_argv[2]); if(t_argc >= 5) { - z = fixedvalue(t_argv[4]); + pos.Z = floatvalue(t_argv[4]); // [Graf Zahl] added option of spawning with a relative z coordinate if(t_argc > 5) { - if (intvalue(t_argv[5])) z+=P_PointInSector(x, y)->floorplane.ZatPoint(x,y); + if (intvalue(t_argv[5])) pos.Z += P_PointInSector(pos)->floorplane.ZatPoint(pos); } } else { // Legacy compatibility is more important than correctness. - z = ONFLOORZ;// (GetDefaultByType(PClass)->flags & MF_SPAWNCEILING) ? ONCEILINGZ : ONFLOORZ; + pos.Z = ONFLOORZ;// (GetDefaultByType(PClass)->flags & MF_SPAWNCEILING) ? ONCEILINGZ : ONFLOORZ; } if(t_argc >= 4) { - angle = intvalue(t_argv[3]) * (SQWORD)ANG45 / 45; + angle = floatvalue(t_argv[3]); } t_return.type = svt_mobj; - t_return.value.mobj = Spawn(pclass, x, y, z, ALLOW_REPLACE); + t_return.value.mobj = Spawn(pclass, pos, ALLOW_REPLACE); if (t_return.value.mobj) { - t_return.value.mobj->angle = angle; + t_return.value.mobj->Angles.Yaw = angle; if (!DFraggleThinker::ActiveThinker->nocheckposition) { @@ -981,8 +979,7 @@ void FParser::SF_ObjX(void) mo = Script->trigger; } - t_return.type = svt_fixed; // haleyjd: SoM's fixed-point fix - t_return.value.f = mo ? mo->X() : 0; // null ptr check + t_return.setDouble(mo ? mo->X() : 0.); } //========================================================================== @@ -1004,8 +1001,7 @@ void FParser::SF_ObjY(void) mo = Script->trigger; } - t_return.type = svt_fixed; // haleyjd - t_return.value.f = mo ? mo->Y() : 0; // null ptr check + t_return.setDouble(mo ? mo->Y() : 0.); } //========================================================================== @@ -1027,8 +1023,7 @@ void FParser::SF_ObjZ(void) mo = Script->trigger; } - t_return.type = svt_fixed; // haleyjd - t_return.value.f = mo ? mo->Z() : 0; // null ptr check + t_return.setDouble(mo ? mo->Z() : 0.); } @@ -1051,8 +1046,7 @@ void FParser::SF_ObjAngle(void) mo = Script->trigger; } - t_return.type = svt_fixed; // haleyjd: fixed-point -- SoM again :) - t_return.value.f = mo ? (fixed_t)AngleToFixed(mo->angle) : 0; // null ptr check + t_return.setDouble(mo ? mo->Angles.Yaw.Degrees : 0.); } @@ -1256,10 +1250,9 @@ void FParser::SF_PushThing(void) AActor * mo = actorvalue(t_argv[0]); if(!mo) return; - angle_t angle = (angle_t)FixedToAngle(fixedvalue(t_argv[1])); - fixed_t force = fixedvalue(t_argv[2]); - - P_ThrustMobj(mo, angle, force); + DAngle angle = floatvalue(t_argv[1]); + double force = floatvalue(t_argv[2]); + mo->Thrust(angle, force); } } @@ -1333,11 +1326,10 @@ void FParser::SF_MobjMomx(void) if(t_argc > 1) { if(mo) - mo->vel.x = fixedvalue(t_argv[1]); + mo->Vel.X = floatvalue(t_argv[1]); } - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->vel.x : 0; + t_return.setDouble(mo ? mo->Vel.X : 0.); } } @@ -1356,12 +1348,11 @@ void FParser::SF_MobjMomy(void) mo = actorvalue(t_argv[0]); if(t_argc > 1) { - if(mo) - mo->vel.y = fixedvalue(t_argv[1]); + if(mo) + mo->Vel.Y = floatvalue(t_argv[1]); } - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->vel.y : 0; + t_return.setDouble(mo ? mo->Vel.Y : 0.); } } @@ -1378,14 +1369,13 @@ void FParser::SF_MobjMomz(void) if (CheckArgs(1)) { mo = actorvalue(t_argv[0]); - if(t_argc > 1) + if (t_argc > 1) { - if(mo) - mo->vel.z = fixedvalue(t_argv[1]); + if (mo) + mo->Vel.Z = floatvalue(t_argv[1]); } - - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->vel.z : 0; + + t_return.setDouble(mo ? mo->Vel.Z : 0.); } } @@ -1402,15 +1392,12 @@ void FParser::SF_PointToAngle(void) { if (CheckArgs(4)) { - fixed_t x1 = fixedvalue(t_argv[0]); - fixed_t y1 = fixedvalue(t_argv[1]); - fixed_t x2 = fixedvalue(t_argv[2]); - fixed_t y2 = fixedvalue(t_argv[3]); + double x1 = floatvalue(t_argv[0]); + double y1 = floatvalue(t_argv[1]); + double x2 = floatvalue(t_argv[2]); + double y2 = floatvalue(t_argv[3]); - angle_t angle = R_PointToAngle2(x1, y1, x2, y2); - - t_return.type = svt_fixed; - t_return.value.f = (fixed_t)AngleToFixed(angle); + t_return.setDouble(DVector2(x2 - x1, y2 - y1).Angle().Normalized360().Degrees); } } @@ -1428,9 +1415,7 @@ void FParser::SF_PointToDist(void) // Doing this in floating point is actually faster with modern computers! double x = floatvalue(t_argv[2]) - floatvalue(t_argv[0]); double y = floatvalue(t_argv[3]) - floatvalue(t_argv[1]); - - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(sqrt(x*x+y*y)); + t_return.setDouble(g_sqrt(x*x+y*y)); } } @@ -1447,7 +1432,7 @@ void FParser::SF_PointToDist(void) void FParser::SF_SetCamera(void) { - angle_t angle; + DAngle angle; player_t * player; AActor * newcamera; @@ -1463,21 +1448,16 @@ void FParser::SF_SetCamera(void) return; // nullptr check } - angle = t_argc < 2 ? newcamera->angle : (fixed_t)FixedToAngle(fixedvalue(t_argv[1])); + angle = t_argc < 2 ? newcamera->Angles.Yaw : floatvalue(t_argv[1]); - newcamera->special1=newcamera->angle; - newcamera->special2=newcamera->Z(); - newcamera->SetZ(t_argc < 3 ? (newcamera->Z() + (41 << FRACBITS)) : (intvalue(t_argv[2]) << FRACBITS)); - newcamera->angle = angle; - if(t_argc < 4) newcamera->pitch = 0; - else - { - fixed_t pitch = fixedvalue(t_argv[3]); - if (pitch < -50 * FRACUNIT) pitch = -50 * FRACUNIT; - if (pitch > 50 * FRACUNIT) pitch = 50 * FRACUNIT; - newcamera->pitch = xs_CRoundToUInt((pitch / 65536.0f)*(ANGLE_45 / 45.0f)*(20.0f / 32.0f)); - } + newcamera->specialf1 = newcamera->Angles.Yaw.Degrees; + newcamera->specialf2 = newcamera->Z(); + newcamera->SetZ(t_argc < 3 ? newcamera->Z() + 41 : floatvalue(t_argv[2])); + newcamera->Angles.Yaw = angle; + if (t_argc < 4) newcamera->Angles.Pitch = 0.; + else newcamera->Angles.Pitch = clamp(floatvalue(t_argv[3]), -50., 50.) * (20. / 32.); player->camera=newcamera; + R_ResetViewInterpolation(); } } @@ -1497,8 +1477,8 @@ void FParser::SF_ClearCamera(void) if (cam) { player->camera=player->mo; - cam->angle=cam->special1; - cam->SetZ(cam->special2); + cam->Angles.Yaw = cam->specialf1; + cam->SetZ(cam->specialf2); } } @@ -1557,16 +1537,13 @@ void FParser::SF_StartSectorSound(void) /************* Sector functions ***************/ -//DMover::EResult P_MoveFloor (sector_t * m_Sector, fixed_t speed, fixed_t dest, int crush, int direction, int flags=0); -//DMover::EResult P_MoveCeiling (sector_t * m_Sector, fixed_t speed, fixed_t dest, int crush, int direction, int flags=0); - class DFloorChanger : public DFloor { public: DFloorChanger(sector_t * sec) : DFloor(sec) {} - bool Move(fixed_t speed, fixed_t dest, int crush, int direction) + bool Move(double speed, double dest, int crush, int direction) { bool res = DMover::crushed != MoveFloor(speed, dest, crush, direction, false); Destroy(); @@ -1589,8 +1566,8 @@ void FParser::SF_FloorHeight(void) { int tagnum; int secnum; - fixed_t dest; - int returnval = 1; // haleyjd: SoM's fixes + double dest; + double returnval = 1; // haleyjd: SoM's fixes if (CheckArgs(1)) { @@ -1602,7 +1579,7 @@ void FParser::SF_FloorHeight(void) int crush = (t_argc >= 3) ? intvalue(t_argv[2]) : false; i = -1; - dest = fixedvalue(t_argv[1]); + dest = floatvalue(t_argv[1]); // set all sectors with tag @@ -1613,7 +1590,7 @@ void FParser::SF_FloorHeight(void) DFloorChanger * f = new DFloorChanger(§ors[i]); if (!f->Move( - abs(dest - sectors[i].CenterFloor()), + fabs(dest - sectors[i].CenterFloor()), sectors[i].floorplane.PointToDist (sectors[i].centerspot, dest), crush? 10:-1, (dest > sectors[i].CenterFloor()) ? 1 : -1)) @@ -1630,13 +1607,11 @@ void FParser::SF_FloorHeight(void) script_error("sector not found with tagnum %i\n", tagnum); return; } - returnval = sectors[secnum].CenterFloor() >> FRACBITS; + returnval = sectors[secnum].CenterFloor(); } // return floor height - - t_return.type = svt_int; - t_return.value.i = returnval; + t_return.setDouble(returnval); } } @@ -1648,7 +1623,7 @@ void FParser::SF_FloorHeight(void) class DMoveFloor : public DFloor { public: - DMoveFloor(sector_t * sec,int moveheight,int _m_Direction,int crush,int movespeed) + DMoveFloor(sector_t * sec,double moveheight,int _m_Direction,int crush,double movespeed) : DFloor(sec) { m_Type = floorRaiseByValue; @@ -1658,7 +1633,7 @@ public: m_FloorDestDist = moveheight; // Do not interpolate instant movement floors. - fixed_t movedist = abs(-sec->floorplane.d - moveheight); + double movedist = fabs(-sec->floorplane.fD() - moveheight); if (m_Speed >= movedist) { StopInterpolation(true); @@ -1680,13 +1655,14 @@ void FParser::SF_MoveFloor(void) { int secnum = -1; sector_t *sec; - int tagnum, platspeed = 1, destheight, crush; + int tagnum, crush; + double platspeed = 1, destheight; if (CheckArgs(2)) { tagnum = intvalue(t_argv[0]); - destheight = intvalue(t_argv[1]) * FRACUNIT; - platspeed = t_argc > 2 ? fixedvalue(t_argv[2]) : FRACUNIT; + destheight = intvalue(t_argv[1]); + platspeed = t_argc > 2 ? floatvalue(t_argv[2]) : 1.; crush = (t_argc > 3 ? intvalue(t_argv[3]) : -1); // move all sectors with tag @@ -1698,8 +1674,8 @@ void FParser::SF_MoveFloor(void) // Don't start a second thinker on the same floor if (sec->floordata) continue; - new DMoveFloor(sec,sec->floorplane.PointToDist(sec->centerspot,destheight), - destheight < sec->CenterFloor() ? -1:1,crush,platspeed); + new DMoveFloor(sec, sec->floorplane.PointToDist(sec->centerspot, destheight), + destheight < sec->CenterFloor() ? -1 : 1, crush, platspeed); } } } @@ -1716,7 +1692,7 @@ public: DCeilingChanger(sector_t * sec) : DCeiling(sec) {} - bool Move(fixed_t speed, fixed_t dest, int crush, int direction) + bool Move(double speed, double dest, int crush, int direction) { bool res = DMover::crushed != MoveCeiling(speed, dest, crush, direction, false); Destroy(); @@ -1736,10 +1712,10 @@ public: // ceiling height of sector void FParser::SF_CeilingHeight(void) { - fixed_t dest; + double dest; int secnum; int tagnum; - int returnval = 1; + double returnval = 1; if (CheckArgs(1)) { @@ -1751,7 +1727,7 @@ void FParser::SF_CeilingHeight(void) int crush = (t_argc >= 3) ? intvalue(t_argv[2]) : false; i = -1; - dest = fixedvalue(t_argv[1]); + dest = floatvalue(t_argv[1]); // set all sectors with tag FSSectorTagIterator itr(tagnum); @@ -1761,7 +1737,7 @@ void FParser::SF_CeilingHeight(void) DCeilingChanger * c = new DCeilingChanger(§ors[i]); if (!c->Move( - abs(dest - sectors[i].CenterCeiling()), + fabs(dest - sectors[i].CenterCeiling()), sectors[i].ceilingplane.PointToDist (sectors[i].centerspot, dest), crush? 10:-1, (dest > sectors[i].CenterCeiling()) ? 1 : -1)) @@ -1778,12 +1754,11 @@ void FParser::SF_CeilingHeight(void) script_error("sector not found with tagnum %i\n", tagnum); return; } - returnval = sectors[secnum].CenterCeiling() >> FRACBITS; + returnval = sectors[secnum].CenterCeiling(); } // return ceiling height - t_return.type = svt_int; - t_return.value.i = returnval; + t_return.setDouble(returnval); } } @@ -1798,7 +1773,7 @@ class DMoveCeiling : public DCeiling { public: - DMoveCeiling(sector_t * sec,int tag,fixed_t destheight,fixed_t speed,int silent,int crush) + DMoveCeiling(sector_t * sec,int tag,double destheight,double speed,int silent,int crush) : DCeiling(sec) { m_Crush = crush; @@ -1807,10 +1782,10 @@ public: m_Type = DCeiling::ceilLowerByValue; // doesn't really matter as long as it's no special value m_Tag=tag; m_TopHeight=m_BottomHeight=sec->ceilingplane.PointToDist(sec->centerspot,destheight); - m_Direction=destheight>sec->GetPlaneTexZ(sector_t::ceiling)? 1:-1; + m_Direction=destheight>sec->GetPlaneTexZF(sector_t::ceiling)? 1:-1; // Do not interpolate instant movement ceilings. - fixed_t movedist = abs(sec->ceilingplane.d - m_BottomHeight); + double movedist = fabs(sec->ceilingplane.fD() - m_BottomHeight); if (m_Speed >= movedist) { StopInterpolation (true); @@ -1831,15 +1806,16 @@ void FParser::SF_MoveCeiling(void) { int secnum = -1; sector_t *sec; - int tagnum, platspeed = 1, destheight; + int tagnum; + double platspeed = 1, destheight; int crush; int silent; if (CheckArgs(2)) { tagnum = intvalue(t_argv[0]); - destheight = intvalue(t_argv[1]) * FRACUNIT; - platspeed = /*FLOORSPEED **/ (t_argc > 2 ? fixedvalue(t_argv[2]) : FRACUNIT); + destheight = intvalue(t_argv[1]); + platspeed = /*FLOORSPEED **/ (t_argc > 2 ? floatvalue(t_argv[2]) : 1); crush=t_argc>3 ? intvalue(t_argv[3]):-1; silent=t_argc>4 ? intvalue(t_argv[4]):1; @@ -2190,7 +2166,7 @@ void FParser::SF_OpenDoor(void) if(t_argc > 2) speed = intvalue(t_argv[2]); else speed = 1; // 1= normal speed - EV_DoDoor(wait_time? DDoor::doorRaise:DDoor::doorOpen,NULL,NULL,sectag,2*FRACUNIT*clamp(speed,1,127),wait_time,0,0); + EV_DoDoor(wait_time ? DDoor::doorRaise : DDoor::doorOpen, NULL, NULL, sectag, 2. * clamp(speed, 1, 127), wait_time, 0, 0); } } @@ -2215,7 +2191,7 @@ void FParser::SF_CloseDoor(void) if(t_argc > 1) speed = intvalue(t_argv[1]); else speed = 1; // 1= normal speed - EV_DoDoor(DDoor::doorClose,NULL,NULL,sectag,2*FRACUNIT*clamp(speed,1,127),0,0,0); + EV_DoDoor(DDoor::doorClose, NULL, NULL, sectag, 2.*clamp(speed, 1, 127), 0, 0, 0); } } @@ -2429,12 +2405,10 @@ void FParser::SF_SetLineTexture(void) void FParser::SF_Max(void) { - fixed_t n1, n2; - if (CheckArgs(2)) { - n1 = fixedvalue(t_argv[0]); - n2 = fixedvalue(t_argv[1]); + auto n1 = fixedvalue(t_argv[0]); + auto n2 = fixedvalue(t_argv[1]); t_return.type = svt_fixed; t_return.value.f = (n1 > n2) ? n1 : n2; @@ -2450,12 +2424,10 @@ void FParser::SF_Max(void) void FParser::SF_Min(void) { - fixed_t n1, n2; - if (CheckArgs(1)) { - n1 = fixedvalue(t_argv[0]); - n2 = fixedvalue(t_argv[1]); + auto n1 = fixedvalue(t_argv[0]); + auto n2 = fixedvalue(t_argv[1]); t_return.type = svt_fixed; t_return.value.f = (n1 < n2) ? n1 : n2; @@ -2471,11 +2443,10 @@ void FParser::SF_Min(void) void FParser::SF_Abs(void) { - fixed_t n1; if (CheckArgs(1)) { - n1 = fixedvalue(t_argv[0]); + auto n1 = fixedvalue(t_argv[0]); t_return.type = svt_fixed; t_return.value.f = (n1 < 0) ? -n1 : n1; @@ -2587,7 +2558,7 @@ static void FS_GiveInventory (AActor *actor, const char * type, int amount) AWeapon *savedPendingWeap = actor->player != NULL? actor->player->PendingWeapon : NULL; bool hadweap = actor->player != NULL ? actor->player->ReadyWeapon != NULL : true; - AInventory *item = static_cast(Spawn (info, 0,0,0, NO_REPLACE)); + AInventory *item = static_cast(Spawn (info)); // This shouldn't count for the item statistics! item->ClearCounters(); @@ -2795,7 +2766,7 @@ void FParser::SF_MaxPlayerAmmo() if(amount < 0) amount = 0; if (!iammo) { - iammo = static_cast(Spawn (ammotype, 0, 0, 0, NO_REPLACE)); + iammo = static_cast(Spawn (ammotype)); iammo->Amount = 0; iammo->AttachToOwner (players[playernum].mo); } @@ -3067,166 +3038,57 @@ void FParser::SF_SetWeapon() // // movecamera(camera, targetobj, targetheight, movespeed, targetangle, anglespeed) // +// This has been completely rewritten in a sane fashion, using actual vector math. +// //========================================================================== void FParser::SF_MoveCamera(void) { - fixed_t x, y, z; - fixed_t zdist, xydist, movespeed; - fixed_t xstep, ystep, zstep, targetheight; - angle_t anglespeed, anglestep, angledist, targetangle, - mobjangle, bigangle, smallangle; - - // I have to use floats for the math where angles are divided - // by fixed values. - double fangledist, fanglestep, fmovestep; - int angledir; - AActor* target; - int moved; - int quad1, quad2; - AActor * cam; - - angledir = moved = 0; - if (CheckArgs(6)) { - cam = actorvalue(t_argv[0]); - - target = actorvalue(t_argv[1]); - if(!cam || !target) + AActor *cam = actorvalue(t_argv[0]); + AActor *target = actorvalue(t_argv[1]); + if(!cam || !target) { script_error("invalid target for camera\n"); return; } - - targetheight = fixedvalue(t_argv[2]); - movespeed = fixedvalue(t_argv[3]); - targetangle = (angle_t)FixedToAngle(fixedvalue(t_argv[4])); - anglespeed = (angle_t)FixedToAngle(fixedvalue(t_argv[5])); - - // figure out how big one step will be - fixedvec2 dist = cam->Vec2To(target); - zdist = targetheight - cam->Z(); - - // Angle checking... - // 90 - // Q1|Q0 - //180--+--0 - // Q2|Q3 - // 270 - quad1 = targetangle / ANG90; - quad2 = cam->angle / ANG90; - bigangle = targetangle > cam->angle ? targetangle : cam->angle; - smallangle = targetangle < cam->angle ? targetangle : cam->angle; - if((quad1 > quad2 && quad1 - 1 == quad2) || (quad2 > quad1 && quad2 - 1 == quad1) || - quad1 == quad2) + + double targetheight = floatvalue(t_argv[2]); + DVector3 campos = cam->Pos(); + DVector3 targpos = DVector3(target->Pos(), targetheight); + if (campos != targpos) { - angledist = bigangle - smallangle; - angledir = targetangle > cam->angle ? 1 : -1; - } - else - { - angle_t diff180 = (bigangle + ANG180) - (smallangle + ANG180); - - if(quad2 == 3 && quad1 == 0) + DVector3 movement = targpos - campos; + double movelen = movement.Length(); + double movespeed = floatvalue(t_argv[3]); + DVector3 movepos; + bool finished = (movespeed >= movelen); + if (finished) movepos = targpos; + else movepos = campos + movement.Resized(movespeed); + + DAngle targetangle = floatvalue(t_argv[4]); + DAngle anglespeed = floatvalue(t_argv[5]); + DAngle diffangle = deltaangle(cam->Angles.Yaw, targetangle); + + if (movespeed > 0 && anglespeed == 0.) { - angledist = diff180; - angledir = 1; - } - else if(quad1 == 3 && quad2 == 0) - { - angledist = diff180; - angledir = -1; + if (!finished) targetangle = diffangle * movespeed / movelen; } else { - angledist = bigangle - smallangle; - if(angledist > ANG180) - { - angledist = diff180; - angledir = targetangle > cam->angle ? -1 : 1; - } - else - angledir = targetangle > cam->angle ? 1 : -1; + targetangle = cam->Angles.Yaw + anglespeed; } - } - - // set step variables based on distance and speed - mobjangle = cam->AngleTo(target); - xydist = cam->Distance2D(target); - - xstep = FixedMul(finecosine[mobjangle >> ANGLETOFINESHIFT], movespeed); - ystep = FixedMul(finesine[mobjangle >> ANGLETOFINESHIFT], movespeed); - - if(xydist && movespeed) - zstep = FixedDiv(zdist, FixedDiv(xydist, movespeed)); - else - zstep = zdist > 0 ? movespeed : -movespeed; - - if(xydist && movespeed && !anglespeed) - { - fangledist = ((double)angledist / (ANG45/45)); - fmovestep = ((double)FixedDiv(xydist, movespeed) / FRACUNIT); - if(fmovestep) - fanglestep = fangledist / fmovestep; - else - fanglestep = 360; - - anglestep =(angle_t) (fanglestep * (ANG45/45)); - } - else - anglestep = anglespeed; - - if(abs(xstep) >= (abs(dist.x) - 1)) - x = cam->X() + dist.x; - else - { - x = cam->X() + xstep; - moved = 1; - } - - if(abs(ystep) >= (abs(dist.y) - 1)) - y = cam->Y() + dist.y; - else - { - y = cam->Y() + ystep; - moved = 1; - } - - if(abs(zstep) >= (abs(zdist) - 1)) - z = targetheight; - else - { - z = cam->Z() + zstep; - moved = 1; - } - - if(anglestep >= angledist) - cam->angle = targetangle; - else - { - if(angledir == 1) - { - cam->angle += anglestep; - moved = 1; - } - else if(angledir == -1) - { - cam->angle -= anglestep; - moved = 1; - } - } - cam->radius=8; - cam->height=8; - if ((x != cam->X() || y != cam->Y()) && !P_TryMove(cam, x, y, true)) - { - Printf("Illegal camera move to (%f, %f)\n", x/65536.f, y/65536.f); - return; + cam->radius = 1 / 8192.; + cam->Height = 1 / 8192.; + cam->SetOrigin(movepos, true); + t_return.value.i = 1; + } + else + { + t_return.value.i = 0; } - cam->SetZ(z); - t_return.type = svt_int; - t_return.value.i = moved; } } @@ -3348,7 +3210,7 @@ void FParser::SF_FixedValue(void) void FParser::SF_SpawnExplosion() { - fixed_t x, y, z; + DVector3 pos; AActor* spawn; PClassActor * pclass; @@ -3356,14 +3218,14 @@ void FParser::SF_SpawnExplosion() { if (!(pclass=T_GetMobjType(t_argv[0]))) return; - x = fixedvalue(t_argv[1]); - y = fixedvalue(t_argv[2]); + pos.X = floatvalue(t_argv[1]); + pos.Y = floatvalue(t_argv[2]); if(t_argc > 3) - z = fixedvalue(t_argv[3]); + pos.Z = floatvalue(t_argv[3]); else - z = P_PointInSector(x, y)->floorplane.ZatPoint(x,y); + pos.Z = P_PointInSector(pos)->floorplane.ZatPoint(pos); - spawn = Spawn (pclass, x, y, z, ALLOW_REPLACE); + spawn = Spawn (pclass, pos, ALLOW_REPLACE); t_return.type = svt_int; t_return.value.i=0; if (spawn) @@ -3417,9 +3279,9 @@ void FParser::SF_SetObjPosition() if (!mobj) return; mobj->SetOrigin( - fixedvalue(t_argv[1]), - (t_argc >= 3)? fixedvalue(t_argv[2]) : mobj->Y(), - (t_argc >= 4)? fixedvalue(t_argv[3]) : mobj->Z(), false); + floatvalue(t_argv[1]), + (t_argc >= 3)? floatvalue(t_argv[2]) : mobj->Y(), + (t_argc >= 4)? floatvalue(t_argv[3]) : mobj->Z(), false); } } @@ -3750,7 +3612,7 @@ void FParser::SF_Resurrect() return; mo->SetState(state); - mo->height = mo->GetDefault()->height; + mo->Height = mo->GetDefault()->Height; mo->radius = mo->GetDefault()->radius; mo->flags = mo->GetDefault()->flags; mo->flags2 = mo->GetDefault()->flags2; @@ -3771,14 +3633,15 @@ void FParser::SF_Resurrect() void FParser::SF_LineAttack() { AActor *mo; - int damage, angle, slope; + int damage; + DAngle angle, slope; if (CheckArgs(3)) { mo = actorvalue(t_argv[0]); damage = intvalue(t_argv[2]); - angle = (intvalue(t_argv[1]) * (ANG45 / 45)); + angle = floatvalue(t_argv[1]); slope = P_AimLineAttack(mo, angle, MISSILERANGE); P_LineAttack(mo, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); @@ -3828,8 +3691,7 @@ void FParser::SF_Sin() { if (CheckArgs(1)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(sin(floatvalue(t_argv[0]))); + t_return.setDouble(g_sin(floatvalue(t_argv[0]))); } } @@ -3838,8 +3700,7 @@ void FParser::SF_ASin() { if (CheckArgs(1)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(asin(floatvalue(t_argv[0]))); + t_return.setDouble(g_asin(floatvalue(t_argv[0]))); } } @@ -3848,8 +3709,7 @@ void FParser::SF_Cos() { if (CheckArgs(1)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(cos(floatvalue(t_argv[0]))); + t_return.setDouble(g_cos(floatvalue(t_argv[0]))); } } @@ -3858,8 +3718,7 @@ void FParser::SF_ACos() { if (CheckArgs(1)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(acos(floatvalue(t_argv[0]))); + t_return.setDouble(g_acos(floatvalue(t_argv[0]))); } } @@ -3868,8 +3727,7 @@ void FParser::SF_Tan() { if (CheckArgs(1)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(tan(floatvalue(t_argv[0]))); + t_return.setDouble(g_tan(floatvalue(t_argv[0]))); } } @@ -3878,8 +3736,7 @@ void FParser::SF_ATan() { if (CheckArgs(1)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(atan(floatvalue(t_argv[0]))); + t_return.setDouble(g_atan(floatvalue(t_argv[0]))); } } @@ -3888,8 +3745,7 @@ void FParser::SF_Exp() { if (CheckArgs(1)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(exp(floatvalue(t_argv[0]))); + t_return.setDouble(g_exp(floatvalue(t_argv[0]))); } } @@ -3897,8 +3753,7 @@ void FParser::SF_Log() { if (CheckArgs(1)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(log(floatvalue(t_argv[0]))); + t_return.setDouble(g_log(floatvalue(t_argv[0]))); } } @@ -3907,8 +3762,7 @@ void FParser::SF_Sqrt() { if (CheckArgs(1)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(sqrt(floatvalue(t_argv[0]))); + t_return.setDouble(g_sqrt(floatvalue(t_argv[0]))); } } @@ -3918,7 +3772,7 @@ void FParser::SF_Floor() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = fixedvalue(t_argv[0]) & 0xffFF0000; + t_return.value.f = fixedvalue(t_argv[0]) & 0xffff0000; } } @@ -3927,8 +3781,7 @@ void FParser::SF_Pow() { if (CheckArgs(2)) { - t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(pow(floatvalue(t_argv[0]), floatvalue(t_argv[1]))); + t_return.setDouble(pow(floatvalue(t_argv[0]), floatvalue(t_argv[1]))); } } @@ -4008,10 +3861,9 @@ void FParser::SF_SetCorona(void) return; } - int num = t_argv[0].value.i; // which corona we want to modify - int what = t_argv[1].value.i; // what we want to modify (type, color, offset,...) - int ival = t_argv[2].value.i; // the value of what we modify - double fval = ((double) t_argv[2].value.f / FRACUNIT); + int num = intvalue(t_argv[0]); // which corona we want to modify + int what = intvalue(t_argv[1]); // what we want to modify (type, color, offset,...) + double val = floatvalue(t_argv[2]); // the value of what we modify /* switch (what) @@ -4042,7 +3894,7 @@ void FParser::SF_SetCorona(void) break; case 6: lspr[num].dynamic_radius = fval; - lspr[num].dynamic_sqrradius = sqrt(lspr[num].dynamic_radius); + lspr[num].dynamic_sqrradius = g_sqrt(lspr[num].dynamic_radius); break; default: CONS_Printf("Error in setcorona\n"); @@ -4108,11 +3960,9 @@ void FParser::SF_MobjRadius(void) if(t_argc > 1) { if(mo) - mo->radius = fixedvalue(t_argv[1]); + mo->radius = floatvalue(t_argv[1]); } - - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->radius : 0; + t_return.setDouble(mo ? mo->radius : 0.); } } @@ -4133,11 +3983,9 @@ void FParser::SF_MobjHeight(void) if(t_argc > 1) { if(mo) - mo->height = fixedvalue(t_argv[1]); + mo->Height = floatvalue(t_argv[1]); } - - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->height : 0; + t_return.setDouble(mo ? mo->Height : 0.); } } @@ -4260,33 +4108,34 @@ void FParser::SF_SpawnShot2(void) { AActor *source = NULL; PClassActor * pclass; - int z=0; - + double z = 0; + // t_argv[0] = type to spawn // t_argv[1] = source mobj, optional, -1 to default // shoots at source's angle - + if (CheckArgs(2)) { - if(t_argv[1].type == svt_int && t_argv[1].value.i < 0) + if (t_argv[1].type == svt_int && t_argv[1].value.i < 0) source = Script->trigger; else source = actorvalue(t_argv[1]); - if (t_argc>2) z=fixedvalue(t_argv[2]); - - if(!source) return; - - if (!(pclass=T_GetMobjType(t_argv[0]))) return; - + if (t_argc > 2) z = floatvalue(t_argv[2]); + + if (!source) return; + + if (!(pclass = T_GetMobjType(t_argv[0]))) return; + t_return.type = svt_mobj; - AActor *mo = Spawn (pclass, source->PosPlusZ(z), ALLOW_REPLACE); - if (mo) + AActor *mo = Spawn(pclass, source->PosPlusZ(z), ALLOW_REPLACE); + if (mo) { - S_Sound (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM); + S_Sound(mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM); mo->target = source; - P_ThrustMobj(mo, mo->angle = source->angle, mo->Speed); + mo->Angles.Yaw = source->Angles.Yaw; + mo->Thrust(); if (!P_CheckMissileSpawn(mo, source->radius)) mo = NULL; } t_return.value.mobj = mo; diff --git a/src/fragglescript/t_oper.cpp b/src/fragglescript/t_oper.cpp index c85bdf9c3..f25f719e7 100644 --- a/src/fragglescript/t_oper.cpp +++ b/src/fragglescript/t_oper.cpp @@ -360,8 +360,7 @@ void FParser::OPmultiply(svalue_t &result,int start, int n, int stop) // haleyjd: 8-17 if(left.type == svt_fixed || right.type == svt_fixed) { - result.type = svt_fixed; - result.value.f = FixedMul(fixedvalue(left), fixedvalue(right)); + result.setDouble(floatvalue(left) * floatvalue(right)); } else { @@ -385,21 +384,20 @@ void FParser::OPdivide(svalue_t &result, int start, int n, int stop) // haleyjd: 8-17 if(left.type == svt_fixed || right.type == svt_fixed) { - fixed_t fr; + auto fr = floatvalue(right); - if((fr = fixedvalue(right)) == 0) + if(fr == 0) script_error("divide by zero\n"); else { - result.type = svt_fixed; - result.value.f = FixedDiv(fixedvalue(left), fr); + result.setDouble(floatvalue(left) / fr); } } else { - int ir; + auto ir = intvalue(right); - if(!(ir = intvalue(right))) + if(!ir) script_error("divide by zero\n"); else { @@ -509,8 +507,7 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop) } else { - result.value.f = fixedvalue(result) + FRACUNIT; - result.type = svt_fixed; + result.setDouble(floatvalue(result)+1); var->SetValue (result); } } @@ -535,8 +532,7 @@ void FParser::OPincrement(svalue_t &result, int start, int n, int stop) } else { - newvalue.type = svt_fixed; - newvalue.value.f = fixedvalue(result) + FRACUNIT; + newvalue.setDouble(floatvalue(result)+1); var->SetValue (newvalue); } } @@ -574,7 +570,7 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop) } else { - result.value.f = fixedvalue(result) - FRACUNIT; + result.setDouble(floatvalue(result)-1); result.type = svt_fixed; var->SetValue (result); } @@ -600,8 +596,7 @@ void FParser::OPdecrement(svalue_t &result, int start, int n, int stop) } else { - newvalue.type = svt_fixed; - newvalue.value.f = fixedvalue(result) - FRACUNIT; + newvalue.setDouble(floatvalue(result)-1); var->SetValue (newvalue); } } diff --git a/src/fragglescript/t_parse.cpp b/src/fragglescript/t_parse.cpp index 64dc3fb52..0b2f27680 100644 --- a/src/fragglescript/t_parse.cpp +++ b/src/fragglescript/t_parse.cpp @@ -567,8 +567,7 @@ void FParser::SimpleEvaluate(svalue_t &returnvar, int n) case number: if(strchr(Tokens[n], '.')) { - returnvar.type = svt_fixed; - returnvar.value.f = (fixed_t)(atof(Tokens[n]) * FRACUNIT); + returnvar.setDouble(atof(Tokens[n])); } else { diff --git a/src/fragglescript/t_script.h b/src/fragglescript/t_script.h index a5159d038..39b0b93ee 100644 --- a/src/fragglescript/t_script.h +++ b/src/fragglescript/t_script.h @@ -82,15 +82,17 @@ enum // // //========================================================================== +typedef int fsfix; struct svalue_t { int type; + FString string; union { int i; - fixed_t f; // haleyjd: 8-17 + fsfix f; // haleyjd: 8-17 AActor *mobj; } value; @@ -106,10 +108,28 @@ struct svalue_t string = other.string; value = other.value; } + + void setInt(int ip) + { + value.i = ip; + type = svt_int; + } + + void setFixed(fsfix fp) + { + value.f = fp; + type = svt_fixed; + } + + void setDouble(double dp) + { + value.f = fsfix(dp/65536); + type = svt_fixed; + } }; int intvalue(const svalue_t & v); -fixed_t fixedvalue(const svalue_t & v); +fsfix fixedvalue(const svalue_t & v); double floatvalue(const svalue_t & v); const char *stringvalue(const svalue_t & v); AActor *actorvalue(const svalue_t &svalue); @@ -153,7 +173,7 @@ public: union value_t { SDWORD i; - fixed_t fixed; // haleyjd: fixed-point + fsfix fixed; // haleyjd: fixed-point // the following are only used in the global script so we don't need to bother with them // when serializing variables. diff --git a/src/fragglescript/t_variable.cpp b/src/fragglescript/t_variable.cpp index 09cdf950f..7fd39aa14 100644 --- a/src/fragglescript/t_variable.cpp +++ b/src/fragglescript/t_variable.cpp @@ -66,7 +66,7 @@ int intvalue(const svalue_t &v) { return (v.type == svt_string ? atoi(v.string) : - v.type == svt_fixed ? (int)(v.value.f / FRACUNIT) : + v.type == svt_fixed ? (int)(v.value.f / 65536.) : v.type == svt_mobj ? -1 : v.value.i ); } @@ -76,11 +76,11 @@ int intvalue(const svalue_t &v) // //========================================================================== -fixed_t fixedvalue(const svalue_t &v) +fsfix fixedvalue(const svalue_t &v) { return (v.type == svt_fixed ? v.value.f : - v.type == svt_string ? (fixed_t)(atof(v.string) * FRACUNIT) : - v.type == svt_mobj ? -1*FRACUNIT : v.value.i * FRACUNIT ); + v.type == svt_string ? (fsfix)(atof(v.string) * 65536.) : + v.type == svt_mobj ? -65536 : v.value.i * 65536 ); } //========================================================================== @@ -93,7 +93,7 @@ double floatvalue(const svalue_t &v) { return v.type == svt_string ? atof(v.string) : - v.type == svt_fixed ? FIXED2DBL(v.value.f) : + v.type == svt_fixed ? v.value.f * 65536. : v.type == svt_mobj ? -1. : (double)v.value.i; } @@ -118,7 +118,7 @@ const char *stringvalue(const svalue_t & v) case svt_fixed: { - double val = ((double)v.value.f) / FRACUNIT; + double val = v.value.f / 65536.; mysnprintf(buffer, countof(buffer), "%g", val); return buffer; } diff --git a/src/g_doom/a_archvile.cpp b/src/g_doom/a_archvile.cpp index 11cbcf15d..84481e5f6 100644 --- a/src/g_doom/a_archvile.cpp +++ b/src/g_doom/a_archvile.cpp @@ -13,7 +13,7 @@ // PIT_VileCheck // Detect a corpse that could be raised. // -void A_Fire(AActor *self, int height); +void A_Fire(AActor *self, double height); // @@ -50,13 +50,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrackle) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Fire) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED_OPT(height) { height = 0; } + PARAM_FLOAT_OPT(height) { height = 0; } A_Fire(self, height); return 0; } -void A_Fire(AActor *self, int height) +void A_Fire(AActor *self, double height) { AActor *dest; @@ -68,7 +68,7 @@ void A_Fire(AActor *self, int height) if (!P_CheckSight (self->target, dest, 0) ) return; - fixedvec3 newpos = dest->Vec3Angle(24 * FRACUNIT, dest->angle, height); + DVector3 newpos = dest->Vec3Angle(24., dest->Angles.Yaw, height); self->SetOrigin(newpos, true); } @@ -116,7 +116,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) PARAM_INT_OPT (dmg) { dmg = 20; } PARAM_INT_OPT (blastdmg) { blastdmg = 70; } PARAM_INT_OPT (blastrad) { blastrad = 70; } - PARAM_FIXED_OPT (thrust) { thrust = FRACUNIT; } + PARAM_FLOAT_OPT (thrust) { thrust = 1; } PARAM_NAME_OPT (dmgtype) { dmgtype = NAME_Fire; } PARAM_INT_OPT (flags) { flags = 0; } @@ -147,14 +147,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) if (fire != NULL) { // move the fire between the vile and the player - fixedvec3 pos = target->Vec3Angle(-24 * FRACUNIT, self->angle, 0); + DVector3 pos = target->Vec3Angle(-24., self->Angles.Yaw, 0); fire->SetOrigin (pos, true); P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0); } if (!(target->flags7 & MF7_DONTTHRUST)) { - target->vel.z = Scale(thrust, 1000, target->Mass); + target->Vel.Z = thrust * 1000 / MAX(1, target->Mass); } return 0; } diff --git a/src/g_doom/a_bossbrain.cpp b/src/g_doom/a_bossbrain.cpp index f752b7334..51ee77ff8 100644 --- a/src/g_doom/a_bossbrain.cpp +++ b/src/g_doom/a_bossbrain.cpp @@ -31,13 +31,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainPain) return 0; } -static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z) +static void BrainishExplosion (const DVector3 &pos) { - AActor *boom = Spawn("Rocket", x, y, z, NO_REPLACE); + AActor *boom = Spawn("Rocket", pos, NO_REPLACE); if (boom != NULL) { boom->DeathSound = "misc/brainexplode"; - boom->vel.z = pr_brainscream() << 9; + boom->Vel.Z = pr_brainscream() /128.; PClassActor *cls = PClass::FindActor("BossBrain"); if (cls != NULL) @@ -57,12 +57,11 @@ static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z) DEFINE_ACTION_FUNCTION(AActor, A_BrainScream) { PARAM_ACTION_PROLOGUE; - fixed_t x; - - for (x = self->X() - 196*FRACUNIT; x < self->X() + 320*FRACUNIT; x += 8*FRACUNIT) + + for (double x = -196; x < +320; x += 8) { - BrainishExplosion (x, self->Y() - 320*FRACUNIT, - 128 + (pr_brainscream() << (FRACBITS + 1))); + // (1 / 512.) is actually what the original value of 128 did, even though it probably meant 128 map units. + BrainishExplosion(self->Vec2OffsetZ(x, -320, (1 / 512.) + pr_brainexplode() * 2)); } S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE); return 0; @@ -71,9 +70,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainScream) DEFINE_ACTION_FUNCTION(AActor, A_BrainExplode) { PARAM_ACTION_PROLOGUE; - fixed_t x = self->X() + pr_brainexplode.Random2()*2048; - fixed_t z = 128 + pr_brainexplode()*2*FRACUNIT; - BrainishExplosion (x, self->Y(), z); + double x = pr_brainexplode.Random2() / 32.; + DVector3 pos = self->Vec2OffsetZ(x, 0, 1 / 512. + pr_brainexplode() * 2); + BrainishExplosion(pos); return 0; } @@ -144,17 +143,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit) spit->master = self; // [RH] Do this correctly for any trajectory. Doom would divide by 0 // if the target had the same y coordinate as the spitter. - if ((spit->vel.x | spit->vel.y) == 0) + if (spit->Vel.X == 0 && spit->Vel.Y == 0) { spit->special2 = 0; } - else if (abs(spit->vel.y) > abs(spit->vel.x)) + else if (fabs(spit->Vel.X) > fabs(spit->Vel.Y)) { - spit->special2 = (targ->Y() - self->Y()) / spit->vel.y; + spit->special2 = int((targ->Y() - self->Y()) / spit->Vel.Y); } else { - spit->special2 = (targ->X() - self->X()) / spit->vel.x; + spit->special2 = int((targ->X() - self->X()) / spit->Vel.X); } // [GZ] Calculates when the projectile will have reached destination spit->special2 += level.maptime; diff --git a/src/g_doom/a_doommisc.cpp b/src/g_doom/a_doommisc.cpp index 66f7cc7e9..93e7abdaa 100644 --- a/src/g_doom/a_doommisc.cpp +++ b/src/g_doom/a_doommisc.cpp @@ -47,7 +47,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BarrelDestroy) if (dmflags2 & DF2_BARRELS_RESPAWN) { - self->height = self->GetDefault()->height; + self->Height = self->GetDefault()->Height; self->renderflags |= RF_INVISIBLE; self->flags &= ~MF_SOLID; } diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index b47518f69..21119f8a0 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -30,9 +30,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int pitch; + DAngle pitch; FTranslatedLineTarget t; if (self->player != NULL) @@ -50,9 +50,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) if (self->FindInventory()) damage *= 10; - angle = self->angle; - - angle += pr_punch.Random2() << 18; + angle = self->Angles.Yaw + pr_punch.Random2() * (5.625 / 256); pitch = P_AimLineAttack (self, angle, MELEERANGE); P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &t); @@ -61,7 +59,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) if (t.linetarget) { S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM); - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; } return 0; } @@ -124,15 +122,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) PARAM_INT_OPT (damage) { damage = 2; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (range) { range = 0; } - PARAM_ANGLE_OPT(spread_xy) { spread_xy = 33554432; /*angle_t(2.8125 * (ANGLE_90 / 90.0));*/ } // The floating point expression does not get optimized away. - PARAM_ANGLE_OPT (spread_z) { spread_z = 0; } - PARAM_FIXED_OPT (lifesteal) { lifesteal = 0; } + PARAM_FLOAT_OPT (range) { range = 0; } + PARAM_ANGLE_OPT (spread_xy) { spread_xy = 2.8125; } + PARAM_ANGLE_OPT (spread_z) { spread_z = 0.; } + PARAM_FLOAT_OPT (lifesteal) { lifesteal = 0; } PARAM_INT_OPT (lifestealmax) { lifestealmax = 0; } PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; } - angle_t angle; - angle_t slope; + DAngle angle; + DAngle slope; player_t *player; FTranslatedLineTarget t; int actualdamage; @@ -155,12 +153,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) damage *= (pr_saw()%10+1); } if (range == 0) - { // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) - range = MELEERANGE+1; + { + range = SAWRANGE; } - angle = self->angle + (pr_saw.Random2() * (spread_xy / 255)); - slope = P_AimLineAttack (self, angle, range, &t) + (pr_saw.Random2() * (spread_z / 255)); + angle = self->Angles.Yaw + spread_xy * (pr_saw.Random2() / 255.); + slope = P_AimLineAttack (self, angle, range, &t) + spread_z * (pr_saw.Random2() / 255.); AWeapon *weapon = self->player->ReadyWeapon; if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!t.linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON()) @@ -209,8 +207,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) if (armorbonustype != NULL) { assert(armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus))); - ABasicArmorBonus *armorbonus = static_cast(Spawn(armorbonustype, 0,0,0, NO_REPLACE)); - armorbonus->SaveAmount *= (actualdamage * lifesteal) >> FRACBITS; + ABasicArmorBonus *armorbonus = static_cast(Spawn(armorbonustype)); + armorbonus->SaveAmount = int(armorbonus->SaveAmount * actualdamage * lifesteal); armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax; armorbonus->flags |= MF_DROPPED; armorbonus->ClearCounters(); @@ -224,7 +222,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) else { - P_GiveBody (self, (actualdamage * lifesteal) >> FRACBITS, lifestealmax); + P_GiveBody (self, int(actualdamage * lifesteal), lifestealmax); } } @@ -233,20 +231,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) // turn to face target if (!(flags & SF_NOTURN)) { - angle = t.angleFromSource; - if (angle - self->angle > ANG180) + DAngle anglediff = deltaangle(self->Angles.Yaw, t.angleFromSource); + + if (anglediff < 0.0) { - if (angle - self->angle < (angle_t)(-ANG90 / 20)) - self->angle = angle + ANG90 / 21; + if (anglediff < -4.5) + self->Angles.Yaw = angle + 90.0 / 21; else - self->angle -= ANG90 / 20; + self->Angles.Yaw -= 4.5; } else { - if (angle - self->angle > ANG90 / 20) - self->angle = angle - ANG90 / 21; + if (anglediff > 4.5) + self->Angles.Yaw = angle - 90.0 / 21; else - self->angle += ANG90 / 20; + self->Angles.Yaw += 4.5; } } if (!(flags & SF_NOPULLIN)) @@ -280,7 +279,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun) } player->mo->PlayAttacking2 (); - angle_t pitch = P_BulletSlope (self); + DAngle pitch = P_BulletSlope (self); for (i = 0; i < 7; i++) { @@ -297,7 +296,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) PARAM_ACTION_PROLOGUE; int i; - angle_t angle; + DAngle angle; int damage; player_t *player; @@ -318,13 +317,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) player->mo->PlayAttacking2 (); - angle_t pitch = P_BulletSlope (self); + DAngle pitch = P_BulletSlope (self); for (i=0 ; i<20 ; i++) { damage = 5*(pr_fireshotgun2()%3+1); - angle = self->angle; - angle += pr_fireshotgun2.Random2() << 19; + angle = self->Angles.Yaw + pr_fireshotgun2.Random2() * (11.25 / 256); // Doom adjusts the bullet slope by shifting a random number [-255,255] // left 5 places. At 2048 units away, this means the vertical position @@ -335,7 +333,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) P_LineAttack (self, angle, PLAYERMISSILERANGE, - pitch + (pr_fireshotgun2.Random2() * 332063), damage, + pitch + pr_fireshotgun2.Random2() * (7.097 / 256), damage, NAME_Hitscan, NAME_BulletPuff); } return 0; @@ -507,10 +505,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade) } // Temporarily raise the pitch to send the grenade slightly upwards - fixed_t SavedPlayerPitch = self->pitch; - self->pitch -= (1152 << FRACBITS); + DAngle SavedPlayerPitch = self->Angles.Pitch; + self->Angles.Pitch -= 6.328125; //(1152 << F RACBITS); P_SpawnPlayerMissile(self, grenade); - self->pitch = SavedPlayerPitch; + self->Angles.Pitch = SavedPlayerPitch; return 0; } @@ -572,7 +570,11 @@ static void FireRailgun(AActor *self, int offset_xy, bool fromweapon) damage = deathmatch ? 100 : 150; - P_RailAttack (self, damage, offset_xy); + FRailParams p; + p.source = self; + p.damage = damage; + p.offset_xy = offset_xy; + P_RailAttack (&p); } @@ -625,7 +627,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG) return 0; } - P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindActor("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG)); + P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindActor("BFGBall"), self->Angles.Yaw, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG)); return 0; } @@ -638,25 +640,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) { PARAM_ACTION_PROLOGUE; PARAM_CLASS_OPT (spraytype, AActor) { spraytype = NULL; } - PARAM_INT_OPT (numrays) { numrays = 40; } - PARAM_INT_OPT (damagecnt) { damagecnt = 15; } - PARAM_ANGLE_OPT (angle) { angle = ANGLE_90; } - PARAM_FIXED_OPT (distance) { distance = 16*64*FRACUNIT; } - PARAM_ANGLE_OPT (vrange) { vrange = 32*ANGLE_1; } + PARAM_INT_OPT (numrays) { numrays = 0; } + PARAM_INT_OPT (damagecnt) { damagecnt = 0; } + PARAM_ANGLE_OPT (angle) { angle = 0.; } + PARAM_FLOAT_OPT (distance) { distance = 0; } + PARAM_ANGLE_OPT (vrange) { vrange = 0.; } PARAM_INT_OPT (defdamage) { defdamage = 0; } int i; int j; int damage; - angle_t an; + DAngle an; FTranslatedLineTarget t; if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra"); if (numrays <= 0) numrays = 40; if (damagecnt <= 0) damagecnt = 15; - if (angle == 0) angle = ANG90; - if (distance <= 0) distance = 16 * 64 * FRACUNIT; - if (vrange == 0) vrange = ANGLE_1 * 32; + if (angle == 0) angle = 90.; + if (distance <= 0) distance = 16 * 64; + if (vrange == 0) vrange = 32.; // [RH] Don't crash if no target if (!self->target) @@ -665,14 +667,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) // offset angles from its attack angle for (i = 0; i < numrays; i++) { - an = self->angle - angle / 2 + angle / numrays*i; + an = self->Angles.Yaw - angle / 2 + angle / numrays*i; // self->target is the originator (player) of the missile P_AimLineAttack(self->target, an, distance, &t, vrange); if (t.linetarget != NULL) { - AActor *spray = Spawn(spraytype, t.linetarget->PosPlusZ(t.linetarget->height >> 2), ALLOW_REPLACE); + AActor *spray = Spawn(spraytype, t.linetarget->PosPlusZ(t.linetarget->Height / 4), ALLOW_REPLACE); int dmgFlags = 0; FName dmgType = NAME_BFGSplash; @@ -702,7 +704,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) damage = defdamage; } - int newdam = P_DamageMobj(t.linetarget, self->target, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource); + int newdam = P_DamageMobj(t.linetarget, self->target, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource.Degrees); P_TraceBleed(newdam > 0 ? newdam : damage, &t, self); } } @@ -755,16 +757,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG) self->player->extralight = 2; // Save values temporarily - angle_t SavedPlayerAngle = self->angle; - fixed_t SavedPlayerPitch = self->pitch; + DAngle SavedPlayerAngle = self->Angles.Yaw; + DAngle SavedPlayerPitch = self->Angles.Pitch; for (int i = 0; i < 2; i++) // Spawn two plasma balls in sequence { - self->angle += ((pr_oldbfg()&127) - 64) * (ANG90/768); - self->pitch += ((pr_oldbfg()&127) - 64) * (ANG90/640); + self->Angles.Yaw += ((pr_oldbfg()&127) - 64) * (90./768); + self->Angles.Pitch += ((pr_oldbfg()&127) - 64) * (90./640); mo = P_SpawnPlayerMissile (self, plasma[i]); // Restore saved values - self->angle = SavedPlayerAngle; - self->pitch = SavedPlayerPitch; + self->Angles.Yaw = SavedPlayerAngle; + self->Angles.Pitch = SavedPlayerPitch; } if (doesautoaim && weapon != NULL) { // Restore autoaim setting diff --git a/src/g_doom/a_fatso.cpp b/src/g_doom/a_fatso.cpp index e79362316..872e1982d 100644 --- a/src/g_doom/a_fatso.cpp +++ b/src/g_doom/a_fatso.cpp @@ -15,7 +15,7 @@ // firing three missiles in three different directions? // Doesn't look like it. // -#define FATSPREAD (ANG90/8) +#define FATSPREAD (90./8) DEFINE_ACTION_FUNCTION(AActor, A_FatRaise) { @@ -32,7 +32,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1) PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; } AActor *missile; - angle_t an; if (!self->target) return 0; @@ -41,16 +40,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1) A_FaceTarget (self); // Change direction to ... - self->angle += FATSPREAD; + self->Angles.Yaw += FATSPREAD; P_SpawnMissile (self, self->target, spawntype); missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { - missile->angle += FATSPREAD; - an = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul (missile->Speed, finecosine[an]); - missile->vel.y = FixedMul (missile->Speed, finesine[an]); + missile->Angles.Yaw += FATSPREAD; + missile->VelFromAngle(); } return 0; } @@ -61,7 +58,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2) PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; } AActor *missile; - angle_t an; if (!self->target) return 0; @@ -70,16 +66,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2) A_FaceTarget (self); // Now here choose opposite deviation. - self->angle -= FATSPREAD; + self->Angles.Yaw -= FATSPREAD; P_SpawnMissile (self, self->target, spawntype); missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { - missile->angle -= FATSPREAD*2; - an = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul (missile->Speed, finecosine[an]); - missile->vel.y = FixedMul (missile->Speed, finesine[an]); + missile->Angles.Yaw -= FATSPREAD*2; + missile->VelFromAngle(); } return 0; } @@ -90,7 +84,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3) PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; } AActor *missile; - angle_t an; if (!self->target) return 0; @@ -102,19 +95,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3) missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { - missile->angle -= FATSPREAD/2; - an = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul (missile->Speed, finecosine[an]); - missile->vel.y = FixedMul (missile->Speed, finesine[an]); + missile->Angles.Yaw -= FATSPREAD/2; + missile->VelFromAngle(); } missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { - missile->angle += FATSPREAD/2; - an = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul (missile->Speed, finecosine[an]); - missile->vel.y = FixedMul (missile->Speed, finesine[an]); + missile->Angles.Yaw += FATSPREAD/2; + missile->VelFromAngle(); } return 0; } @@ -137,8 +126,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; } PARAM_INT_OPT (n) { n = 0; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (vrange) { vrange = 4*FRACUNIT; } - PARAM_FIXED_OPT (hrange) { hrange = FRACUNIT/2; } + PARAM_FLOAT_OPT (vrange) { vrange = 4; } + PARAM_FLOAT_OPT (hrange) { hrange = 0.5; } int i, j; @@ -152,20 +141,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) } P_RadiusAttack (self, self->target, 128, 128, self->DamageType, (flags & MSF_DontHurt) ? 0 : RADF_HURTSOURCE); - P_CheckSplash(self, 128<Pos(), NO_REPLACE); // We need something to aim at. AActor *master = (flags & MSF_DontHurt) ? (AActor*)(self->target) : self; - target->height = self->height; + target->Height = self->Height; for (i = -n; i <= n; i += 8) { for (j = -n; j <= n; j += 8) { AActor *mo; target->SetXYZ( - self->X() + (i << FRACBITS), // Aim in many directions from source - self->Y() + (j << FRACBITS), + self->X() + i, // Aim in many directions from source + self->Y() + j, self->Z() + (P_AproxDistance(i,j) * vrange)); // Aim up fairly high if ((flags & MSF_Classic) || // Flag explicitely set, or no flags and compat options (flags == 0 && (self->state->DefineFlags & SDF_DEHACKED) && (i_compatflags & COMPATF_MUSHROOM))) @@ -178,9 +167,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) } if (mo != NULL) { // Slow it down a bit - mo->vel.x = FixedMul(mo->vel.x, hrange); - mo->vel.y = FixedMul(mo->vel.y, hrange); - mo->vel.z = FixedMul(mo->vel.z, hrange); + mo->Vel *= hrange; mo->flags &= ~MF_NOGRAVITY; // Make debris fall under gravity } } diff --git a/src/g_doom/a_keen.cpp b/src/g_doom/a_keen.cpp index bb73d2015..d0a10da58 100644 --- a/src/g_doom/a_keen.cpp +++ b/src/g_doom/a_keen.cpp @@ -35,7 +35,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KeenDie) } } - EV_DoDoor (DDoor::doorOpen, NULL, NULL, doortag, 2*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorOpen, NULL, NULL, doortag, 2., 0, 0, 0); return 0; } diff --git a/src/g_doom/a_lostsoul.cpp b/src/g_doom/a_lostsoul.cpp index 8aa7108cf..056802fe0 100644 --- a/src/g_doom/a_lostsoul.cpp +++ b/src/g_doom/a_lostsoul.cpp @@ -19,12 +19,9 @@ // Fly at the player like a missile. // -void A_SkullAttack(AActor *self, fixed_t speed) +void A_SkullAttack(AActor *self, double speed) { AActor *dest; - angle_t an; - int dist; - if (!self->target) return; @@ -33,21 +30,14 @@ void A_SkullAttack(AActor *self, fixed_t speed) S_Sound (self, CHAN_VOICE, self->AttackSound, 1, ATTN_NORM); A_FaceTarget (self); - an = self->angle >> ANGLETOFINESHIFT; - self->vel.x = FixedMul (speed, finecosine[an]); - self->vel.y = FixedMul (speed, finesine[an]); - dist = self->AproxDistance (dest); - dist = dist / speed; - - if (dist < 1) - dist = 1; - self->vel.z = (dest->Z() + (dest->height>>1) - self->Z()) / dist; + self->VelFromAngle(speed); + self->Vel.Z = (dest->Center() - self->Z()) / self->DistanceBySpeed(dest, speed); } DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED_OPT(speed) { speed = SKULLSPEED; } + PARAM_FLOAT_OPT(speed) { speed = SKULLSPEED; } if (speed <= 0) speed = SKULLSPEED; diff --git a/src/g_doom/a_painelemental.cpp b/src/g_doom/a_painelemental.cpp index acdfdb04d..3620b88db 100644 --- a/src/g_doom/a_painelemental.cpp +++ b/src/g_doom/a_painelemental.cpp @@ -10,8 +10,6 @@ #include "doomstat.h" */ -DECLARE_ACTION(A_SkullAttack) - enum PA_Flags { PAF_NOSKULLATTACK = 1, @@ -23,21 +21,21 @@ enum PA_Flags // A_PainShootSkull // Spawn a lost soul and launch it at the target // -void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int flags = 0, int limit = -1) +void A_PainShootSkull (AActor *self, DAngle Angle, PClassActor *spawntype, int flags = 0, int limit = -1) { AActor *other; - int prestep; + double prestep; if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul"); assert(spawntype != NULL); if (self->DamageType == NAME_Massacre) return; // [RH] check to make sure it's not too close to the ceiling - if (self->Top() + 8*FRACUNIT > self->ceilingz) + if (self->Top() + 8 > self->ceilingz) { if (self->flags & MF_FLOAT) { - self->vel.z -= 2*FRACUNIT; + self->Vel.Z -= 2; self->flags |= MF_INFLOAT; self->flags4 |= MF4_VFRICTION; } @@ -64,14 +62,13 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int } // okay, there's room for another one - prestep = 4*FRACUNIT + - 3*(self->radius + GetDefaultByType(spawntype)->radius)/2; + prestep = 4 + (self->radius + GetDefaultByType(spawntype)->radius) * 1.5; // NOTE: The following code contains some advance work for line-to-line portals which is currenty inactive. - fixedvec2 dist = Vec2Angle(prestep, angle); - fixedvec3 pos = self->Vec3Offset(dist.x, dist.y, 8 * FRACUNIT, true); - fixedvec3 src = self->Pos(); + DVector2 dist = Angle.ToVector(prestep); + DVector3 pos = self->Vec3Offset(dist.X, dist.Y, 8., true); + DVector3 src = self->Pos(); for (int i = 0; i < 2; i++) { @@ -79,7 +76,7 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int // wall or an impassible line, or a "monsters can't cross" line.// | // If it is, then we don't allow the spawn. // V - FBoundingBox box(MIN(src.x, pos.x), MIN(src.y, pos.y), MAX(src.x, pos.x), MAX(src.y, pos.y)); + FBoundingBox box(MIN(src.X, pos.X), MIN(src.Y, pos.Y), MAX(src.X, pos.X), MAX(src.Y, pos.Y)); FBlockLinesIterator it(box); line_t *ld; bool inportal = false; @@ -88,8 +85,8 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int { if (ld->isLinePortal() && i == 0) { - if (P_PointOnLineSidePrecise(src.x, src.y, ld) == 0 && - P_PointOnLineSidePrecise(pos.x, pos.y, ld) == 1) + if (P_PointOnLineSidePrecise(src, ld) == 0 && + P_PointOnLineSidePrecise(pos, ld) == 1) { // crossed a portal line from front to back, we need to repeat the check on the other side as well. inportal = true; @@ -98,12 +95,9 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int else if (!(ld->flags & ML_TWOSIDED) || (ld->flags & (ML_BLOCKING | ML_BLOCKMONSTERS | ML_BLOCKEVERYTHING))) { - if (!(box.Left() > ld->bbox[BOXRIGHT] || - box.Right() < ld->bbox[BOXLEFT] || - box.Top() < ld->bbox[BOXBOTTOM] || - box.Bottom() > ld->bbox[BOXTOP])) + if (box.inRange(ld)) { - if (P_PointOnLineSidePrecise(src.x, src.y, ld) != P_PointOnLineSidePrecise(pos.x, pos.y, ld)) + if (P_PointOnLineSidePrecise(src, ld) != P_PointOnLineSidePrecise(pos, ld)) return; // line blocks trajectory // ^ } } @@ -111,20 +105,19 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int if (!inportal) break; // recalculate position and redo the check on the other side of the portal - pos = self->Vec3Offset(dist.x, dist.y, 8 * FRACUNIT); - src.x = pos.x - dist.x; - src.y = pos.y - dist.y; + pos = self->Vec3Offset(dist.X, dist.Y, 8.); + src.X = pos.X - dist.X; + src.Y = pos.Y - dist.Y; } - other = Spawn (spawntype, pos.x, pos.y, pos.z, ALLOW_REPLACE); + other = Spawn (spawntype, pos, ALLOW_REPLACE); // Check to see if the new Lost Soul's z value is above the // ceiling of its new sector, or below the floor. If so, kill it. - if ((other->Top() > - (other->Sector->HighestCeilingAt(other))) || - (other->Z() < other->Sector->LowestFloorAt(other))) + if (other->Top() > other->Sector->HighestCeilingAt(other) || + other->Z() < other->Sector->LowestFloorAt(other)) { // kill it immediately P_DamageMobj (other, self, self, TELEFRAG_DAMAGE, NAME_None);// ^ @@ -160,13 +153,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack) return 0; PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; } - PARAM_ANGLE_OPT (angle) { angle = 0; } + PARAM_ANGLE_OPT (angle) { angle = 0.; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (limit) { limit = -1; } if (!(flags & PAF_AIMFACING)) A_FaceTarget (self); - A_PainShootSkull (self, self->angle+angle, spawntype, flags, limit); + A_PainShootSkull (self, self->Angles.Yaw + angle, spawntype, flags, limit); return 0; } @@ -179,8 +172,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack) return 0; A_FaceTarget (self); - A_PainShootSkull (self, self->angle + ANG45, spawntype); - A_PainShootSkull (self, self->angle - ANG45, spawntype); + A_PainShootSkull (self, self->Angles.Yaw + 45., spawntype); + A_PainShootSkull (self, self->Angles.Yaw - 45., spawntype); return 0; } @@ -194,8 +187,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie) self->flags &= ~MF_FRIENDLY; } A_Unblock(self, true); - A_PainShootSkull (self, self->angle + ANG90, spawntype); - A_PainShootSkull (self, self->angle + ANG180, spawntype); - A_PainShootSkull (self, self->angle + ANG270, spawntype); + A_PainShootSkull (self, self->Angles.Yaw + 90, spawntype); + A_PainShootSkull (self, self->Angles.Yaw + 180, spawntype); + A_PainShootSkull (self, self->Angles.Yaw + 270, spawntype); return 0; } diff --git a/src/g_doom/a_possessed.cpp b/src/g_doom/a_possessed.cpp index 5fc2e6b89..f6b559c4b 100644 --- a/src/g_doom/a_possessed.cpp +++ b/src/g_doom/a_possessed.cpp @@ -22,19 +22,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_PosAttack) { PARAM_ACTION_PROLOGUE; - int angle; int damage; - int slope; + DAngle angle; + DAngle slope; if (!self->target) return 0; A_FaceTarget (self); - angle = self->angle; + angle = self->Angles.Yaw; slope = P_AimLineAttack (self, angle, MISSILERANGE); S_Sound (self, CHAN_WEAPON, "grunt/attack", 1, ATTN_NORM); - angle += pr_posattack.Random2() << 20; + angle += pr_posattack.Random2() * (22.5 / 256); damage = ((pr_posattack()%5)+1)*3; P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); return 0; @@ -43,16 +43,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_PosAttack) static void A_SPosAttack2 (AActor *self) { int i; - int bangle; - int slope; + DAngle bangle; + DAngle slope; A_FaceTarget (self); - bangle = self->angle; + bangle = self->Angles.Yaw; slope = P_AimLineAttack (self, bangle, MISSILERANGE); for (i=0 ; i<3 ; i++) { - int angle = bangle + (pr_sposattack.Random2() << 20); + DAngle angle = bangle + pr_sposattack.Random2() * (22.5 / 256); int damage = ((pr_sposattack()%5)+1)*3; P_LineAttack(self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); } @@ -88,10 +88,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack) { PARAM_ACTION_PROLOGUE; - int angle; - int bangle; + DAngle angle; + DAngle bangle; int damage; - int slope; + DAngle slope; if (!self->target) return 0; @@ -104,10 +104,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack) S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); A_FaceTarget (self); - bangle = self->angle; + bangle = self->Angles.Yaw; slope = P_AimLineAttack (self, bangle, MISSILERANGE); - angle = bangle + (pr_cposattack.Random2() << 20); + angle = bangle + pr_cposattack.Random2() * (22.5 / 256); damage = ((pr_cposattack()%5)+1)*3; P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); return 0; diff --git a/src/g_doom/a_revenant.cpp b/src/g_doom/a_revenant.cpp index 1b36d6cb2..9c8a38602 100644 --- a/src/g_doom/a_revenant.cpp +++ b/src/g_doom/a_revenant.cpp @@ -28,27 +28,26 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkelMissile) return 0; A_FaceTarget (self); - self->AddZ(16*FRACUNIT); - missile = P_SpawnMissile (self, self->target, PClass::FindActor("RevenantTracer")); - self->AddZ(-16*FRACUNIT); + self->AddZ(16.); + missile = P_SpawnMissile(self, self->target, PClass::FindActor("RevenantTracer")); + self->AddZ(-16.); if (missile != NULL) { - missile->SetOrigin(missile->Vec3Offset(missile->vel.x, missile->vel.y, 0), false); + missile->SetOrigin(missile->Vec3Offset(missile->Vel.X, missile->Vel.Y, 0.), false); missile->tracer = self->target; } return 0; } -#define TRACEANGLE (0xc000000) +#define TRACEANGLE (16.875) DEFINE_ACTION_FUNCTION(AActor, A_Tracer) { PARAM_ACTION_PROLOGUE; - angle_t exact; - fixed_t dist; - fixed_t slope; + double dist; + double slope; AActor *dest; AActor *smoke; @@ -65,11 +64,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer) return 0; // spawn a puff of smoke behind the rocket - P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->angle, self->angle, 3); + P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->Angles.Yaw, self->Angles.Yaw, 3); - smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->vel.x, -self->vel.y, 0), ALLOW_REPLACE); + smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->Vel.X, -self->Vel.Y, 0.), ALLOW_REPLACE); - smoke->vel.z = FRACUNIT; + smoke->Vel.Z = 1.; smoke->tics -= pr_tracer()&3; if (smoke->tics < 1) smoke->tics = 1; @@ -81,49 +80,42 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer) return 0; // change angle - exact = self->AngleTo(dest); + DAngle exact = self->AngleTo(dest); + DAngle diff = deltaangle(self->Angles.Yaw, exact); - if (exact != self->angle) + if (diff < 0) { - if (exact - self->angle > 0x80000000) - { - self->angle -= TRACEANGLE; - if (exact - self->angle < 0x80000000) - self->angle = exact; - } - else - { - self->angle += TRACEANGLE; - if (exact - self->angle > 0x80000000) - self->angle = exact; - } + self->Angles.Yaw -= TRACEANGLE; + if (deltaangle(self->Angles.Yaw, exact) > 0) + self->Angles.Yaw = exact; } - - exact = self->angle>>ANGLETOFINESHIFT; - self->vel.x = FixedMul (self->Speed, finecosine[exact]); - self->vel.y = FixedMul (self->Speed, finesine[exact]); + else if (diff > 0) + { + self->Angles.Yaw += TRACEANGLE; + if (deltaangle(self->Angles.Yaw, exact) < 0.) + self->Angles.Yaw = exact; + } + + self->VelFromAngle(); if (!(self->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { // change slope - dist = self->AproxDistance (dest) / self->Speed; + dist = self->DistanceBySpeed(dest, self->Speed); - if (dist < 1) - dist = 1; - - if (dest->height >= 56*FRACUNIT) + if (dest->Height >= 56.) { - slope = (dest->Z()+40*FRACUNIT - self->Z()) / dist; + slope = (dest->Z() + 40. - self->Z()) / dist; } else { - slope = (dest->Z() + self->height*2/3 - self->Z()) / dist; + slope = (dest->Z() + self->Height*(2./3) - self->Z()) / dist; } - if (slope < self->vel.z) - self->vel.z -= FRACUNIT/8; + if (slope < self->Vel.Z) + self->Vel.Z -= 1. / 8; else - self->vel.z += FRACUNIT/8; + self->Vel.Z += 1. / 8; } return 0; } diff --git a/src/g_doom/a_scriptedmarine.cpp b/src/g_doom/a_scriptedmarine.cpp index 0f9e48e59..a3d33f555 100644 --- a/src/g_doom/a_scriptedmarine.cpp +++ b/src/g_doom/a_scriptedmarine.cpp @@ -275,14 +275,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw) A_FaceTarget (self); if (self->CheckMeleeRange ()) { - angle_t angle; + DAngle angle; FTranslatedLineTarget t; damage *= (pr_m_saw()%10+1); - angle = self->angle + (pr_m_saw.Random2() << 18); + angle = self->Angles.Yaw + pr_m_saw.Random2() * (5.625 / 256); - P_LineAttack (self, angle, MELEERANGE+1, - P_AimLineAttack (self, angle, MELEERANGE+1), damage, + P_LineAttack (self, angle, SAWRANGE, + P_AimLineAttack (self, angle, SAWRANGE), damage, NAME_Melee, pufftype, false, &t); if (!t.linetarget) @@ -294,19 +294,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw) // turn to face target angle = t.angleFromSource; - if (angle - self->angle > ANG180) + DAngle anglediff = deltaangle(self->Angles.Yaw, angle); + + if (anglediff < 0.0) { - if (angle - self->angle < (angle_t)(-ANG90/20)) - self->angle = angle + ANG90/21; + if (anglediff < -4.5) + self->Angles.Yaw = angle + 90.0 / 21; else - self->angle -= ANG90/20; + self->Angles.Yaw -= 4.5; } else { - if (angle - self->angle > ANG90/20) - self->angle = angle - ANG90/21; + if (anglediff > 4.5) + self->Angles.Yaw = angle - 90.0 / 21; else - self->angle += ANG90/20; + self->Angles.Yaw += 4.5; } } else @@ -325,9 +327,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw) static void MarinePunch(AActor *self, int damagemul) { - angle_t angle; + DAngle angle; int damage; - int pitch; + DAngle pitch; FTranslatedLineTarget t; if (self->target == NULL) @@ -336,7 +338,7 @@ static void MarinePunch(AActor *self, int damagemul) damage = ((pr_m_punch()%10+1) << 1) * damagemul; A_FaceTarget (self); - angle = self->angle + (pr_m_punch.Random2() << 18); + angle = self->Angles.Yaw + pr_m_punch.Random2() * (5.625 / 256); pitch = P_AimLineAttack (self, angle, MELEERANGE); P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &t); @@ -344,7 +346,7 @@ static void MarinePunch(AActor *self, int damagemul) if (t.linetarget) { S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM); - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; } } @@ -363,17 +365,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch) // //============================================================================ -void P_GunShot2 (AActor *mo, bool accurate, int pitch, PClassActor *pufftype) +void P_GunShot2 (AActor *mo, bool accurate, DAngle pitch, PClassActor *pufftype) { - angle_t angle; + DAngle angle; int damage; damage = 5*(pr_m_gunshot()%3+1); - angle = mo->angle; + angle = mo->Angles.Yaw; if (!accurate) { - angle += pr_m_gunshot.Random2 () << 18; + angle += pr_m_gunshot.Random2() * (5.625 / 256); } P_LineAttack (mo, angle, MISSILERANGE, pitch, damage, NAME_Hitscan, pufftype); @@ -395,7 +397,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FirePistol) S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM); A_FaceTarget (self); - P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE), + P_GunShot2 (self, accurate, P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE), PClass::FindActor(NAME_BulletPuff)); return 0; } @@ -410,14 +412,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun) { PARAM_ACTION_PROLOGUE; - int pitch; + DAngle pitch; if (self->target == NULL) return 0; S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM); A_FaceTarget (self); - pitch = P_AimLineAttack (self, self->angle, MISSILERANGE); + pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); for (int i = 0; i < 7; ++i) { P_GunShot2 (self, false, pitch, PClass::FindActor(NAME_BulletPuff)); @@ -457,21 +459,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2) { PARAM_ACTION_PROLOGUE; - int pitch; + DAngle pitch; if (self->target == NULL) return 0; S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM); A_FaceTarget (self); - pitch = P_AimLineAttack (self, self->angle, MISSILERANGE); + pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); for (int i = 0; i < 20; ++i) { int damage = 5*(pr_m_fireshotgun2()%3+1); - angle_t angle = self->angle + (pr_m_fireshotgun2.Random2() << 19); + DAngle angle = self->Angles.Yaw + pr_m_fireshotgun2.Random2() * (11.25 / 256); P_LineAttack (self, angle, MISSILERANGE, - pitch + (pr_m_fireshotgun2.Random2() * 332063), damage, + pitch + pr_m_fireshotgun2.Random2() * (7.097 / 256), damage, NAME_Hitscan, NAME_BulletPuff); } self->special1 = level.maptime; @@ -494,7 +496,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun) S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM); A_FaceTarget (self); - P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE), + P_GunShot2 (self, accurate, P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE), PClass::FindActor(NAME_BulletPuff)); return 0; } @@ -647,13 +649,11 @@ void AScriptedMarine::SetSprite (PClassActor *source) { // A valid actor class wasn't passed, so use the standard sprite SpriteOverride = sprite = GetClass()->OwnedStates[0].sprite; // Copy the standard scaling - scaleX = GetDefault()->scaleX; - scaleY = GetDefault()->scaleY; + Scale = GetDefault()->Scale; } else { // Use the same sprite and scaling the passed class spawns with SpriteOverride = sprite = GetDefaultByType (source)->SpawnState->sprite; - scaleX = GetDefaultByType(source)->scaleX; - scaleY = GetDefaultByType(source)->scaleY; + Scale = GetDefaultByType(source)->Scale; } } diff --git a/src/g_game.cpp b/src/g_game.cpp index 627853acb..7c31e09c0 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -197,9 +197,9 @@ short consistancy[MAXPLAYERS][BACKUPTICS]; float normforwardmove[2] = {0x19, 0x32}; // [RH] For setting turbo from console float normsidemove[2] = {0x18, 0x28}; // [RH] Ditto -fixed_t forwardmove[2], sidemove[2]; -fixed_t angleturn[4] = {640, 1280, 320, 320}; // + slow turn -fixed_t flyspeed[2] = {1*256, 3*256}; +int forwardmove[2], sidemove[2]; +int angleturn[4] = {640, 1280, 320, 320}; // + slow turn +int flyspeed[2] = {1*256, 3*256}; int lookspeed[2] = {450, 512}; #define SLOWTURNTICS 6 @@ -1182,8 +1182,7 @@ void G_Ticker () } if (players[i].mo) { - DWORD sum = rngsum + players[i].mo->X() + players[i].mo->Y() + players[i].mo->Z() - + players[i].mo->angle + players[i].mo->pitch; + DWORD sum = rngsum + int((players[i].mo->X() + players[i].mo->Y() + players[i].mo->Z())*257) + players[i].mo->Angles.Yaw.BAMs() + players[i].mo->Angles.Pitch.BAMs(); sum ^= players[i].health; consistancy[i][buf] = sum; } @@ -1288,7 +1287,7 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags) p->mo->flags &= ~MF_SHADOW; } p->mo->RenderStyle = p->mo->GetDefault()->RenderStyle; - p->mo->alpha = p->mo->GetDefault()->alpha; + p->mo->Alpha = p->mo->GetDefault()->Alpha; p->extralight = 0; // cancel gun flashes p->fixedcolormap = NOFIXEDCOLORMAP; // cancel ir goggles p->fixedlightlevel = -1; @@ -1423,33 +1422,30 @@ void G_PlayerReborn (int player) bool G_CheckSpot (int playernum, FPlayerStart *mthing) { - fixed_t x; - fixed_t y; - fixed_t z, oldz; + DVector3 spot; + double oldz; int i; if (mthing->type == 0) return false; - x = mthing->x; - y = mthing->y; - z = mthing->z; + spot = mthing->pos; if (!(level.flags & LEVEL_USEPLAYERSTARTZ)) { - z = 0; + spot.Z = 0; } - z += P_PointInSector (x, y)->floorplane.ZatPoint (x, y); + spot.Z += P_PointInSector (spot)->floorplane.ZatPoint (spot); if (!players[playernum].mo) { // first spawn of level, before corpses for (i = 0; i < playernum; i++) - if (players[i].mo && players[i].mo->X() == x && players[i].mo->Y() == y) + if (players[i].mo && players[i].mo->X() == spot.X && players[i].mo->Y() == spot.Y) return false; return true; } oldz = players[playernum].mo->Z(); // [RH] Need to save corpse's z-height - players[playernum].mo->SetZ(z); // [RH] Checks are now full 3-D + players[playernum].mo->SetZ(spot.Z); // [RH] Checks are now full 3-D // killough 4/2/98: fix bug where P_CheckPosition() uses a non-solid // corpse to detect collisions with other players in DM starts @@ -1459,7 +1455,7 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing) // return false; players[playernum].mo->flags |= MF_SOLID; - i = P_CheckPosition(players[playernum].mo, x, y); + i = P_CheckPosition(players[playernum].mo, spot); players[playernum].mo->flags &= ~MF_SOLID; players[playernum].mo->SetZ(oldz); // [RH] Restore corpse's height if (!i) @@ -1476,10 +1472,10 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing) // // [RH] Returns the distance of the closest player to the given mapthing -static fixed_t PlayersRangeFromSpot (FPlayerStart *spot) +static double PlayersRangeFromSpot (FPlayerStart *spot) { - fixed_t closest = INT_MAX; - fixed_t distance; + double closest = INT_MAX; + double distance; int i; for (i = 0; i < MAXPLAYERS; i++) @@ -1487,7 +1483,7 @@ static fixed_t PlayersRangeFromSpot (FPlayerStart *spot) if (!playeringame[i] || !players[i].mo || players[i].health <= 0) continue; - distance = players[i].mo->AproxDistance (spot->x, spot->y); + distance = players[i].mo->Distance2D(spot->pos.X, spot->pos.Y); if (distance < closest) closest = distance; @@ -1499,13 +1495,13 @@ static fixed_t PlayersRangeFromSpot (FPlayerStart *spot) // [RH] Select the deathmatch spawn spot farthest from everyone. static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections) { - fixed_t bestdistance = 0; + double bestdistance = 0; FPlayerStart *bestspot = NULL; unsigned int i; for (i = 0; i < selections; i++) { - fixed_t distance = PlayersRangeFromSpot (&deathmatchstarts[i]); + double distance = PlayersRangeFromSpot (&deathmatchstarts[i]); if (distance > bestdistance) { @@ -1645,8 +1641,8 @@ static void G_QueueBody (AActor *body) const AActor *const defaultActor = body->GetDefault(); const FPlayerSkin &skin = skins[skinidx]; - body->scaleX = Scale(body->scaleX, skin.ScaleX, defaultActor->scaleX); - body->scaleY = Scale(body->scaleY, skin.ScaleY, defaultActor->scaleY); + body->Scale.X *= skin.Scale.X / defaultActor->Scale.X; + body->Scale.Y *= skin.Scale.Y / defaultActor->Scale.Y; } bodyqueslot++; @@ -1933,13 +1929,6 @@ void G_DoLoadGame () BYTE *vars_p = (BYTE *)text; C_ReadCVars (&vars_p); delete[] text; - if (SaveVersion <= 4509) - { - // account for the flag shuffling for making freelook a 3-state option - INTBOOL flag = dmflags & DF_YES_FREELOOK; - dmflags = dmflags & ~DF_YES_FREELOOK; - if (flag) dmflags2 = dmflags2 | DF2_RESPAWN_SUPER; - } } // dearchive all the modifications diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index 80c5d215a..3251e3812 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -41,13 +41,13 @@ void AChickenPlayer::MorphPlayerThink () { return; } - if (!(vel.x | vel.y) && pr_chickenplayerthink () < 160) + if (Vel.X == 0 && Vel.Y == 0 && pr_chickenplayerthink () < 160) { // Twitch view angle - angle += pr_chickenplayerthink.Random2 () << 19; + Angles.Yaw += pr_chickenplayerthink.Random2() * (360. / 256. / 32.); } if ((Z() <= floorz) && (pr_chickenplayerthink() < 32)) { // Jump and noise - vel.z += JumpZ; + Vel.Z += JumpZ; FState * painstate = FindState(NAME_Pain); if (painstate != NULL) SetState (painstate); @@ -105,11 +105,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Feathers) } for (i = 0; i < count; i++) { - mo = Spawn("Feather", self->PosPlusZ(20*FRACUNIT), NO_REPLACE); + mo = Spawn("Feather", self->PosPlusZ(20.), NO_REPLACE); mo->target = self; - mo->vel.x = pr_feathers.Random2() << 8; - mo->vel.y = pr_feathers.Random2() << 8; - mo->vel.z = FRACUNIT + (pr_feathers() << 9); + mo->Vel.X = pr_feathers.Random2() / 256.; + mo->Vel.Y = pr_feathers.Random2() / 256.; + mo->Vel.Z = 1. + pr_feathers() / 128.; mo->SetState (mo->SpawnState + (pr_feathers()&7)); } return 0; @@ -125,8 +125,7 @@ void P_UpdateBeak (AActor *self) { if (self->player != NULL) { - self->player->psprites[ps_weapon].sy = WEAPONTOP + - (self->player->chickenPeck << (FRACBITS-1)); + self->player->psprites[ps_weapon].sy = WEAPONTOP + self->player->chickenPeck / 2; } } @@ -172,9 +171,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; player_t *player; FTranslatedLineTarget t; @@ -184,12 +183,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1) } damage = 1 + (pr_beakatkpl1()&3); - angle = player->mo->angle; + angle = player->mo->Angles.Yaw; slope = P_AimLineAttack (player->mo, angle, MELEERANGE); P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t); if (t.linetarget) { - player->mo->angle = t.angleFromSource; + player->mo->Angles.Yaw = t.angleFromSource; } P_PlayPeck (player->mo); player->chickenPeck = 12; @@ -207,9 +206,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; player_t *player; FTranslatedLineTarget t; @@ -219,12 +218,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2) } damage = pr_beakatkpl2.HitDice (4); - angle = player->mo->angle; + angle = player->mo->Angles.Yaw; slope = P_AimLineAttack (player->mo, angle, MELEERANGE); P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t); if (t.linetarget) { - player->mo->angle = t.angleFromSource; + player->mo->Angles.Yaw = t.angleFromSource; } P_PlayPeck (player->mo); player->chickenPeck = 12; diff --git a/src/g_heretic/a_dsparil.cpp b/src/g_heretic/a_dsparil.cpp index ed2b97321..a978f3097 100644 --- a/src/g_heretic/a_dsparil.cpp +++ b/src/g_heretic/a_dsparil.cpp @@ -67,8 +67,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack) PARAM_ACTION_PROLOGUE; AActor *mo; - fixed_t vz; - angle_t angle; + DAngle angle; if (!self->target) { @@ -86,17 +85,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack) PClassActor *fx = PClass::FindActor("SorcererFX1"); if (self->health > (self->SpawnHealth()/3)*2) { // Spit one fireball - P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx ); + P_SpawnMissileZ (self, self->Z() + 48, self->target, fx ); } else { // Spit three fireballs - mo = P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx); + mo = P_SpawnMissileZ (self, self->Z() + 48, self->target, fx); if (mo != NULL) { - vz = mo->vel.z; - angle = mo->angle; - P_SpawnMissileAngleZ (self, self->Z() + 48*FRACUNIT, fx, angle-ANGLE_1*3, vz); - P_SpawnMissileAngleZ (self, self->Z() + 48*FRACUNIT, fx, angle+ANGLE_1*3, vz); + angle = mo->Angles.Yaw; + P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle - 3, mo->Vel.Z); + P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle + 3, mo->Vel.Z); } if (self->health < self->SpawnHealth()/3) { // Maybe attack again @@ -130,7 +128,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise) mo = Spawn("Sorcerer2", self->Pos(), ALLOW_REPLACE); mo->Translation = self->Translation; mo->SetState (mo->FindState("Rise")); - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; mo->CopyFriendliness (self, true); return 0; } @@ -143,31 +141,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise) void P_DSparilTeleport (AActor *actor) { - fixed_t prevX; - fixed_t prevY; - fixed_t prevZ; + DVector3 prev; AActor *mo; AActor *spot; DSpotState *state = DSpotState::GetSpotState(); if (state == NULL) return; - spot = state->GetSpotWithMinMaxDistance(PClass::FindClass("BossSpot"), actor->X(), actor->Y(), 128*FRACUNIT, 0); + spot = state->GetSpotWithMinMaxDistance(PClass::FindClass("BossSpot"), actor->X(), actor->Y(), 128, 0); if (spot == NULL) return; - prevX = actor->X(); - prevY = actor->Y(); - prevZ = actor->Z(); + prev = actor->Pos(); if (P_TeleportMove (actor, spot->Pos(), false)) { - mo = Spawn("Sorcerer2Telefade", prevX, prevY, prevZ, ALLOW_REPLACE); + mo = Spawn("Sorcerer2Telefade", prev, ALLOW_REPLACE); if (mo) mo->Translation = actor->Translation; S_Sound (mo, CHAN_BODY, "misc/teleport", 1, ATTN_NORM); actor->SetState (actor->FindState("Teleport")); S_Sound (actor, CHAN_BODY, "misc/teleport", 1, ATTN_NORM); - actor->SetZ(actor->floorz, false); - actor->angle = spot->angle; - actor->vel.x = actor->vel.y = actor->vel.z = 0; + actor->SetZ(actor->floorz); + actor->Angles.Yaw = spot->Angles.Yaw; + actor->Vel.Zero(); } } @@ -230,8 +224,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack) PClassActor *fx = PClass::FindActor("Sorcerer2FX2"); if (fx) { - P_SpawnMissileAngle (self, fx, self->angle-ANG45, FRACUNIT/2); - P_SpawnMissileAngle (self, fx, self->angle+ANG45, FRACUNIT/2); + P_SpawnMissileAngle(self, fx, self->Angles.Yaw - 45, 0.5); + P_SpawnMissileAngle(self, fx, self->Angles.Yaw + 45, 0.5); } } else @@ -257,9 +251,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark) for (i = 0; i < 2; i++) { mo = Spawn("Sorcerer2FXSpark", self->Pos(), ALLOW_REPLACE); - mo->vel.x = pr_bluespark.Random2() << 9; - mo->vel.y = pr_bluespark.Random2() << 9; - mo->vel.z = FRACUNIT + (pr_bluespark()<<8); + mo->Vel.X = pr_bluespark.Random2() / 128.; + mo->Vel.Y = pr_bluespark.Random2() / 128.; + mo->Vel.Z = 1. + pr_bluespark() / 256.; } return 0; } @@ -279,7 +273,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard) mo = Spawn("Wizard", self->Pos(), ALLOW_REPLACE); if (mo != NULL) { - mo->AddZ(-mo->GetDefault()->height / 2, false); + mo->AddZ(-mo->GetDefault()->Height / 2, false); if (!P_TestMobjLocation (mo)) { // Didn't fit mo->ClearCounters(); @@ -289,7 +283,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard) { // [RH] Make the new wizards inherit D'Sparil's target mo->CopyFriendliness (self->target, true); - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); self->SetState (self->FindState(NAME_Death)); self->flags &= ~MF_MISSILE; mo->master = self->target; diff --git a/src/g_heretic/a_hereticartifacts.cpp b/src/g_heretic/a_hereticartifacts.cpp index 2ed4da34c..518abb44a 100644 --- a/src/g_heretic/a_hereticartifacts.cpp +++ b/src/g_heretic/a_hereticartifacts.cpp @@ -49,12 +49,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb) { PARAM_ACTION_PROLOGUE; - self->AddZ(32*FRACUNIT, false); - self->PrevZ = self->Z(); // no interpolation! + self->AddZ(32, false); self->RenderStyle = STYLE_Add; - self->alpha = FRACUNIT; + self->Alpha = 1.; P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE); - P_CheckSplash(self, 128<angle >> ANGLETOFINESHIFT; AActor *mo = Spawn("ActivatedTimeBomb", - Owner->Vec3Angle(24*FRACUNIT, Owner->angle, - Owner->floorclip), ALLOW_REPLACE); + Owner->Vec3Angle(24., Owner->Angles.Yaw, - Owner->Floorclip), ALLOW_REPLACE); mo->target = Owner; return true; } diff --git a/src/g_heretic/a_hereticimp.cpp b/src/g_heretic/a_hereticimp.cpp index d2d40bed4..81185c0c1 100644 --- a/src/g_heretic/a_hereticimp.cpp +++ b/src/g_heretic/a_hereticimp.cpp @@ -28,7 +28,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack) self->SetState (self->SeeState); return 0; } - A_SkullAttack(self, 12 * FRACUNIT); + A_SkullAttack(self, 12.); return 0; } @@ -47,14 +47,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode) self->flags &= ~MF_NOGRAVITY; chunk = Spawn("HereticImpChunk1", self->Pos(), ALLOW_REPLACE); - chunk->vel.x = pr_imp.Random2 () << 10; - chunk->vel.y = pr_imp.Random2 () << 10; - chunk->vel.z = 9*FRACUNIT; + chunk->Vel.X = pr_imp.Random2() / 64.; + chunk->Vel.Y = pr_imp.Random2() / 64.; + chunk->Vel.Z = 9; chunk = Spawn("HereticImpChunk2", self->Pos(), ALLOW_REPLACE); - chunk->vel.x = pr_imp.Random2 () << 10; - chunk->vel.y = pr_imp.Random2 () << 10; - chunk->vel.z = 9*FRACUNIT; + chunk->Vel.X = pr_imp.Random2() / 64.; + chunk->Vel.Y = pr_imp.Random2() / 64.; + chunk->Vel.Z = 9; if (self->special1 == 666) { // Extreme death crash self->SetState (self->FindState("XCrash")); diff --git a/src/g_heretic/a_hereticmisc.cpp b/src/g_heretic/a_hereticmisc.cpp index af8431a95..c8a330536 100644 --- a/src/g_heretic/a_hereticmisc.cpp +++ b/src/g_heretic/a_hereticmisc.cpp @@ -59,11 +59,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain) } for (count = chance > 240 ? 2 : 1; count; count--) { - goo = Spawn(gootype, self->PosPlusZ(48*FRACUNIT), ALLOW_REPLACE); + goo = Spawn(gootype, self->PosPlusZ(48.), ALLOW_REPLACE); goo->target = self; - goo->vel.x = pr_podpain.Random2() << 9; - goo->vel.y = pr_podpain.Random2() << 9; - goo->vel.z = FRACUNIT/2 + (pr_podpain() << 9); + goo->Vel.X = pr_podpain.Random2() / 128.; + goo->Vel.Y = pr_podpain.Random2() / 128.; + goo->Vel.Z = 0.5 + pr_podpain() / 128.; } return 0; } @@ -104,23 +104,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod) PARAM_CLASS_OPT(podtype, AActor) { podtype = PClass::FindActor("Pod"); } AActor *mo; - fixed_t x; - fixed_t y; if (self->special1 == MAX_GEN_PODS) { // Too many generated pods return 0; } - x = self->X(); - y = self->Y(); - mo = Spawn(podtype, x, y, ONFLOORZ, ALLOW_REPLACE); - if (!P_CheckPosition (mo, x, y)) + mo = Spawn(podtype, self->PosAtZ(ONFLOORZ), ALLOW_REPLACE); + if (!P_CheckPosition (mo, mo->Pos())) { // Didn't fit mo->Destroy (); return 0; } mo->SetState (mo->FindState("Grow")); - P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT)); + mo->Thrust(pr_makepod() * (360. / 256), 4.5); S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE); self->special1++; // Increment generated pod count mo->master = self; // Link the generator to the pod @@ -139,7 +135,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter) if (++self->health > 35) { - self->vel.z += self->vel.z/2; + self->Vel.Z *= 1.5; } return 0; } @@ -172,19 +168,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast) int i; int count; AActor *blast; - angle_t angle; count = 1 + (pr_blast() % 3); for (i = 0; i < count; i++) { - blast = Spawn("VolcanoBlast", self->PosPlusZ(44*FRACUNIT), ALLOW_REPLACE); + blast = Spawn("VolcanoBlast", self->PosPlusZ(44.), ALLOW_REPLACE); blast->target = self; - angle = pr_blast () << 24; - blast->angle = angle; - angle >>= ANGLETOFINESHIFT; - blast->vel.x = FixedMul (1*FRACUNIT, finecosine[angle]); - blast->vel.y = FixedMul (1*FRACUNIT, finesine[angle]); - blast->vel.z = (FRACUNIT*5/2) + (pr_blast() << 10); + blast->Angles.Yaw = pr_blast() * (360 / 256.); + blast->VelFromAngle(1.); + blast->Vel.Z = 2.5 + pr_blast() / 64.; S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM); P_CheckMissileSpawn (blast, self->radius); } @@ -203,26 +195,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact) unsigned int i; AActor *tiny; - angle_t angle; if (self->Z() <= self->floorz) { self->flags |= MF_NOGRAVITY; - self->gravity = FRACUNIT; - self->AddZ(28*FRACUNIT); - //self->vel.z = 3*FRACUNIT; + self->Gravity = 1; + self->AddZ(28); + //self->Vel.Z = 3; } P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, RADF_HURTSOURCE); for (i = 0; i < 4; i++) { tiny = Spawn("VolcanoTBlast", self->Pos(), ALLOW_REPLACE); tiny->target = self; - angle = i*ANG90; - tiny->angle = angle; - angle >>= ANGLETOFINESHIFT; - tiny->vel.x = FixedMul (FRACUNIT*7/10, finecosine[angle]); - tiny->vel.y = FixedMul (FRACUNIT*7/10, finesine[angle]); - tiny->vel.z = FRACUNIT + (pr_volcimpact() << 9); + tiny->Angles.Yaw = 90.*i; + tiny->VelFromAngle(0.7); + tiny->Vel.Z = 1. + pr_volcimpact() / 128.; P_CheckMissileSpawn (tiny, self->radius); } return 0; diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 814a80bf5..504321061 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -63,8 +63,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; - int slope; + DAngle angle; + DAngle slope; player_t *player; FTranslatedLineTarget t; @@ -86,15 +86,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack) { puff = PClass::FindActor(NAME_BulletPuff); // just to be sure } - angle = self->angle; - angle += pr_sap.Random2() << 18; + angle = self->Angles.Yaw + pr_sap.Random2() * (5.625 / 256); slope = P_AimLineAttack (self, angle, MELEERANGE); P_LineAttack (self, angle, MELEERANGE, slope, damage, NAME_Melee, puff, true, &t); if (t.linetarget) { //S_StartSound(player->mo, sfx_stfhit); // turn to face target - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; } return 0; } @@ -110,7 +109,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; player_t *player; @@ -122,18 +121,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1) AWeapon *weapon = player->ReadyWeapon; if (weapon != NULL) { - if (!weapon->DepleteAmmo (weapon->bAltFire)) + if (!weapon->DepleteAmmo(weapon->bAltFire)) return 0; } - angle_t pitch = P_BulletSlope(self); - damage = 7+(pr_fgw()&7); - angle = self->angle; + DAngle pitch = P_BulletSlope(self); + damage = 7 + (pr_fgw() & 7); + angle = self->Angles.Yaw; if (player->refire) { - angle += pr_fgw.Random2() << 18; + angle += pr_fgw.Random2() * (5.625 / 256); } - P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff1"); - S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM); + P_LineAttack(self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff1"); + S_Sound(self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM); return 0; } @@ -148,9 +147,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2) PARAM_ACTION_PROLOGUE; int i; - angle_t angle; + DAngle angle; int damage; - fixed_t vz; + double vz; player_t *player; if (NULL == (player = self->player)) @@ -164,17 +163,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - angle_t pitch = P_BulletSlope(self); - vz = FixedMul (GetDefaultByName("GoldWandFX2")->Speed, - finetangent[FINEANGLES/4-((signed)pitch>>ANGLETOFINESHIFT)]); - P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle-(ANG45/8), vz); - P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle+(ANG45/8), vz); - angle = self->angle-(ANG45/8); + DAngle pitch = P_BulletSlope(self); + + vz = -GetDefaultByName("GoldWandFX2")->Speed * pitch.TanClamped(); + P_SpawnMissileAngle(self, PClass::FindActor("GoldWandFX2"), self->Angles.Yaw - (45. / 8), vz); + P_SpawnMissileAngle(self, PClass::FindActor("GoldWandFX2"), self->Angles.Yaw + (45. / 8), vz); + angle = self->Angles.Yaw - (45. / 8); for(i = 0; i < 5; i++) { damage = 1+(pr_fgw2()&7); P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff2"); - angle += ((ANG45/8)*2)/4; + angle += ((45. / 8) * 2) / 4; } S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM); return 0; @@ -204,8 +203,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL1) return 0; } P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX1")); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/10)); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/10)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw - 4.5); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw + 4.5); return 0; } @@ -233,10 +232,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL2) return 0; } P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2")); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle-(ANG45/10)); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle+(ANG45/10)); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/5)); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/5)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->Angles.Yaw - 4.5); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->Angles.Yaw + 4.5); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw - 9.); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw + 9.); return 0; } @@ -250,11 +249,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle Angle; int damage; - int slope; + DAngle slope; int randVal; - fixed_t dist; + double dist; player_t *player; PClassActor *pufftype; FTranslatedLineTarget t; @@ -273,25 +272,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2) * FRACUNIT; - player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3) * FRACUNIT; - angle = self->angle; + player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2); + player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3); + Angle = self->Angles.Yaw; if (power) { damage = pr_gatk.HitDice (2); dist = 4*MELEERANGE; - angle += pr_gatk.Random2() << 17; + Angle += pr_gatk.Random2() * (2.8125 / 256); pufftype = PClass::FindActor("GauntletPuff2"); } else { damage = pr_gatk.HitDice (2); - dist = MELEERANGE+1; - angle += pr_gatk.Random2() << 18; + dist = SAWRANGE; + Angle += pr_gatk.Random2() * (5.625 / 256); pufftype = PClass::FindActor("GauntletPuff1"); } - slope = P_AimLineAttack (self, angle, dist); - P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage); + slope = P_AimLineAttack (self, Angle, dist); + P_LineAttack (self, Angle, dist, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage); if (!t.linetarget) { if (pr_gatk() > 64) @@ -324,20 +323,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) S_Sound (self, CHAN_AUTO, "weapons/gauntletshit", 1, ATTN_NORM); } // turn to face target - angle = t.angleFromSource; - if (angle-self->angle > ANG180) + DAngle angle = t.angleFromSource; + DAngle anglediff = deltaangle(self->Angles.Yaw, angle); + + if (anglediff < 0.0) { - if ((int)(angle-self->angle) < -ANG90/20) - self->angle = angle+ANG90/21; + if (anglediff < -4.5) + self->Angles.Yaw = angle + 90.0 / 21; else - self->angle -= ANG90/20; + self->Angles.Yaw -= 4.5; } else { - if (angle-self->angle > ANG90/20) - self->angle = angle-ANG90/21; + if (anglediff > 4.5) + self->Angles.Yaw = angle - 90.0 / 21; else - self->angle += ANG90/20; + self->Angles.Yaw += 4.5; } self->flags |= MF_JUSTATTACKED; return 0; @@ -387,7 +388,6 @@ int AMaceFX4::DoSpecialDamage (AActor *target, int damage, FName damagetype) void FireMacePL1B (AActor *actor) { AActor *ball; - angle_t angle; player_t *player; if (NULL == (player = actor->player)) @@ -401,16 +401,13 @@ void FireMacePL1B (AActor *actor) if (!weapon->DepleteAmmo (weapon->bAltFire)) return; } - ball = Spawn("MaceFX2", actor->PosPlusZ(28*FRACUNIT - actor->floorclip), ALLOW_REPLACE); - ball->vel.z = 2*FRACUNIT+/*((player->lookdir)<<(FRACBITS-5))*/ - finetangent[FINEANGLES/4-(actor->pitch>>ANGLETOFINESHIFT)]; - angle = actor->angle; + ball = Spawn("MaceFX2", actor->PosPlusZ(28 - actor->Floorclip), ALLOW_REPLACE); + ball->Vel.Z = 2 - player->mo->Angles.Pitch.TanClamped(); ball->target = actor; - ball->angle = angle; - ball->AddZ(2*finetangent[FINEANGLES/4-(actor->pitch>>ANGLETOFINESHIFT)]); - angle >>= ANGLETOFINESHIFT; - ball->vel.x = (actor->vel.x>>1) + FixedMul(ball->Speed, finecosine[angle]); - ball->vel.y = (actor->vel.y>>1) + FixedMul(ball->Speed, finesine[angle]); + ball->Angles.Yaw = actor->Angles.Yaw; + ball->AddZ(ball->Vel.Z); + ball->VelFromAngle(); + ball->Vel += actor->Vel.XY()/2; S_Sound (ball, CHAN_BODY, "weapons/maceshoot", 1, ATTN_NORM); P_CheckMissileSpawn (ball, actor->radius); } @@ -435,19 +432,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1) if (pr_maceatk() < 28) { - FireMacePL1B (self); + FireMacePL1B(self); return 0; } AWeapon *weapon = player->ReadyWeapon; if (weapon != NULL) { - if (!weapon->DepleteAmmo (weapon->bAltFire)) + if (!weapon->DepleteAmmo(weapon->bAltFire)) return 0; } - player->psprites[ps_weapon].sx = ((pr_maceatk()&3)-2)*FRACUNIT; - player->psprites[ps_weapon].sy = WEAPONTOP+(pr_maceatk()&3)*FRACUNIT; - ball = P_SpawnPlayerMissile (self, PClass::FindActor("MaceFX1"), - self->angle+(((pr_maceatk()&7)-4)<<24)); + player->psprites[ps_weapon].sx = ((pr_maceatk() & 3) - 2); + player->psprites[ps_weapon].sy = WEAPONTOP + (pr_maceatk() & 3); + ball = P_SpawnPlayerMissile(self, PClass::FindActor("MaceFX1"), self->Angles.Yaw + (((pr_maceatk() & 7) - 4) * (360. / 256))); if (ball) { ball->special1 = 16; // tics till dropoff @@ -476,21 +472,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check) } self->special1 = 0; self->flags &= ~MF_NOGRAVITY; - self->gravity = FRACUNIT/8; + self->Gravity = 1. / 8;; // [RH] Avoid some precision loss by scaling the velocity directly #if 0 // This is the original code, for reference. - angle_t angle = self->angle>>ANGLETOFINESHIFT; - self->vel.x = FixedMul(7*FRACUNIT, finecosine[angle]); - self->vel.y = FixedMul(7*FRACUNIT, finesine[angle]); + a.ngle_t angle = self->angle>>ANGLETOF.INESHIFT; + self->velx = F.ixedMul(7*F.RACUNIT, f.inecosine[angle]); + self->vely = F.ixedMul(7*F.RACUNIT, f.inesine[angle]); #else - double velscale = sqrt ((double)self->vel.x * (double)self->vel.x + - (double)self->vel.y * (double)self->vel.y); - velscale = 458752 / velscale; - self->vel.x = (int)(self->vel.x * velscale); - self->vel.y = (int)(self->vel.y * velscale); + double velscale = 7 / self->Vel.XY().Length(); + self->Vel.X *= velscale; + self->Vel.Y *= velscale; #endif - self->vel.z -= self->vel.z >> 1; + self->Vel.Z *= 0.5; return 0; } @@ -507,16 +501,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact) if ((self->health != MAGIC_JUNK) && (self->flags & MF_INBOUNCE)) { // Bounce self->health = MAGIC_JUNK; - self->vel.z = (self->vel.z * 192) >> 8; + self->Vel.Z *= 0.75; self->BounceFlags = BOUNCE_None; self->SetState (self->SpawnState); S_Sound (self, CHAN_BODY, "weapons/macebounce", 1, ATTN_NORM); } else { // Explode - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); self->flags |= MF_NOGRAVITY; - self->gravity = FRACUNIT; + self->Gravity = 1; S_Sound (self, CHAN_BODY, "weapons/macehit", 1, ATTN_NORM); } return 0; @@ -533,7 +527,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2) PARAM_ACTION_PROLOGUE; AActor *tiny; - angle_t angle; if ((self->Z() <= self->floorz) && P_HitFloor (self)) { // Landed in some sort of liquid @@ -542,42 +535,36 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2) } if (self->flags & MF_INBOUNCE) { - if (self->vel.z < 2*FRACUNIT) + if (self->Vel.Z < 2) { goto boom; } // Bounce - self->vel.z = (self->vel.z * 192) >> 8; + self->Vel.Z *= 0.75; self->SetState (self->SpawnState); tiny = Spawn("MaceFX3", self->Pos(), ALLOW_REPLACE); - angle = self->angle+ANG90; tiny->target = self->target; - tiny->angle = angle; - angle >>= ANGLETOFINESHIFT; - tiny->vel.x = (self->vel.x>>1) + FixedMul(self->vel.z-FRACUNIT, finecosine[angle]); - tiny->vel.y = (self->vel.y>>1) + FixedMul(self->vel.z-FRACUNIT, finesine[angle]); - tiny->vel.z = self->vel.z; + tiny->Angles.Yaw = self->Angles.Yaw + 90.; + tiny->VelFromAngle(self->Vel.Z - 1.); + tiny->Vel += { self->Vel.X * .5, self->Vel.Y * .5, self->Vel.Z }; P_CheckMissileSpawn (tiny, self->radius); tiny = Spawn("MaceFX3", self->Pos(), ALLOW_REPLACE); - angle = self->angle-ANG90; tiny->target = self->target; - tiny->angle = angle; - angle >>= ANGLETOFINESHIFT; - tiny->vel.x = (self->vel.x>>1) + FixedMul(self->vel.z-FRACUNIT, finecosine[angle]); - tiny->vel.y = (self->vel.y>>1) + FixedMul(self->vel.z-FRACUNIT, finesine[angle]); - tiny->vel.z = self->vel.z; + tiny->Angles.Yaw = self->Angles.Yaw - 90.; + tiny->VelFromAngle(self->Vel.Z - 1.); + tiny->Vel += { self->Vel.X * .5, self->Vel.Y * .5, self->Vel.Z }; P_CheckMissileSpawn (tiny, self->radius); } else { // Explode boom: - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); self->flags |= MF_NOGRAVITY; self->BounceFlags = BOUNCE_None; - self->gravity = FRACUNIT; + self->Gravity = 1; } return 0; } @@ -607,13 +594,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->angle, &t); + mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->Angles.Yaw, &t); if (mo) { - mo->vel.x += self->vel.x; - mo->vel.y += self->vel.y; - mo->vel.z = 2*FRACUNIT+ - clamp(finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)], -5*FRACUNIT, 5*FRACUNIT); + mo->Vel += self->Vel.XY(); + mo->Vel.Z = 2 - player->mo->Angles.Pitch.TanClamped(); if (t.linetarget && !t.unlinked) { mo->tracer = t.linetarget; @@ -635,7 +620,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) int i; AActor *target; - angle_t angle = 0; + DAngle angle = 0.; bool newAngle; FTranslatedLineTarget t; @@ -646,7 +631,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) } if (self->flags & MF_INBOUNCE) { - if (self->vel.z < 2*FRACUNIT) + if (self->Vel.Z < 2) { goto boom; } @@ -668,10 +653,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) } else { // Find new target - angle = 0; + angle = 0.; for (i = 0; i < 16; i++) { - P_AimLineAttack (self, angle, 10*64*FRACUNIT, &t, 0, ALF_NOFRIENDS|ALF_PORTALRESTRICT, NULL, self->target); + P_AimLineAttack (self, angle, 640., &t, 0., ALF_NOFRIENDS|ALF_PORTALRESTRICT, NULL, self->target); if (t.linetarget && self->target != t.linetarget) { self->tracer = t.linetarget; @@ -679,15 +664,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) newAngle = true; break; } - angle += ANGLE_45/2; + angle += 22.5; } } if (newAngle) { - self->angle = angle; - angle >>= ANGLETOFINESHIFT; - self->vel.x = FixedMul (self->Speed, finecosine[angle]); - self->vel.y = FixedMul (self->Speed, finesine[angle]); + self->Angles.Yaw = angle; + self->VelFromAngle(); } self->SetState (self->SpawnState); S_Sound (self, CHAN_BODY, "weapons/macestop", 1, ATTN_NORM); @@ -695,9 +678,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) else { // Explode boom: - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); self->flags |= MF_NOGRAVITY; - self->gravity = FRACUNIT; + self->Gravity = 1; S_Sound (self, CHAN_BODY, "weapons/maceexplode", 1, ATTN_NORM); } return 0; @@ -737,7 +720,7 @@ void ABlasterFX1::Effect () { if (pr_bfx1t() < 64) { - Spawn("BlasterSmoke", X(), Y(), MAX (Z() - 8 * FRACUNIT, floorz), ALLOW_REPLACE); + Spawn("BlasterSmoke", PosAtZ(MAX(Z() - 8., floorz)), ALLOW_REPLACE); } } @@ -778,7 +761,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; player_t *player; @@ -793,12 +776,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - angle_t pitch = P_BulletSlope(self); + DAngle pitch = P_BulletSlope(self); damage = pr_fb1.HitDice (4); - angle = self->angle; + angle = self->Angles.Yaw; if (player->refire) { - angle += pr_fb1.Random2() << 18; + angle += pr_fb1.Random2() * (5.625 / 256); } P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "BlasterPuff"); S_Sound (self, CHAN_WEAPON, "weapons/blastershoot", 1, ATTN_NORM); @@ -816,18 +799,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers) PARAM_ACTION_PROLOGUE; unsigned int i; - angle_t angle; + DAngle angle; AActor *ripper; for(i = 0; i < 8; i++) { ripper = Spawn (self->Pos(), ALLOW_REPLACE); - angle = i*ANG45; + angle = i*45.; ripper->target = self->target; - ripper->angle = angle; - angle >>= ANGLETOFINESHIFT; - ripper->vel.x = FixedMul (ripper->Speed, finecosine[angle]); - ripper->vel.y = FixedMul (ripper->Speed, finesine[angle]); + ripper->Angles.Yaw = angle; + ripper->VelFromAngle(); P_CheckMissileSpawn (ripper, self->radius); } return 0; @@ -955,7 +936,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->angle, &t, &MissileActor); + P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->Angles.Yaw, &t, &MissileActor); // Use MissileActor instead of the return value from // P_SpawnPlayerMissile because we need to give info to the mobj // even if it exploded immediately. @@ -1071,10 +1052,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm) { // Fudge rain frequency return 0; } - fixedvec2 pos = self->Vec2Offset( - ((pr_storm()&127) - 64) * FRACUNIT, - ((pr_storm()&127) - 64) * FRACUNIT); - mo = Spawn (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE); + double xo = ((pr_storm() & 127) - 64); + double yo = ((pr_storm() & 127) - 64); + DVector3 pos = self->Vec2OffsetZ(xo, yo, ONCEILINGZ); + mo = Spawn (pos, ALLOW_REPLACE); // We used bouncecount to store the 3D floor index in A_HideInCeiling if (!mo) return 0; if (mo->Sector->PortalGroup != self->Sector->PortalGroup) @@ -1083,19 +1064,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm) mo->Destroy(); return 0; } - fixed_t newz; if (self->bouncecount >= 0 && (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size()) - newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(mo);// - 40 * FRACUNIT; + pos.Z = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(mo); else - newz = self->Sector->ceilingplane.ZatPoint(mo); - int moceiling = P_Find3DFloor(NULL, pos.x, pos.y, newz, false, false, newz); - if (moceiling >= 0) - mo->SetZ(newz - mo->height, false); - mo->Translation = multiplayer ? - TRANSLATION(TRANSLATION_RainPillar,self->special2) : 0; + pos.Z = self->Sector->ceilingplane.ZatPoint(mo); + int moceiling = P_Find3DFloor(NULL, pos, false, false, pos.Z); + if (moceiling >= 0) mo->SetZ(pos.Z - mo->Height); + mo->Translation = multiplayer ? TRANSLATION(TRANSLATION_RainPillar,self->special2) : 0; mo->target = self->target; - mo->vel.x = 1; // Force collision detection - mo->vel.z = -mo->Speed; + mo->Vel.X = MinVel; // Force collision detection + mo->Vel.Z = -mo->Speed; mo->special2 = self->special2; // Transfer player number P_CheckMissileSpawn (mo, self->radius); if (self->special1 != -1 && !S_IsActorPlayingSomething (self, CHAN_BODY, -1)) @@ -1136,21 +1114,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_HideInCeiling) PARAM_ACTION_PROLOGUE; // We use bouncecount to store the 3D floor index - fixed_t foo; - for (unsigned int i=0; i< self->Sector->e->XFloor.ffloors.Size(); i++) + double foo; + for (int i = self->Sector->e->XFloor.ffloors.Size() - 1; i >= 0; i--) { F3DFloor * rover = self->Sector->e->XFloor.ffloors[i]; - if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - - if ((foo = rover->bottom.plane->ZatPoint(self)) >= (self->Top())) + if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; + + if ((foo = rover->bottom.plane->ZatPoint(self)) >= self->Top()) { - self->SetZ(foo + 4*FRACUNIT, false); + self->SetZ(foo + 4, false); self->bouncecount = i; return 0; } } self->bouncecount = -1; - self->SetZ(self->ceilingz + 4*FRACUNIT, false); + self->SetZ(self->ceilingz + 4, false); return 0; } @@ -1237,7 +1215,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; player_t *player; if (NULL == (player = self->player)) @@ -1252,10 +1229,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1) return 0; } P_SpawnPlayerMissile (self, RUNTIME_CLASS(APhoenixFX1)); - angle = self->angle + ANG180; - angle >>= ANGLETOFINESHIFT; - self->vel.x += FixedMul (4*FRACUNIT, finecosine[angle]); - self->vel.y += FixedMul (4*FRACUNIT, finesine[angle]); + self->Thrust(self->Angles.Yaw + 180, 4); return 0; } @@ -1270,22 +1244,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff) PARAM_ACTION_PROLOGUE; AActor *puff; - angle_t angle; + DAngle angle; //[RH] Heretic never sets the target for seeking - //P_SeekerMissile (self, ANGLE_1*5, ANGLE_1*10); + //P_SeekerMissile (self, 5, 10); puff = Spawn("PhoenixPuff", self->Pos(), ALLOW_REPLACE); - angle = self->angle + ANG90; - angle >>= ANGLETOFINESHIFT; - puff->vel.x = FixedMul (FRACUNIT*13/10, finecosine[angle]); - puff->vel.y = FixedMul (FRACUNIT*13/10, finesine[angle]); - puff->vel.z = 0; + angle = self->Angles.Yaw + 90; + puff->Vel = DVector3(angle.ToVector(1.3), 0); + puff = Spawn("PhoenixPuff", self->Pos(), ALLOW_REPLACE); - angle = self->angle - ANG90; - angle >>= ANGLETOFINESHIFT; - puff->vel.x = FixedMul (FRACUNIT*13/10, finecosine[angle]); - puff->vel.y = FixedMul (FRACUNIT*13/10, finesine[angle]); - puff->vel.z = 0; + angle = self->Angles.Yaw - 90; + puff->Vel = DVector3(angle.ToVector(1.3), 0); return 0; } @@ -1323,9 +1292,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) PARAM_ACTION_PROLOGUE; AActor *mo; - angle_t angle; - fixed_t slope; + double slope; FSoundID soundid; player_t *player; APhoenixRod *flamethrower; @@ -1345,20 +1313,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) S_StopSound (self, CHAN_WEAPON); return 0; } - angle = self->angle; - fixed_t xo = (pr_fp2.Random2() << 9); - fixed_t yo = (pr_fp2.Random2() << 9); - fixedvec3 pos = self->Vec3Offset(xo, yo, - 26*FRACUNIT + finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)] - self->floorclip); + slope = -self->Angles.Pitch.TanClamped(); + double xo = pr_fp2.Random2() / 128.; + double yo = pr_fp2.Random2() / 128.; + DVector3 pos = self->Vec3Offset(xo, yo, 26 + slope - self->Floorclip); - slope = finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)] + (FRACUNIT/10); + slope += 0.1; mo = Spawn("PhoenixFX2", pos, ALLOW_REPLACE); mo->target = self; - mo->angle = angle; - mo->vel.x = self->vel.x + FixedMul (mo->Speed, finecosine[angle>>ANGLETOFINESHIFT]); - mo->vel.y = self->vel.y + FixedMul (mo->Speed, finesine[angle>>ANGLETOFINESHIFT]); - mo->vel.z = FixedMul (mo->Speed, slope); + mo->Angles.Yaw = self->Angles.Yaw; + mo->VelFromAngle(); + mo->Vel += self->Vel.XY(); + mo->Vel.Z = mo->Speed * slope; if (!player->refire || !S_IsActorPlayingSomething (self, CHAN_WEAPON, -1)) { S_Sound (self, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM); @@ -1403,7 +1370,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlameEnd) { PARAM_ACTION_PROLOGUE; - self->vel.z += FRACUNIT*3/2; + self->Vel.Z += 1.5; return 0; } @@ -1417,7 +1384,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FloatPuff) { PARAM_ACTION_PROLOGUE; - self->vel.z += FRACUNIT*18/10; + self->Vel.Z += 1.8; return 0; } diff --git a/src/g_heretic/a_ironlich.cpp b/src/g_heretic/a_ironlich.cpp index 5c7746e82..7f33fb57a 100644 --- a/src/g_heretic/a_ironlich.cpp +++ b/src/g_heretic/a_ironlich.cpp @@ -30,9 +30,9 @@ int AWhirlwind::DoSpecialDamage (AActor *target, int damage, FName damagetype) if (!(target->flags7 & MF7_DONTTHRUST)) { - target->angle += pr_foo.Random2() << 20; - target->vel.x += pr_foo.Random2() << 10; - target->vel.y += pr_foo.Random2() << 10; + target->Angles.Yaw += pr_foo.Random2() * (360 / 4096.); + target->Vel.X += pr_foo.Random2() / 64.; + target->Vel.Y += pr_foo.Random2() / 64.; } if ((level.time & 16) && !(target->flags2 & MF2_BOSS) && !(target->flags7 & MF7_DONTTHRUST)) @@ -42,10 +42,10 @@ int AWhirlwind::DoSpecialDamage (AActor *target, int damage, FName damagetype) { randVal = 160; } - target->vel.z += randVal << 11; - if (target->vel.z > 12*FRACUNIT) + target->Vel.Z += randVal / 32.; + if (target->Vel.Z > 12) { - target->vel.z = 12*FRACUNIT; + target->Vel.Z = 12; } } if (!(level.time & 7)) @@ -73,7 +73,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) int randAttack; static const int atkResolve1[] = { 50, 150 }; static const int atkResolve2[] = { 150, 200 }; - int dist; // Ice ball (close 20% : far 60%) // Fire column (close 40% : far 20%) @@ -93,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) P_TraceBleed (newdam > 0 ? newdam : damage, target, self); return 0; } - dist = self->AproxDistance (target) > 8*64*FRACUNIT; + int dist = self->Distance2D(target) > 8 * 64; randAttack = pr_atk (); if (randAttack < atkResolve1[dist]) { // Ice ball @@ -114,10 +113,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) S_Sound (self, CHAN_BODY, "ironlich/attack1", 1, ATTN_NORM); } fire->target = baseFire->target; - fire->angle = baseFire->angle; - fire->vel.x = baseFire->vel.x; - fire->vel.y = baseFire->vel.y; - fire->vel.z = baseFire->vel.z; + fire->Angles.Yaw = baseFire->Angles.Yaw; + fire->Vel = baseFire->Vel; fire->Damage = NULL; fire->health = (i+1) * 2; P_CheckMissileSpawn (fire, self->radius); @@ -129,7 +126,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) mo = P_SpawnMissile (self, target, RUNTIME_CLASS(AWhirlwind)); if (mo != NULL) { - mo->AddZ(-32*FRACUNIT, false); + mo->AddZ(-32); mo->tracer = target; mo->health = 20*TICRATE; // Duration S_Sound (self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM); @@ -151,21 +148,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek) self->health -= 3; if (self->health < 0) { - self->vel.x = self->vel.y = self->vel.z = 0; - self->SetState (self->FindState(NAME_Death)); + self->Vel.Zero(); + self->SetState(self->FindState(NAME_Death)); self->flags &= ~MF_MISSILE; return 0; } if ((self->threshold -= 3) < 0) { self->threshold = 58 + (pr_seek() & 31); - S_Sound (self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM); + S_Sound(self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM); } if (self->tracer && self->tracer->flags&MF_SHADOW) { return 0; } - P_SeekerMissile (self, ANGLE_1*10, ANGLE_1*30); + P_SeekerMissile(self, 10, 30); return 0; } @@ -180,19 +177,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact) PARAM_ACTION_PROLOGUE; unsigned int i; - angle_t angle; AActor *shard; for (i = 0; i < 8; i++) { shard = Spawn("HeadFX2", self->Pos(), ALLOW_REPLACE); - angle = i*ANG45; shard->target = self->target; - shard->angle = angle; - angle >>= ANGLETOFINESHIFT; - shard->vel.x = FixedMul (shard->Speed, finecosine[angle]); - shard->vel.y = FixedMul (shard->Speed, finesine[angle]); - shard->vel.z = -FRACUNIT*6/10; + shard->Angles.Yaw = i*45.; + shard->VelFromAngle(); + shard->Vel.Z = -.6; P_CheckMissileSpawn (shard, self->radius); } return 0; @@ -209,7 +202,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow) PARAM_ACTION_PROLOGUE; self->health--; - self->AddZ(9*FRACUNIT); + self->AddZ(9.); if (self->health == 0) { self->Damage = self->GetDefault()->Damage; diff --git a/src/g_heretic/a_knight.cpp b/src/g_heretic/a_knight.cpp index a2b2cc45b..9f42a328a 100644 --- a/src/g_heretic/a_knight.cpp +++ b/src/g_heretic/a_knight.cpp @@ -25,12 +25,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_DripBlood) AActor *mo; - fixed_t xo = (pr_dripblood.Random2() << 11); - fixed_t yo = (pr_dripblood.Random2() << 11); - mo = Spawn ("Blood", self->Vec3Offset(xo, yo, 0), ALLOW_REPLACE); - mo->vel.x = pr_dripblood.Random2 () << 10; - mo->vel.y = pr_dripblood.Random2 () << 10; - mo->gravity = FRACUNIT/8; + double xo = pr_dripblood.Random2() / 32.; + double yo = pr_dripblood.Random2() / 32.; + mo = Spawn ("Blood", self->Vec3Offset(xo, yo, 0.), ALLOW_REPLACE); + mo->Vel.X = pr_dripblood.Random2 () / 64.; + mo->Vel.Y = pr_dripblood.Random2() / 64.; + mo->Gravity = 1./8; return 0; } @@ -60,11 +60,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack) S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM); if (self->flags & MF_SHADOW || pr_knightatk () < 40) { // Red axe - P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindActor("RedAxe")); + P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("RedAxe")); return 0; } // Green axe - P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindActor("KnightAxe")); + P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("KnightAxe")); return 0; } diff --git a/src/g_heretic/a_wizard.cpp b/src/g_heretic/a_wizard.cpp index 7a92a1155..704488f16 100644 --- a/src/g_heretic/a_wizard.cpp +++ b/src/g_heretic/a_wizard.cpp @@ -53,7 +53,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk2) PARAM_ACTION_PROLOGUE; A_FaceTarget (self); - self->alpha = HR_SHADOW; + self->Alpha = HR_SHADOW; self->RenderStyle = STYLE_Translucent; self->flags3 |= MF3_GHOST; return 0; @@ -88,8 +88,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3) mo = P_SpawnMissile (self, self->target, fx); if (mo != NULL) { - P_SpawnMissileAngle(self, fx, mo->angle-(ANG45/8), mo->vel.z); - P_SpawnMissileAngle(self, fx, mo->angle+(ANG45/8), mo->vel.z); + P_SpawnMissileAngle(self, fx, mo->Angles.Yaw - 45. / 8, mo->Vel.Z); + P_SpawnMissileAngle(self, fx, mo->Angles.Yaw + 45. / 8, mo->Vel.Z); } return 0; } diff --git a/src/g_hexen/a_bats.cpp b/src/g_hexen/a_bats.cpp index 2bde56340..56c7ac024 100644 --- a/src/g_hexen/a_bats.cpp +++ b/src/g_hexen/a_bats.cpp @@ -39,7 +39,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn) AActor *mo; int delta; - angle_t angle; + DAngle angle; // Countdown until next spawn if (self->special1-- > 0) return 0; @@ -47,7 +47,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn) delta = self->args[1]; if (delta==0) delta=1; - angle = self->angle + (((pr_batspawn()%delta)-(delta>>1))<<24); + + angle = self->Angles.Yaw + (((pr_batspawn() % delta) - (delta >> 1)) * (360 / 256.)); + mo = P_SpawnMissileAngle (self, PClass::FindActor("Bat"), angle, 0); if (mo) { @@ -64,7 +66,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove) { PARAM_ACTION_PROLOGUE; - angle_t newangle; + DAngle newangle; if (self->special2 < 0) { @@ -74,17 +76,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove) if (pr_batmove()<128) { - newangle = self->angle + ANGLE_1*self->args[4]; + newangle = self->Angles.Yaw + self->args[4]; } else { - newangle = self->angle - ANGLE_1*self->args[4]; + newangle = self->Angles.Yaw - self->args[4]; } // Adjust velocity vector to new direction - newangle >>= ANGLETOFINESHIFT; - self->vel.x = FixedMul (self->Speed, finecosine[newangle]); - self->vel.y = FixedMul (self->Speed, finesine[newangle]); + self->VelFromAngle(newangle, self->Speed); if (pr_batmove()<15) { @@ -92,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove) } // Handle Z movement - self->SetZ(self->target->Z() + 16*finesine[self->args[0] << BOBTOFINESHIFT]); + self->SetZ(self->target->Z() + 2 * BobSin(self->args[0])); self->args[0] = (self->args[0]+3)&63; return 0; } diff --git a/src/g_hexen/a_bishop.cpp b/src/g_hexen/a_bishop.cpp index 649e5b273..5fb95d8be 100644 --- a/src/g_hexen/a_bishop.cpp +++ b/src/g_hexen/a_bishop.cpp @@ -80,7 +80,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave) { PARAM_ACTION_PROLOGUE; - A_Weave(self, 2, 2, 2*FRACUNIT, FRACUNIT); + A_Weave(self, 2, 2, 2., 1.); return 0; } @@ -118,15 +118,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur) self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs if (pr_doblur() < 120) { - P_ThrustMobj (self, self->angle + ANG90, 11*FRACUNIT); + self->Thrust(self->Angles.Yaw + 90, 11); } else if (pr_doblur() > 125) { - P_ThrustMobj (self, self->angle - ANG90, 11*FRACUNIT); + self->Thrust(self->Angles.Yaw - 90, 11); } else { // Thrust forward - P_ThrustMobj (self, self->angle, 11*FRACUNIT); + self->Thrust(11); } S_Sound (self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM); return 0; @@ -146,8 +146,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur) if (!--self->special1) { - self->vel.x = 0; - self->vel.y = 0; + self->Vel.X = self->Vel.Y = 0; if (pr_sblur() > 96) { self->SetState (self->SeeState); @@ -160,7 +159,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur) mo = Spawn ("BishopBlur", self->Pos(), ALLOW_REPLACE); if (mo) { - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; } return 0; } @@ -175,9 +174,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopChase) { PARAM_ACTION_PROLOGUE; - fixed_t newz = self->Z() - finesine[self->special2 << BOBTOFINESHIFT] * 4; + double newz = self->Z() - BobSin(self->special2) / 2.; self->special2 = (self->special2 + 4) & 63; - newz += finesine[self->special2 << BOBTOFINESHIFT] * 4; + newz += BobSin(self->special2) / 2.; self->SetZ(newz); return 0; } @@ -194,10 +193,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff) AActor *mo; - mo = Spawn ("BishopPuff", self->PosPlusZ(40*FRACUNIT), ALLOW_REPLACE); + mo = Spawn ("BishopPuff", self->PosPlusZ(40.), ALLOW_REPLACE); if (mo) { - mo->vel.z = FRACUNIT/2; + mo->Vel.Z = -.5; } return 0; } @@ -219,13 +218,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur) self->SetState (self->FindState ("Blur")); return 0; } - fixed_t xo = (pr_pain.Random2() << 12); - fixed_t yo = (pr_pain.Random2() << 12); - fixed_t zo = (pr_pain.Random2() << 11); + double xo = pr_pain.Random2() / 16.; + double yo = pr_pain.Random2() / 16.; + double zo = pr_pain.Random2() / 32.; mo = Spawn ("BishopPainBlur", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; } return 0; } diff --git a/src/g_hexen/a_blastradius.cpp b/src/g_hexen/a_blastradius.cpp index 541b6bfac..58ff083ac 100644 --- a/src/g_hexen/a_blastradius.cpp +++ b/src/g_hexen/a_blastradius.cpp @@ -9,8 +9,8 @@ */ /* For reference, the default values: -#define BLAST_RADIUS_DIST 255*FRACUNIT -#define BLAST_SPEED 20*FRACUNIT +#define BLAST_RADIUS_DIST 255*F.RACUNIT +#define BLAST_SPEED 20*F.RACUNIT #define BLAST_FULLSTRENGTH 255 */ @@ -22,11 +22,11 @@ // //========================================================================== -void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor *Owner, PClassActor *blasteffect, bool dontdamage) +void BlastActor (AActor *victim, double strength, double speed, AActor *Owner, PClassActor *blasteffect, bool dontdamage) { - angle_t angle,ang; + DAngle angle; AActor *mo; - fixedvec3 pos; + DVector3 pos; if (!victim->SpecialBlastHandling (Owner, strength)) { @@ -34,35 +34,33 @@ void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor *Owner, } angle = Owner->AngleTo(victim); - angle >>= ANGLETOFINESHIFT; - victim->vel.x = FixedMul (speed, finecosine[angle]); - victim->vel.y = FixedMul (speed, finesine[angle]); + DVector2 move = angle.ToVector(speed); + victim->Vel.X = move.X; + victim->Vel.Y = move.Y; // Spawn blast puff - ang = victim->AngleTo(Owner); - ang >>= ANGLETOFINESHIFT; + angle -= 180.; pos = victim->Vec3Offset( - FixedMul (victim->radius+FRACUNIT, finecosine[ang]), - FixedMul (victim->radius+FRACUNIT, finesine[ang]), - -victim->floorclip + (victim->height>>1)); + (victim->radius + 1) * angle.Cos(), + (victim->radius + 1) * angle.Sin(), + (victim->Height / 2) - victim->Floorclip); mo = Spawn (blasteffect, pos, ALLOW_REPLACE); if (mo) { - mo->vel.x = victim->vel.x; - mo->vel.y = victim->vel.y; + mo->Vel.X = victim->Vel.X; + mo->Vel.Y = victim->Vel.Y; } if (victim->flags & MF_MISSILE) { // [RH] Floor and ceiling huggers should not be blasted vertically. if (!(victim->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { - victim->vel.z = 8*FRACUNIT; - mo->vel.z = victim->vel.z; + mo->Vel.Z = victim->Vel.Z = 8; } } else { - victim->vel.z = (1000 / victim->Mass) << FRACBITS; + victim->Vel.Z = 1000. / victim->Mass; } if (victim->player) { @@ -99,15 +97,14 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast) { PARAM_ACTION_PROLOGUE; PARAM_INT_OPT (blastflags) { blastflags = 0; } - PARAM_FIXED_OPT (strength) { strength = 255*FRACUNIT; } - PARAM_FIXED_OPT (radius) { radius = 255*FRACUNIT; } - PARAM_FIXED_OPT (speed) { speed = 20*FRACUNIT; } + PARAM_FLOAT_OPT (strength) { strength = 255; } + PARAM_FLOAT_OPT (radius) { radius = 255; } + PARAM_FLOAT_OPT (speed) { speed = 20; } PARAM_CLASS_OPT (blasteffect, AActor) { blasteffect = PClass::FindActor("BlastEffect"); } PARAM_SOUND_OPT (blastsound) { blastsound = "BlastRadius"; } AActor *mo; TThinkerIterator iterator; - fixed_t dist; if (self->player && (blastflags & BF_USEAMMO) && ACTION_CALL_FROM_WEAPON()) { @@ -146,8 +143,7 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast) { // Must be monster, player, missile, touchy or vulnerable continue; } - dist = self->AproxDistance (mo); - if (dist > radius) + if (self->Distance2D(mo) > radius) { // Out of range continue; } diff --git a/src/g_hexen/a_boostarmor.cpp b/src/g_hexen/a_boostarmor.cpp index 2d6bde4e3..3234174f3 100644 --- a/src/g_hexen/a_boostarmor.cpp +++ b/src/g_hexen/a_boostarmor.cpp @@ -29,7 +29,7 @@ bool AArtiBoostArmor::Use (bool pickup) for (int i = 0; i < 4; ++i) { - armor = Spawn (0,0,0, NO_REPLACE); + armor = Spawn(); armor->flags |= MF_DROPPED; armor->health = i; armor->Amount = 1; @@ -46,7 +46,7 @@ bool AArtiBoostArmor::Use (bool pickup) } else { - ABasicArmorBonus *armor = Spawn (0,0,0, NO_REPLACE); + ABasicArmorBonus *armor = Spawn(); armor->flags |= MF_DROPPED; armor->SaveAmount = 50; armor->MaxSaveAmount = 300; diff --git a/src/g_hexen/a_clericflame.cpp b/src/g_hexen/a_clericflame.cpp index 62395d321..5b4eba2e8 100644 --- a/src/g_hexen/a_clericflame.cpp +++ b/src/g_hexen/a_clericflame.cpp @@ -13,9 +13,8 @@ #include "thingdef/thingdef.h" */ -const fixed_t FLAMESPEED = fixed_t(0.45*FRACUNIT); -const fixed_t CFLAMERANGE = 12*64*FRACUNIT; -const fixed_t FLAMEROTSPEED = 2*FRACUNIT; +const double FLAMESPEED = 0.45; +const double FLAMEROTSPEED = 2.; static FRandom pr_missile ("CFlameMissile"); @@ -43,20 +42,18 @@ void ACFlameMissile::BeginPlay () void ACFlameMissile::Effect () { - fixed_t newz; - if (!--special1) { special1 = 4; - newz = Z()-12*FRACUNIT; + double newz = Z() - 12; if (newz < floorz) { newz = floorz; } - AActor *mo = Spawn ("CFlameFloor", X(), Y(), newz, ALLOW_REPLACE); + AActor *mo = Spawn ("CFlameFloor", PosAtZ(newz), ALLOW_REPLACE); if (mo) { - mo->angle = angle; + mo->Angles.Yaw = Angles.Yaw; } } } @@ -99,9 +96,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlamePuff) PARAM_ACTION_PROLOGUE; self->renderflags &= ~RF_INVISIBLE; - self->vel.x = 0; - self->vel.y = 0; - self->vel.z = 0; + self->Vel.Zero(); S_Sound (self, CHAN_BODY, "ClericFlameExplode", 1, ATTN_NORM); return 0; } @@ -117,8 +112,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile) PARAM_ACTION_PROLOGUE; int i; - int an, an90; - fixed_t dist; + DAngle an; + double dist; AActor *mo; self->renderflags &= ~RF_INVISIBLE; @@ -126,33 +121,28 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile) AActor *BlockingMobj = self->BlockingMobj; if (BlockingMobj && BlockingMobj->flags&MF_SHOOTABLE) { // Hit something, so spawn the flame circle around the thing - dist = BlockingMobj->radius+18*FRACUNIT; + dist = BlockingMobj->radius + 18; for (i = 0; i < 4; i++) { - an = (i*ANG45)>>ANGLETOFINESHIFT; - an90 = (i*ANG45+ANG90)>>ANGLETOFINESHIFT; - mo = Spawn ("CircleFlame", BlockingMobj->Vec3Offset( - FixedMul(dist, finecosine[an]), - FixedMul(dist, finesine[an]), - 5*FRACUNIT), ALLOW_REPLACE); + an = i*45.; + mo = Spawn ("CircleFlame", BlockingMobj->Vec3Angle(dist, an, 5), ALLOW_REPLACE); if (mo) { - mo->angle = an<Angles.Yaw = an; mo->target = self->target; - mo->vel.x = mo->special1 = FixedMul(FLAMESPEED, finecosine[an]); - mo->vel.y = mo->special2 = FixedMul(FLAMESPEED, finesine[an]); + mo->VelFromAngle(FLAMESPEED); + mo->specialf1 = mo->Vel.X; + mo->specialf2 = mo->Vel.Y; mo->tics -= pr_missile()&3; } - mo = Spawn ("CircleFlame", BlockingMobj->Vec3Offset( - -FixedMul(dist, finecosine[an]), - -FixedMul(dist, finesine[an]), - 5*FRACUNIT), ALLOW_REPLACE); + mo = Spawn("CircleFlame", BlockingMobj->Vec3Angle(dist, an, 5), ALLOW_REPLACE); if(mo) { - mo->angle = ANG180+(an<Angles.Yaw = an + 180.; mo->target = self->target; - mo->vel.x = mo->special1 = FixedMul(-FLAMESPEED, finecosine[an]); - mo->vel.y = mo->special2 = FixedMul(-FLAMESPEED, finesine[an]); + mo->VelFromAngle(-FLAMESPEED); + mo->specialf1 = mo->Vel.X; + mo->specialf2 = mo->Vel.Y; mo->tics -= pr_missile()&3; } } @@ -171,11 +161,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameRotate) { PARAM_ACTION_PROLOGUE; - int an; + DAngle an = self->Angles.Yaw + 90.; + self->VelFromAngle(an, FLAMEROTSPEED); + self->Vel += DVector2(self->specialf1, self->specialf2); - an = (self->angle+ANG90)>>ANGLETOFINESHIFT; - self->vel.x = self->special1+FixedMul(FLAMEROTSPEED, finecosine[an]); - self->vel.y = self->special2+FixedMul(FLAMEROTSPEED, finesine[an]); - self->angle += ANG90/15; + self->Angles.Yaw += 6.; return 0; } diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp index fe71289ac..749ad3dad 100644 --- a/src/g_hexen/a_clericholy.cpp +++ b/src/g_hexen/a_clericholy.cpp @@ -63,7 +63,7 @@ IMPLEMENT_CLASS (ACWeapWraithverge) IMPLEMENT_CLASS (AHolySpirit) -bool AHolySpirit::Slam (AActor *thing) +bool AHolySpirit::Slam(AActor *thing) { if (thing->flags&MF_SHOOTABLE && thing != target) { @@ -91,14 +91,14 @@ bool AHolySpirit::Slam (AActor *thing) // ghost burns out faster when attacking players/bosses health -= 6; } - P_DamageMobj (thing, this, target, dam, NAME_Melee); + P_DamageMobj(thing, this, target, dam, NAME_Melee); if (pr_spiritslam() < 128) { - Spawn ("HolyPuff", Pos(), ALLOW_REPLACE); - S_Sound (this, CHAN_WEAPON, "SpiritAttack", 1, ATTN_NORM); + Spawn("HolyPuff", Pos(), ALLOW_REPLACE); + S_Sound(this, CHAN_WEAPON, "SpiritAttack", 1, ATTN_NORM); if (thing->flags3&MF3_ISMONSTER && pr_spiritslam() < 128) { - thing->Howl (); + thing->Howl(); } } } @@ -110,7 +110,7 @@ bool AHolySpirit::Slam (AActor *thing) return true; } -bool AHolySpirit::SpecialBlastHandling (AActor *source, fixed_t strength) +bool AHolySpirit::SpecialBlastHandling (AActor *source, double strength) { if (tracer == source) { @@ -133,7 +133,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2) PARAM_ACTION_PROLOGUE; int j; - int i; AActor *mo; for (j = 0; j < 4; j++) @@ -145,23 +144,24 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2) } switch (j) { // float bob index + case 0: - mo->special2 = pr_holyatk2(8 << BOBTOFINESHIFT); // upper-left + mo->WeaveIndexZ = pr_holyatk2() & 7; // upper-left break; case 1: - mo->special2 = FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT); // upper-right + mo->WeaveIndexZ = 32 + (pr_holyatk2() & 7); // upper-right break; case 2: - mo->special2 = (FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT)) << 16; // lower-left + mo->WeaveIndexXY = 32 + (pr_holyatk2() & 7); // lower-left break; case 3: - i = pr_holyatk2(8 << BOBTOFINESHIFT); - mo->special2 = ((FINEANGLES/2 + i) << 16) + FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT); + mo->WeaveIndexXY = 32 + (pr_holyatk2() & 7); + mo->WeaveIndexZ = 32 + (pr_holyatk2() & 7); break; } mo->SetZ(self->Z()); - mo->angle = self->angle+(ANGLE_45+ANGLE_45/2)-ANGLE_45*j; - P_ThrustMobj(mo, mo->angle, mo->Speed); + mo->Angles.Yaw = self->Angles.Yaw + 67.5 - 45.*j; + mo->Thrust(); mo->target = self->target; mo->args[0] = 10; // initial turn value mo->args[1] = 0; // initial look angle @@ -225,7 +225,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->angle, &t); + AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->Angles.Yaw, &t); if (missile != NULL && !t.unlinked) { missile->tracer = t.linetarget; @@ -263,42 +263,41 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyPalette) // //============================================================================ -static void CHolyTailFollow (AActor *actor, fixed_t dist) +static void CHolyTailFollow(AActor *actor, double dist) { AActor *child; - int an; - fixed_t oldDistance, newDistance; + DAngle an; + double oldDistance, newDistance; while (actor) { child = actor->tracer; if (child) { - an = actor->AngleTo(child) >> ANGLETOFINESHIFT; - oldDistance = child->AproxDistance (actor); - if (P_TryMove (child, actor->X()+FixedMul(dist, finecosine[an]), - actor->Y()+FixedMul(dist, finesine[an]), true)) + an = actor->AngleTo(child); + oldDistance = child->Distance2D(actor); + if (P_TryMove(child, actor->Pos().XY() + an.ToVector(dist), true)) { - newDistance = child->AproxDistance (actor)-FRACUNIT; - if (oldDistance < FRACUNIT) + newDistance = child->Distance2D(actor) - 1; + if (oldDistance < 1) { if (child->Z() < actor->Z()) { - child->SetZ(actor->Z()-dist); + child->SetZ(actor->Z() - dist); } else { - child->SetZ(actor->Z()+dist); + child->SetZ(actor->Z() + dist); } } else { - child->SetZ(actor->Z() + Scale (newDistance, child->Z()-actor->Z(), oldDistance)); + child->SetZ(actor->Z() + (newDistance * (child->Z() - actor->Z()) / oldDistance)); } } } actor = child; - dist -= FRACUNIT; + dist -= 1; } } @@ -341,13 +340,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyTail) } else { - if (P_TryMove (self, - parent->X() - 14*finecosine[parent->angle>>ANGLETOFINESHIFT], - parent->Y() - 14*finesine[parent->angle>>ANGLETOFINESHIFT], true)) + if (P_TryMove(self, parent->Vec2Angle(14., parent->Angles.Yaw, true), true)) { - self->SetZ(parent->Z()-5*FRACUNIT); + self->SetZ(parent->Z() - 5.); } - CHolyTailFollow (self, 10*FRACUNIT); + CHolyTailFollow(self, 10); } return 0; } @@ -377,34 +374,32 @@ static void CHolyFindTarget (AActor *actor) // Similar to P_SeekerMissile, but seeks to a random Z on the target //============================================================================ -static void CHolySeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax) +static void CHolySeekerMissile (AActor *actor, DAngle thresh, DAngle turnMax) { int dir; - int dist; - angle_t delta; - angle_t angle; + DAngle delta; AActor *target; - fixed_t newZ; - fixed_t deltaZ; + double newZ; + double deltaZ; target = actor->tracer; if (target == NULL) { return; } - if(!(target->flags&MF_SHOOTABLE) - || (!(target->flags3&MF3_ISMONSTER) && !target->player)) + if (!(target->flags&MF_SHOOTABLE) + || (!(target->flags3&MF3_ISMONSTER) && !target->player)) { // Target died/target isn't a player or creature actor->tracer = NULL; - actor->flags &= ~(MF_NOCLIP|MF_SKULLFLY); + actor->flags &= ~(MF_NOCLIP | MF_SKULLFLY); actor->flags |= MF_MISSILE; - CHolyFindTarget (actor); + CHolyFindTarget(actor); return; } dir = P_FaceMobj (actor, target, &delta); if (delta > thresh) { - delta >>= 1; + delta /= 2; if (delta > turnMax) { delta = turnMax; @@ -412,72 +407,36 @@ static void CHolySeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax) } if (dir) { // Turn clockwise - actor->angle += delta; + actor->Angles.Yaw += delta; } else { // Turn counter clockwise - actor->angle -= delta; + actor->Angles.Yaw -= delta; } - angle = actor->angle>>ANGLETOFINESHIFT; - actor->vel.x = FixedMul (actor->Speed, finecosine[angle]); - actor->vel.y = FixedMul (actor->Speed, finesine[angle]); + actor->VelFromAngle(); + if (!(level.time&15) || actor->Z() > target->Top() || actor->Top() < target->Z()) { - newZ = target->Z()+((pr_holyseeker()*target->height)>>8); + newZ = target->Z() + ((pr_holyseeker()*target->Height) / 256.); deltaZ = newZ - actor->Z(); - if (abs(deltaZ) > 15*FRACUNIT) + if (fabs(deltaZ) > 15) { if (deltaZ > 0) { - deltaZ = 15*FRACUNIT; + deltaZ = 15; } else { - deltaZ = -15*FRACUNIT; + deltaZ = -15; } } - dist = actor->AproxDistance (target); - dist = dist / actor->Speed; - if (dist < 1) - { - dist = 1; - } - actor->vel.z = deltaZ / dist; + actor->Vel.Z = deltaZ / actor->DistanceBySpeed(target, actor->Speed); } return; } -//============================================================================ -// -// A_CHolyWeave -// -//============================================================================ - -void CHolyWeave (AActor *actor, FRandom &pr_random) -{ - fixed_t newX, newY, newZ; - int weaveXY, weaveZ; - int angle; - - weaveXY = actor->special2 >> 16; - weaveZ = actor->special2 & FINEMASK; - angle = (actor->angle + ANG90) >> ANGLETOFINESHIFT; - newX = actor->X() - FixedMul(finecosine[angle], finesine[weaveXY] * 32); - newY = actor->Y() - FixedMul(finesine[angle], finesine[weaveXY] * 32); - weaveXY = (weaveXY + pr_random(5 << BOBTOFINESHIFT)) & FINEMASK; - newX += FixedMul(finecosine[angle], finesine[weaveXY] * 32); - newY += FixedMul(finesine[angle], finesine[weaveXY] * 32); - P_TryMove(actor, newX, newY, true); - newZ = actor->Z(); - newZ -= finesine[weaveZ] * 16; - weaveZ = (weaveZ + pr_random(5 << BOBTOFINESHIFT)) & FINEMASK; - newZ += finesine[weaveZ] * 16; - actor->SetZ(newZ); - actor->special2 = weaveZ + (weaveXY << 16); -} - //============================================================================ // // A_CHolySeek @@ -491,23 +450,25 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek) self->health--; if (self->health <= 0) { - self->vel.x >>= 2; - self->vel.y >>= 2; - self->vel.z = 0; + self->Vel.X /= 4; + self->Vel.Y /= 4; + self->Vel.Z = 0; self->SetState (self->FindState(NAME_Death)); self->tics -= pr_holyseek()&3; return 0; } if (self->tracer) { - CHolySeekerMissile (self, self->args[0]*ANGLE_1, - self->args[0]*ANGLE_1*2); + CHolySeekerMissile (self, (double)self->args[0], self->args[0]*2.); if (!((level.time+7)&15)) { self->args[0] = 5+(pr_holyseek()/20); } } - CHolyWeave (self, pr_holyweave); + + int xyspeed = (pr_holyweave() % 5); + int zspeed = (pr_holyweave() % 5); + A_Weave(self, xyspeed, zspeed, 4., 2.); return 0; } @@ -546,7 +507,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClericAttack) if (!self->target) return 0; - AActor * missile = P_SpawnMissileZ (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor ("HolyMissile")); + AActor * missile = P_SpawnMissileZ (self, self->Z() + 40., self->target, PClass::FindActor ("HolyMissile")); if (missile != NULL) missile->tracer = NULL; // No initial target S_Sound (self, CHAN_WEAPON, "HolySymbolFire", 1, ATTN_NORM); return 0; diff --git a/src/g_hexen/a_clericmace.cpp b/src/g_hexen/a_clericmace.cpp index 6b7fe06ae..69f1f729c 100644 --- a/src/g_hexen/a_clericmace.cpp +++ b/src/g_hexen/a_clericmace.cpp @@ -17,9 +17,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; int i; player_t *player; FTranslatedLineTarget t; @@ -36,7 +36,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) { for (int j = 1; j >= -1; j -= 2) { - angle = player->mo->angle + j*i*(ANG45 / 16); + angle = player->mo->Angles.Yaw + j*i*(45. / 16); slope = P_AimLineAttack(player->mo, angle, 2 * MELEERANGE, &t); if (t.linetarget) { @@ -44,7 +44,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) if (t.linetarget != NULL) { AdjustPlayerAngle(player->mo, &t); - goto macedone; + return 0; } } } @@ -52,9 +52,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) // didn't find any creatures, so try to strike any walls player->mo->weaponspecial = 0; - angle = player->mo->angle; + angle = player->mo->Angles.Yaw; slope = P_AimLineAttack (player->mo, angle, MELEERANGE); P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, hammertime); -macedone: return 0; } diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index fcad8f20c..d936e8d1d 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -51,8 +51,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) APlayerPawn *pmo; int damage; int newLife, max; - angle_t angle; - int slope; + DAngle angle; + DAngle slope; int i; player_t *player; FTranslatedLineTarget t; @@ -72,14 +72,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) { for (int j = 1; j >= -1; j -= 2) { - angle = pmo->angle + j*i*(ANG45 / 16); - slope = P_AimLineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), &t, 0, ALF_CHECK3D); + angle = pmo->Angles.Yaw + j*i*(45. / 16); + slope = P_AimLineAttack(pmo, angle, 1.5 * MELEERANGE, &t, 0., ALF_CHECK3D); if (t.linetarget) { - P_LineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &t); + P_LineAttack(pmo, angle, 1.5 * MELEERANGE, slope, damage, NAME_Melee, puff, false, &t); if (t.linetarget != NULL) { - pmo->angle = t.angleFromSource; + pmo->Angles.Yaw = t.angleFromSource; if (((t.linetarget->player && (!t.linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || t.linetarget->flags3&MF3_ISMONSTER) && (!(t.linetarget->flags2&(MF2_DORMANT | MF2_INVULNERABLE)))) { @@ -131,12 +131,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle-(ANG45/15)); + mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->Angles.Yaw - 3.0); if (mo) { mo->WeaveIndexXY = 32; } - mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle+(ANG45/15)); + mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->Angles.Yaw + 3.0); if (mo) { mo->WeaveIndexXY = 0; @@ -155,7 +155,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither) { PARAM_ACTION_PROLOGUE; - A_Weave(self, 3, 0, FRACUNIT, 0); + A_Weave(self, 3, 0, 1., 0.); return 0; } diff --git a/src/g_hexen/a_dragon.cpp b/src/g_hexen/a_dragon.cpp index f9b38268b..c94be3988 100644 --- a/src/g_hexen/a_dragon.cpp +++ b/src/g_hexen/a_dragon.cpp @@ -22,16 +22,15 @@ DECLARE_ACTION(A_DragonFlight) // //============================================================================ -static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) +static void DragonSeek (AActor *actor, DAngle thresh, DAngle turnMax) { int dir; - int dist; - angle_t delta; - angle_t angle; + double dist; + DAngle delta; AActor *target; int i; - angle_t bestAngle; - angle_t angleToSpot, angleToTarget; + DAngle bestAngle; + DAngle angleToSpot, angleToTarget; AActor *mo; target = actor->tracer; @@ -42,7 +41,7 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) dir = P_FaceMobj (actor, target, &delta); if (delta > thresh) { - delta >>= 1; + delta /= 2; if (delta > turnMax) { delta = turnMax; @@ -50,30 +49,25 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) } if (dir) { // Turn clockwise - actor->angle += delta; + actor->Angles.Yaw += delta; } else { // Turn counter clockwise - actor->angle -= delta; + actor->Angles.Yaw -= delta; } - angle = actor->angle>>ANGLETOFINESHIFT; - actor->vel.x = FixedMul (actor->Speed, finecosine[angle]); - actor->vel.y = FixedMul (actor->Speed, finesine[angle]); - dist = actor->AproxDistance (target) / actor->Speed; + actor->VelFromAngle(); + + dist = actor->DistanceBySpeed(target, actor->Speed); if (actor->Top() < target->Z() || target->Top() < actor->Z()) { - if (dist < 1) - { - dist = 1; - } - actor->vel.z = (target->Z() - actor->Z())/dist; + actor->Vel.Z = (target->Z() - actor->Z()) / dist; } if (target->flags&MF_SHOOTABLE && pr_dragonseek() < 64) { // attack the destination mobj if it's attackable AActor *oldTarget; - - if (absangle(actor->angle - actor->AngleTo(target)) < ANGLE_45/2) + + if (absangle(actor->Angles.Yaw, actor->AngleTo(target)) < 22.5) { oldTarget = actor->target; actor->target = target; @@ -97,7 +91,7 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) if (actor->target && pr_dragonseek() < 200) { AActor *bestActor = NULL; - bestAngle = ANGLE_MAX; + bestAngle = 360.; angleToTarget = actor->AngleTo(actor->target); for (i = 0; i < 5; i++) { @@ -112,9 +106,10 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) continue; } angleToSpot = actor->AngleTo(mo); - if (absangle(angleToSpot-angleToTarget) < bestAngle) + DAngle diff = absangle(angleToSpot, angleToTarget); + if (diff < bestAngle) { - bestAngle = absangle(angleToSpot-angleToTarget); + bestAngle = diff; bestActor = mo; } } @@ -182,9 +177,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; - DragonSeek (self, 4*ANGLE_1, 8*ANGLE_1); + DragonSeek (self, 4., 8.); if (self->target) { if(!(self->target->flags&MF_SHOOTABLE)) @@ -192,15 +187,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight) self->target = NULL; return 0; } - angle = self->AngleTo(self->target); - if (absangle(self->angle-angle) < ANGLE_45/2 && self->CheckMeleeRange()) + angle = absangle(self->Angles.Yaw, self->AngleTo(self->target)); + if (angle <22.5 && self->CheckMeleeRange()) { int damage = pr_dragonflight.HitDice (8); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); } - else if (absangle(self->angle-angle) <= ANGLE_1*20) + else if (angle <= 20) { self->SetState (self->MissileState); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); @@ -266,9 +261,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2) delay = 16+(pr_dragonfx2()>>3); for (i = 1+(pr_dragonfx2()&3); i; i--) { - fixed_t xo = ((pr_dragonfx2() - 128) << 14); - fixed_t yo = ((pr_dragonfx2() - 128) << 14); - fixed_t zo = ((pr_dragonfx2() - 128) << 12); + double xo = (pr_dragonfx2() - 128) / 4.; + double yo = (pr_dragonfx2() - 128) / 4.; + double zo = (pr_dragonfx2() - 128) / 16.; mo = Spawn ("DragonExplosion", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) diff --git a/src/g_hexen/a_fighteraxe.cpp b/src/g_hexen/a_fighteraxe.cpp index aa6a6ec5c..c83726b44 100644 --- a/src/g_hexen/a_fighteraxe.cpp +++ b/src/g_hexen/a_fighteraxe.cpp @@ -13,7 +13,7 @@ #include "thingdef/thingdef.h" */ -#define AXERANGE ((fixed_t)(2.25*MELEERANGE)) +#define AXERANGE (2.25 * MELEERANGE) static FRandom pr_axeatk ("FAxeAtk"); @@ -199,10 +199,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; - fixed_t power; + DAngle angle; + int power; int damage; - int slope; + DAngle slope; int i; int useMana; player_t *player; @@ -223,7 +223,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) if (player->ReadyWeapon->Ammo1->Amount > 0) { damage <<= 1; - power = 6*FRACUNIT; + power = 6; pufftype = PClass::FindActor ("AxePuffGlow"); useMana = 1; } @@ -236,7 +236,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) { for (int j = 1; j >= -1; j -= 2) { - angle = pmo->angle + j*i*(ANG45 / 16); + angle = pmo->Angles.Yaw + j*i*(45. / 16); slope = P_AimLineAttack(pmo, angle, AXERANGE, &t); if (t.linetarget) { @@ -245,7 +245,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) { if (t.linetarget->flags3&MF3_ISMONSTER || t.linetarget->player) { - P_ThrustMobj(t.linetarget, t.angleFromSource, power); + t.linetarget->Thrust(t.angleFromSource, power); } AdjustPlayerAngle(pmo, &t); useMana++; @@ -257,7 +257,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) // didn't find any creatures, so try to strike any walls pmo->weaponspecial = 0; - angle = pmo->angle; + angle = pmo->Angles.Yaw; slope = P_AimLineAttack (pmo, angle, MELEERANGE); P_LineAttack (pmo, angle, MELEERANGE, slope, damage, NAME_Melee, pufftype, true); diff --git a/src/g_hexen/a_fighterhammer.cpp b/src/g_hexen/a_fighterhammer.cpp index eadf7a05c..c33737bfd 100644 --- a/src/g_hexen/a_fighterhammer.cpp +++ b/src/g_hexen/a_fighterhammer.cpp @@ -13,7 +13,7 @@ #include "thingdef/thingdef.h" */ -const fixed_t HAMMER_RANGE = MELEERANGE+MELEERANGE/2; +const double HAMMER_RANGE = 1.5 * MELEERANGE; static FRandom pr_hammeratk ("FHammerAtk"); @@ -27,10 +27,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - fixed_t power; - int slope; + DAngle slope; int i; player_t *player; FTranslatedLineTarget t; @@ -43,46 +42,32 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) AActor *pmo=player->mo; damage = 60+(pr_hammeratk()&63); - power = 10*FRACUNIT; hammertime = PClass::FindActor("HammerPuff"); for (i = 0; i < 16; i++) { - angle = pmo->angle + i*(ANG45/32); - slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &t, 0, ALF_CHECK3D); - if (t.linetarget != NULL) + for (int j = 1; j >= -1; j -= 2) { - P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t); + angle = pmo->Angles.Yaw + j*i*(45. / 32); + slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &t, 0., ALF_CHECK3D); if (t.linetarget != NULL) { - AdjustPlayerAngle(pmo, &t); - if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player) + P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t); + if (t.linetarget != NULL) { - P_ThrustMobj(t.linetarget, t.angleFromSource, power); + AdjustPlayerAngle(pmo, &t); + if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player) + { + t.linetarget->Thrust(t.angleFromSource, 10); + } + pmo->weaponspecial = false; // Don't throw a hammer + goto hammerdone; } - pmo->weaponspecial = false; // Don't throw a hammer - goto hammerdone; - } - } - angle = pmo->angle-i*(ANG45/32); - slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &t, 0, ALF_CHECK3D); - if (t.linetarget != NULL) - { - P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t); - if (t.linetarget != NULL) - { - AdjustPlayerAngle(pmo, &t); - if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player) - { - P_ThrustMobj(t.linetarget, t.angleFromSource, power); - } - pmo->weaponspecial = false; // Don't throw a hammer - goto hammerdone; } } } // didn't find any targets in meleerange, so set to throw out a hammer - angle = pmo->angle; - slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, NULL, 0, ALF_CHECK3D); + angle = pmo->Angles.Yaw; + slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, NULL, 0., ALF_CHECK3D); if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true) != NULL) { pmo->weaponspecial = false; diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index 8abf3fa18..607a9a88a 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -23,29 +23,25 @@ static FRandom pr_fpatk ("FPunchAttack"); // //============================================================================ -#define MAX_ANGLE_ADJUST (5*ANGLE_1) +#define MAX_ANGLE_ADJUST (5.) void AdjustPlayerAngle (AActor *pmo, FTranslatedLineTarget *t) { - angle_t angle; - int difference; - - angle = pmo->AngleTo(t->linetarget); - difference = (int)angle - (int)pmo->angle; - if (abs(difference) > MAX_ANGLE_ADJUST) + DAngle difference = deltaangle(pmo->Angles.Yaw, pmo->AngleTo(t->linetarget)); + if (fabs(difference) > MAX_ANGLE_ADJUST) { if (difference > 0) { - pmo->angle += MAX_ANGLE_ADJUST; + pmo->Angles.Yaw += MAX_ANGLE_ADJUST; } else { - pmo->angle -= MAX_ANGLE_ADJUST; + pmo->Angles.Yaw -= MAX_ANGLE_ADJUST; } } else { - pmo->angle = angle; + pmo->Angles.Yaw = t->angleFromSource; } } @@ -57,11 +53,11 @@ void AdjustPlayerAngle (AActor *pmo, FTranslatedLineTarget *t) // //============================================================================ -static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power) +static bool TryPunch(APlayerPawn *pmo, DAngle angle, int damage, int power) { PClassActor *pufftype; FTranslatedLineTarget t; - int slope; + DAngle slope; slope = P_AimLineAttack (pmo, angle, 2*MELEERANGE, &t); if (t.linetarget != NULL) @@ -82,7 +78,7 @@ static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power) if (t.linetarget->player != NULL || (t.linetarget->Mass != INT_MAX && (t.linetarget->flags3 & MF3_ISMONSTER))) { - P_ThrustMobj (t.linetarget, t.angleFromSource, power); + t.linetarget->Thrust(t.angleFromSource, power); } AdjustPlayerAngle (pmo, &t); return true; @@ -102,7 +98,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) PARAM_ACTION_PROLOGUE; int damage; - fixed_t power; int i; player_t *player; @@ -113,11 +108,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) APlayerPawn *pmo = player->mo; damage = 40+(pr_fpatk()&15); - power = 2*FRACUNIT; for (i = 0; i < 16; i++) { - if (TryPunch(pmo, pmo->angle + i*(ANG45/16), damage, power) || - TryPunch(pmo, pmo->angle - i*(ANG45/16), damage, power)) + if (TryPunch(pmo, pmo->Angles.Yaw + i*(45./16), damage, 2) || + TryPunch(pmo, pmo->Angles.Yaw - i*(45./16), damage, 2)) { // hit something if (pmo->weaponspecial >= 3) { @@ -131,7 +125,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) // didn't find any creatures, so try to strike any walls pmo->weaponspecial = 0; - int slope = P_AimLineAttack (pmo, pmo->angle, MELEERANGE); - P_LineAttack (pmo, pmo->angle, MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("PunchPuff"), true); + DAngle slope = P_AimLineAttack (pmo, pmo->Angles.Yaw, MELEERANGE); + P_LineAttack (pmo, pmo->Angles.Yaw, MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("PunchPuff"), true); return 0; } diff --git a/src/g_hexen/a_fighterquietus.cpp b/src/g_hexen/a_fighterquietus.cpp index cb797f661..27e787d31 100644 --- a/src/g_hexen/a_fighterquietus.cpp +++ b/src/g_hexen/a_fighterquietus.cpp @@ -31,7 +31,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces) PARAM_CLASS(p2, AActor); PARAM_CLASS(p3, AActor); - for (int i = 0, j = 0, fineang = 0; i < 3; ++i) + for (int i = 0, j = 0; i < 3; ++i) { PClassActor *cls = j == 0 ? p1 : j == 1 ? p2 : p3; if (cls) @@ -39,11 +39,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces) AActor *piece = Spawn (cls, self->Pos(), ALLOW_REPLACE); if (piece != NULL) { - piece->vel.x = self->vel.x + finecosine[fineang]; - piece->vel.y = self->vel.y + finesine[fineang]; - piece->vel.z = self->vel.z; + piece->Vel = self->Vel + DAngle(i*120.).ToVector(1); piece->flags |= MF_DROPPED; - fineang += FINEANGLES/3; j = (j == 0) ? (pr_quietusdrop() & 1) + 1 : 3-j; } } @@ -95,11 +92,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - P_SpawnPlayerMissile (self, 0, 0, -10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle+ANGLE_45/4); - P_SpawnPlayerMissile (self, 0, 0, -5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle+ANGLE_45/8); - P_SpawnPlayerMissile (self, 0, 0, 0, RUNTIME_CLASS(AFSwordMissile), self->angle); - P_SpawnPlayerMissile (self, 0, 0, 5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle-ANGLE_45/8); - P_SpawnPlayerMissile (self, 0, 0, 10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle-ANGLE_45/4); + P_SpawnPlayerMissile (self, 0, 0, -10, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./4)); + P_SpawnPlayerMissile (self, 0, 0, -5, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./8)); + P_SpawnPlayerMissile (self, 0, 0, 0, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw); + P_SpawnPlayerMissile (self, 0, 0, 5, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./8)); + P_SpawnPlayerMissile (self, 0, 0, 10, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./4)); S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM); return 0; } @@ -118,9 +115,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordFlames) for (i = 1+(pr_fswordflame()&3); i; i--) { - fixed_t xo = ((pr_fswordflame() - 128) << 12); - fixed_t yo = ((pr_fswordflame() - 128) << 12); - fixed_t zo = ((pr_fswordflame() - 128) << 11); + double xo = (pr_fswordflame() - 128) / 16.; + double yo = (pr_fswordflame() - 128) / 16.; + double zo = (pr_fswordflame() - 128) / 8.; Spawn ("FSwordFlame", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); } return 0; @@ -138,13 +135,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FighterAttack) if (!self->target) return 0; - angle_t angle = self->angle; - - P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle+ANG45/4, 0); - P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle+ANG45/8, 0); - P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle, 0); - P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/8, 0); - P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle-ANG45/4, 0); + P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45. / 4), 0); + P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45. / 8), 0); + P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw, 0); + P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45. / 8), 0); + P_SpawnMissileAngle(self, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45. / 4), 0); S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM); return 0; } diff --git a/src/g_hexen/a_firedemon.cpp b/src/g_hexen/a_firedemon.cpp index cbfffdd1d..712363167 100644 --- a/src/g_hexen/a_firedemon.cpp +++ b/src/g_hexen/a_firedemon.cpp @@ -9,7 +9,7 @@ #include "thingdef/thingdef.h" */ -#define FIREDEMON_ATTACK_RANGE 64*8*FRACUNIT +#define FIREDEMON_ATTACK_RANGE (64*8.) static FRandom pr_firedemonrock ("FireDemonRock"); static FRandom pr_smbounce ("SMBounce"); @@ -54,16 +54,16 @@ void A_FiredSpawnRock (AActor *actor) break; } - fixed_t xo = ((pr_firedemonrock() - 128) << 12); - fixed_t yo = ((pr_firedemonrock() - 128) << 12); - fixed_t zo = (pr_firedemonrock() << 11); + double xo = (pr_firedemonrock() - 128) / 16.; + double yo = (pr_firedemonrock() - 128) / 16.; + double zo = pr_firedemonrock() / 32.; mo = Spawn (rtype, actor->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { mo->target = actor; - mo->vel.x = (pr_firedemonrock() - 128) <<10; - mo->vel.y = (pr_firedemonrock() - 128) <<10; - mo->vel.z = (pr_firedemonrock() << 10); + mo->Vel.X = (pr_firedemonrock() - 128) / 64.; + mo->Vel.Y = (pr_firedemonrock() - 128) / 64.; + mo->Vel.Z = (pr_firedemonrock() / 64.); mo->special1 = 2; // Number bounces } @@ -101,10 +101,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SmBounce) PARAM_ACTION_PROLOGUE; // give some more velocity (x,y,&z) - self->SetZ(self->floorz + FRACUNIT); - self->vel.z = (2*FRACUNIT) + (pr_smbounce() << 10); - self->vel.x = pr_smbounce()%3<vel.y = pr_smbounce()%3<SetZ(self->floorz + 1); + self->Vel.Z = 2. + pr_smbounce() / 64.; + self->Vel.X = pr_smbounce() % 3; + self->Vel.Y = pr_smbounce() % 3; return 0; } @@ -137,20 +137,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase) int weaveindex = self->special1; AActor *target = self->target; - angle_t ang; - fixed_t dist; + DAngle ang; + double dist; if (self->reactiontime) self->reactiontime--; if (self->threshold) self->threshold--; // Float up and down - self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8); + self->AddZ(BobSin(weaveindex)); self->special1 = (weaveindex + 2) & 63; // Ensure it stays above certain height - if (self->Z() < self->floorz + (64*FRACUNIT)) + if (self->Z() < self->floorz + 64) { - self->AddZ(2*FRACUNIT); + self->AddZ(2); } if(!self->target || !(self->target->flags&MF_SHOOTABLE)) @@ -167,20 +167,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase) else { self->special2 = 0; - self->vel.x = self->vel.y = 0; - dist = self->AproxDistance (target); + self->Vel.X = self->Vel.Y = 0; + dist = self->Distance2D(target); if (dist < FIREDEMON_ATTACK_RANGE) { if (pr_firedemonchase() < 30) { ang = self->AngleTo(target); if (pr_firedemonchase() < 128) - ang += ANGLE_90; + ang += 90; else - ang -= ANGLE_90; - ang >>= ANGLETOFINESHIFT; - self->vel.x = finecosine[ang] << 3; //FixedMul (8*FRACUNIT, finecosine[ang]); - self->vel.y = finesine[ang] << 3; //FixedMul (8*FRACUNIT, finesine[ang]); + ang -= 90; + self->Thrust(ang, 8); self->special2 = 3; // strafe time } } @@ -235,16 +233,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch) mo = Spawn ("FireDemonSplotch1", self->Pos(), ALLOW_REPLACE); if (mo) { - mo->vel.x = (pr_firedemonsplotch() - 128) << 11; - mo->vel.y = (pr_firedemonsplotch() - 128) << 11; - mo->vel.z = (pr_firedemonsplotch() << 10) + FRACUNIT*3; + mo->Vel.X = (pr_firedemonsplotch() - 128) / 32.; + mo->Vel.Y = (pr_firedemonsplotch() - 128) / 32.; + mo->Vel.Z = (pr_firedemonsplotch() / 64.) + 3; } mo = Spawn ("FireDemonSplotch2", self->Pos(), ALLOW_REPLACE); if (mo) { - mo->vel.x = (pr_firedemonsplotch() - 128) << 11; - mo->vel.y = (pr_firedemonsplotch() - 128) << 11; - mo->vel.z = (pr_firedemonsplotch() << 10) + FRACUNIT*3; + mo->Vel.X = (pr_firedemonsplotch() - 128) / 32.; + mo->Vel.Y = (pr_firedemonsplotch() - 128) / 32.; + mo->Vel.Z = (pr_firedemonsplotch() / 64.) + 3; } return 0; } diff --git a/src/g_hexen/a_flechette.cpp b/src/g_hexen/a_flechette.cpp index 09fb735e9..ccc2bf112 100644 --- a/src/g_hexen/a_flechette.cpp +++ b/src/g_hexen/a_flechette.cpp @@ -39,13 +39,10 @@ IMPLEMENT_CLASS (AArtiPoisonBag1) bool AArtiPoisonBag1::Use (bool pickup) { - angle_t angle = Owner->angle >> ANGLETOFINESHIFT; - AActor *mo; - - mo = Spawn ("PoisonBag", Owner->Vec3Offset( - 16*finecosine[angle], - 24*finesine[angle], - -Owner->floorclip+8*FRACUNIT), ALLOW_REPLACE); + AActor *mo = Spawn("PoisonBag", Owner->Vec3Offset( + 16 * Owner->Angles.Yaw.Cos(), + 24 * Owner->Angles.Yaw.Sin(), + -Owner->Floorclip + 8), ALLOW_REPLACE); if (mo) { mo->target = Owner; @@ -67,13 +64,10 @@ IMPLEMENT_CLASS (AArtiPoisonBag2) bool AArtiPoisonBag2::Use (bool pickup) { - angle_t angle = Owner->angle >> ANGLETOFINESHIFT; - AActor *mo; - - mo = Spawn ("FireBomb", Owner->Vec3Offset( - 16*finecosine[angle], - 24*finesine[angle], - -Owner->floorclip+8*FRACUNIT), ALLOW_REPLACE); + AActor *mo = Spawn("FireBomb", Owner->Vec3Offset( + 16 * Owner->Angles.Yaw.Cos(), + 24 * Owner->Angles.Yaw.Sin(), + -Owner->Floorclip + 8), ALLOW_REPLACE); if (mo) { mo->target = Owner; @@ -97,14 +91,14 @@ bool AArtiPoisonBag3::Use (bool pickup) { AActor *mo; - mo = Spawn("ThrowingBomb", Owner->PosPlusZ(-Owner->floorclip+35*FRACUNIT + (Owner->player? Owner->player->crouchoffset : 0)), ALLOW_REPLACE); + mo = Spawn("ThrowingBomb", Owner->PosPlusZ(35. - Owner->Floorclip + (Owner->player? Owner->player->crouchoffset : 0)), ALLOW_REPLACE); if (mo) { - mo->angle = Owner->angle + (((pr_poisonbag()&7) - 4) << 24); + mo->Angles.Yaw = Owner->Angles.Yaw + (((pr_poisonbag() & 7) - 4) * (360./256.)); /* Original flight code from Hexen - * mo->momz = 4*FRACUNIT+((player->lookdir)<<(FRACBITS-4)); - * mo->z += player->lookdir<<(FRACBITS-4); + * mo->momz = 4*F.RACUNIT+((player->lookdir)<<(F.RACBITS-4)); + * mo->z += player->lookdir<<(F.RACBITS-4); * P_ThrustMobj(mo, mo->angle, mo->info->speed); * mo->momx += player->mo->momx>>1; * mo->momy += player->mo->momy>>1; @@ -114,16 +108,16 @@ bool AArtiPoisonBag3::Use (bool pickup) // is as set by the projectile. To accommodate this with a proper trajectory, we // aim the projectile ~20 degrees higher than we're looking at and increase the // speed we fire at accordingly. - angle_t orgpitch = angle_t(-Owner->pitch) >> ANGLETOFINESHIFT; - angle_t modpitch = angle_t(0xDC00000 - Owner->pitch) >> ANGLETOFINESHIFT; - angle_t angle = mo->angle >> ANGLETOFINESHIFT; - fixed_t speed = fixed_t(sqrt((double)mo->Speed*mo->Speed + (4.0*65536*4*65536))); - fixed_t xyscale = FixedMul(speed, finecosine[modpitch]); + DAngle orgpitch = -Owner->Angles.Pitch; + DAngle modpitch = clamp(-Owner->Angles.Pitch + 20, -89., 89.); + DAngle angle = mo->Angles.Yaw; + double speed = DVector2(mo->Speed, 4.).Length(); + double xyscale = speed * modpitch.Cos(); - mo->vel.z = FixedMul(speed, finesine[modpitch]); - mo->vel.x = FixedMul(xyscale, finecosine[angle]) + (Owner->vel.x >> 1); - mo->vel.y = FixedMul(xyscale, finesine[angle]) + (Owner->vel.y >> 1); - mo->AddZ(FixedMul(mo->Speed, finesine[orgpitch])); + mo->Vel.Z = speed * modpitch.Sin(); + mo->Vel.X = xyscale * angle.Cos() + Owner->Vel.X / 2; + mo->Vel.Y = xyscale * angle.Sin() + Owner->Vel.Y / 2; + mo->AddZ(mo->Speed * orgpitch.Sin()); mo->target = Owner; mo->tics -= pr_poisonbag()&3; @@ -265,7 +259,7 @@ AInventory *AArtiPoisonBag::CreateCopy (AActor *other) AInventory *copy; PClassActor *spawntype = GetFlechetteType(other); - copy = static_cast(Spawn (spawntype, 0, 0, 0, NO_REPLACE)); + copy = static_cast(Spawn (spawntype)); copy->Amount = Amount; copy->MaxAmount = MaxAmount; GoAwayAndDie (); @@ -306,7 +300,7 @@ IMPLEMENT_CLASS (APoisonCloud) void APoisonCloud::BeginPlay () { - vel.x = 1; // missile objects must move to impact other objects + Vel.X = MinVel; // missile objects must move to impact other objects special1 = 24+(pr_poisoncloud()&7); special2 = 0; } @@ -324,7 +318,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype) } else { - dopoison = victim->player->poisoncount < (int)(4.f * level.teamdamage); + dopoison = victim->player->poisoncount < (int)(4. * level.teamdamage); } if (dopoison) @@ -332,7 +326,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype) int damage = 15 + (pr_poisoncloudd()&15); if (mate) { - damage = (int)((double)damage * level.teamdamage); + damage = (int)(damage * level.teamdamage); } // Handle passive damage modifiers (e.g. PowerProtection) if (victim->Inventory != NULL) @@ -340,11 +334,7 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype) victim->Inventory->ModifyDamage(damage, damagetype, damage, true); } // Modify with damage factors - damage = FixedMul(damage, victim->DamageFactor); - if (damage > 0) - { - damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, damagetype, victim->GetClass()->DamageFactors); - } + damage = victim->ApplyDamageFactor(damagetype, damage); if (damage > 0) { P_PoisonDamage (victim->player, this, @@ -376,7 +366,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagInit) AActor *mo; - mo = Spawn (self->PosPlusZ(28*FRACUNIT), ALLOW_REPLACE); + mo = Spawn (self->PosPlusZ(28.), ALLOW_REPLACE); if (mo) { mo->target = self->target; @@ -419,7 +409,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage) P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE); bobIndex = self->special2; - self->AddZ(finesine[bobIndex << BOBTOFINESHIFT] >> 1); + self->AddZ(BobSin(bobIndex) / 16); self->special2 = (bobIndex + 1) & 63; return 0; } @@ -452,15 +442,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2) PARAM_ACTION_PROLOGUE; // [RH] Check using actual velocity, although the vel.z < 2 check still stands - //if (abs(self->vel.x) < FRACUNIT*3/2 && abs(self->vel.y) < FRACUNIT*3/2 - // && self->vel.z < 2*FRACUNIT) - if (self->vel.z < 2*FRACUNIT && - TMulScale32 (self->vel.x, self->vel.x, self->vel.y, self->vel.y, self->vel.z, self->vel.z) - < (3*3)/(2*2)) + if (self->Vel.Z < 2 && self->Vel.LengthSquared() < (9./4.)) { self->SetState (self->SpawnState + 6); self->SetZ(self->floorz); - self->vel.z = 0; + self->Vel.Z = 0; self->BounceFlags = BOUNCE_None; self->flags &= ~MF_MISSILE; } diff --git a/src/g_hexen/a_flies.cpp b/src/g_hexen/a_flies.cpp index 16fefef73..1023c12ae 100644 --- a/src/g_hexen/a_flies.cpp +++ b/src/g_hexen/a_flies.cpp @@ -84,26 +84,24 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz) return 0; } - angle_t ang = self->AngleTo(targ); - self->angle = ang; + self->Angles.Yaw = self->AngleTo(targ); self->args[0]++; - ang >>= ANGLETOFINESHIFT; - if (!P_TryMove(self, self->X() + 6 * finecosine[ang], self->Y() + 6 * finesine[ang], true)) + if (!P_TryMove(self, self->Pos().XY() + self->Angles.Yaw.ToVector(6), true)) { self->SetIdle(true); return 0; } if (self->args[0] & 2) { - self->vel.x += (pr_fly() - 128) << BOBTOFINESHIFT; - self->vel.y += (pr_fly() - 128) << BOBTOFINESHIFT; + self->Vel.X += (pr_fly() - 128) / 512.; + self->Vel.Y += (pr_fly() - 128) / 512.; } int zrand = pr_fly(); - if (targ->Z() + 5*FRACUNIT < self->Z() && zrand > 150) + if (targ->Z() + 5. < self->Z() && zrand > 150) { zrand = -zrand; } - self->vel.z = zrand << BOBTOFINESHIFT; + self->Vel.Z = zrand / 512.; if (pr_fly() < 40) { S_Sound(self, CHAN_VOICE, self->ActiveSound, 0.5f, ATTN_STATIC); diff --git a/src/g_hexen/a_fog.cpp b/src/g_hexen/a_fog.cpp index d974910cc..b89f8d38c 100644 --- a/src/g_hexen/a_fog.cpp +++ b/src/g_hexen/a_fog.cpp @@ -15,7 +15,7 @@ static FRandom pr_fogspawn ("FogSpawn"); // args[3] Lifetime countdown // args[4] Boolean: fog moving? // special1 Internal: Counter for spawn frequency -// special2 Internal: Index into floatbob table +// WeaveIndexZ Internal: Index into floatbob table // //========================================================================== @@ -37,7 +37,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn) }; AActor *mo = NULL; - angle_t delta; + int delta; if (self->special1-- > 0) { @@ -51,13 +51,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn) { delta = self->args[1]; if (delta==0) delta=1; - mo->angle = self->angle + (((pr_fogspawn()%delta)-(delta>>1))<<24); + mo->Angles.Yaw = self->Angles.Yaw + (((pr_fogspawn() % delta) - (delta >> 1)) * (360 / 256.)); mo->target = self; if (self->args[0] < 1) self->args[0] = 1; mo->args[0] = (pr_fogspawn() % (self->args[0]))+1; // Random speed mo->args[3] = self->args[3]; // Set lifetime mo->args[4] = 1; // Set to moving - mo->special2 = pr_fogspawn()&63; + mo->WeaveIndexZ = pr_fogspawn()&63; } return 0; } @@ -72,8 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove) { PARAM_ACTION_PROLOGUE; - int speed = self->args[0]<args[0]; int weaveindex; if (!self->args[4]) @@ -89,14 +88,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove) if ((self->args[3] % 4) == 0) { - weaveindex = self->special2; - self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 4); - self->special2 = (weaveindex + 1) & 63; + weaveindex = self->WeaveIndexZ; + self->AddZ(BobSin(weaveindex) / 2); + self->WeaveIndexZ = (weaveindex + 1) & 63; } - angle = self->angle>>ANGLETOFINESHIFT; - self->vel.x = FixedMul(speed, finecosine[angle]); - self->vel.y = FixedMul(speed, finesine[angle]); + self->VelFromAngle(speed); return 0; } diff --git a/src/g_hexen/a_healingradius.cpp b/src/g_hexen/a_healingradius.cpp index 2563df089..c381f3964 100644 --- a/src/g_hexen/a_healingradius.cpp +++ b/src/g_hexen/a_healingradius.cpp @@ -12,7 +12,7 @@ #include "doomstat.h" */ -#define HEAL_RADIUS_DIST 255*FRACUNIT +#define HEAL_RADIUS_DIST 255. static FRandom pr_healradius ("HealRadius"); @@ -42,7 +42,7 @@ bool AArtiHealingRadius::Use (bool pickup) if (playeringame[i] && players[i].mo != NULL && players[i].mo->health > 0 && - players[i].mo->AproxDistance (Owner) <= HEAL_RADIUS_DIST) + players[i].mo->Distance2D (Owner) <= HEAL_RADIUS_DIST) { // Q: Is it worth it to make this selectable as a player property? // A: Probably not - but it sure doesn't hurt. @@ -52,7 +52,7 @@ bool AArtiHealingRadius::Use (bool pickup) case NAME_Armor: for (int j = 0; j < 4; ++j) { - AHexenArmor *armor = Spawn (0,0,0, NO_REPLACE); + AHexenArmor *armor = Spawn (); armor->health = j; armor->Amount = 1; if (!armor->CallTryPickup (players[i].mo)) diff --git a/src/g_hexen/a_heresiarch.cpp b/src/g_hexen/a_heresiarch.cpp index 6aee19a71..d6ce35d18 100644 --- a/src/g_hexen/a_heresiarch.cpp +++ b/src/g_hexen/a_heresiarch.cpp @@ -16,7 +16,7 @@ // Sorcerer stuff // // Sorcerer Variables -// special1 Angle of ball 1 (all others relative to that) +// specialf1 Angle of ball 1 (all others relative to that) // StopBall which ball to stop at in stop mode (MT_???) // args[0] Defense time // args[1] Number of full rotations since stopping mode @@ -24,7 +24,7 @@ // args[3] Movement mode (see SORC_ macros) // args[4] Current ball orbit speed // Sorcerer Ball Variables -// special1 Previous angle of ball (for woosh) +// specialf1 Previous angle of ball (for woosh) // special2 Countdown of rapid fire (FX4) //============================================================================ @@ -45,9 +45,9 @@ #define SORC_NORMAL 5 #define SORC_FIRING_SPELL 6 -#define BALL1_ANGLEOFFSET 0 -#define BALL2_ANGLEOFFSET (ANGLE_MAX/3) -#define BALL3_ANGLEOFFSET ((ANGLE_MAX/3)*2) +#define BALL1_ANGLEOFFSET 0. +#define BALL2_ANGLEOFFSET 120. +#define BALL3_ANGLEOFFSET 240. void A_SlowBalls (AActor *actor); void A_StopBalls (AActor *actor); @@ -65,6 +65,7 @@ class AHeresiarch : public AActor DECLARE_CLASS (AHeresiarch, AActor) public: const PClass *StopBall; + DAngle BallAngle; void Serialize (FArchive &arc); void Die (AActor *source, AActor *inflictor, int dmgflags); @@ -75,7 +76,7 @@ IMPLEMENT_CLASS (AHeresiarch) void AHeresiarch::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << StopBall; + arc << StopBall << BallAngle; } void AHeresiarch::Die (AActor *source, AActor *inflictor, int dmgflags) @@ -101,15 +102,16 @@ public: virtual void DoFireSpell (); virtual void SorcUpdateBallAngle (); virtual void CastSorcererSpell (); - angle_t AngleOffset; + DAngle AngleOffset; + DAngle OldAngle; void Serialize (FArchive &arc) { Super::Serialize (arc); - arc << AngleOffset; + arc << AngleOffset << OldAngle; } - bool SpecialBlastHandling (AActor *source, fixed_t strength) + bool SpecialBlastHandling (AActor *source, double strength) { // don't blast sorcerer balls return false; } @@ -169,26 +171,6 @@ IMPLEMENT_CLASS (ASorcBall3) // Sorcerer spell 1 (The burning, bouncing head thing) ---------------------- -/* -class ASorcFX1 : public AActor -{ - DECLARE_CLASS (ASorcFX1, AActor) -public: - bool FloorBounceMissile (secplane_t &plane) - { - fixed_t orgvelz = vel.z; - - if (!Super::FloorBounceMissile (plane)) - { - vel.z = -orgvelz; // no energy absorbed - return false; - } - return true; - } -}; -IMPLEMENT_CLASS (ASorcFX1) -*/ - //============================================================================ // // SorcBall::DoFireSpell @@ -231,7 +213,7 @@ void ASorcBall1::DoFireSpell () DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls) { - PARAM_ACTION_PROLOGUE; + PARAM_ACTION_PROLOGUE_TYPE(AHeresiarch); AActor *mo; @@ -240,9 +222,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls) self->args[0] = 0; // Currently no defense self->args[3] = SORC_NORMAL; self->args[4] = SORCBALL_INITIAL_SPEED; // Initial orbit speed - self->special1 = ANGLE_1; + self->BallAngle = 1.; - fixedvec3 pos = self->PosPlusZ(-self->floorclip + self->height); + DVector3 pos = self->PosPlusZ(-self->Floorclip + self->Height); mo = Spawn("SorcBall1", pos, NO_REPLACE); if (mo) @@ -262,11 +244,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls) // // A_SorcBallOrbit // +// - actor is ball //============================================================================ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) { - PARAM_ACTION_PROLOGUE; + PARAM_ACTION_PROLOGUE_TYPE(ASorcBall); // [RH] If no parent, then die instead of crashing if (self->target == NULL) @@ -275,78 +258,78 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) return 0; } - ASorcBall *actor; - angle_t angle, baseangle; int mode = self->target->args[3]; AHeresiarch *parent = barrier_cast(self->target); - int dist = parent->radius - (self->radius<<1); - angle_t prevangle = self->special1; + double dist = parent->radius - (self->radius*2); +#if 0 + // This cannot happen anymore because this is defined locally in SorcBall if (!self->IsKindOf (RUNTIME_CLASS(ASorcBall))) { I_Error ("Corrupted sorcerer:\nTried to use a %s", self->GetClass()->TypeName.GetChars()); } - actor = static_cast (self); +#endif - if (actor->target->health <= 0) + if (self->target->health <= 0) { - actor->SetState (actor->FindState(NAME_Pain)); + self->SetState (self->FindState(NAME_Pain)); return 0; } - baseangle = (angle_t)parent->special1; - angle = baseangle + actor->AngleOffset; - actor->angle = angle; - angle >>= ANGLETOFINESHIFT; + DAngle prevangle = self->OldAngle; + DAngle baseangle = parent->BallAngle; + DAngle angle = baseangle + self->AngleOffset; + + self->Angles.Yaw = angle; switch (mode) { case SORC_NORMAL: // Balls rotating normally - actor->SorcUpdateBallAngle (); + self->SorcUpdateBallAngle (); break; case SORC_DECELERATE: // Balls decelerating - A_DecelBalls(actor); - actor->SorcUpdateBallAngle (); + A_DecelBalls(self); + self->SorcUpdateBallAngle (); break; case SORC_ACCELERATE: // Balls accelerating - A_AccelBalls(actor); - actor->SorcUpdateBallAngle (); + A_AccelBalls(self); + self->SorcUpdateBallAngle (); break; case SORC_STOPPING: // Balls stopping - if ((parent->StopBall == actor->GetClass()) && + if ((parent->StopBall == self->GetClass()) && (parent->args[1] > SORCBALL_SPEED_ROTATIONS) && - (absangle(angle - (parent->angle>>ANGLETOFINESHIFT)) < (30<<5))) + absangle(angle, parent->Angles.Yaw) < 42.1875) { // Can stop now - actor->target->args[3] = SORC_FIRESPELL; - actor->target->args[4] = 0; + self->target->args[3] = SORC_FIRESPELL; + self->target->args[4] = 0; // Set angle so self angle == sorcerer angle - parent->special1 = (int)(parent->angle - actor->AngleOffset); + parent->BallAngle = parent->Angles.Yaw - self->AngleOffset; } else { - actor->SorcUpdateBallAngle (); + self->SorcUpdateBallAngle (); } break; case SORC_FIRESPELL: // Casting spell - if (parent->StopBall == actor->GetClass()) + if (parent->StopBall == self->GetClass()) { // Put sorcerer into special throw spell anim if (parent->health > 0) parent->SetState (parent->FindState("Attack1")); - actor->DoFireSpell (); + self->DoFireSpell (); } break; case SORC_FIRING_SPELL: - if (parent->StopBall == actor->GetClass()) + if (parent->StopBall == self->GetClass()) { - if (actor->special2-- <= 0) + if (self->special2-- <= 0) { // Done rapid firing parent->args[3] = SORC_STOPPED; @@ -357,7 +340,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) else { // Do rapid fire spell - A_SorcOffense2(actor); + A_SorcOffense2(self); } } break; @@ -367,21 +350,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) break; } - if ((angle < prevangle) && (parent->args[4]==SORCBALL_TERMINAL_SPEED)) + if (deltaangle(angle, prevangle) < 0 && (parent->args[4]==SORCBALL_TERMINAL_SPEED)) { parent->args[1]++; // Bump rotation counter // Completed full rotation - make woosh sound - S_Sound (actor, CHAN_BODY, "SorcererBallWoosh", 1, ATTN_NORM); + S_Sound (self, CHAN_BODY, "SorcererBallWoosh", 1, ATTN_NORM); } - actor->special1 = angle; // Set previous angle + self->OldAngle = angle; // Set previous angle - fixedvec3 pos = parent->Vec3Offset( - FixedMul(dist, finecosine[angle]), - FixedMul(dist, finesine[angle]), - -parent->floorclip + parent->height); - actor->SetOrigin (pos, true); - actor->floorz = parent->floorz; - actor->ceilingz = parent->ceilingz; + DVector3 pos = parent->Vec3Angle(dist, angle, -parent->Floorclip + parent->Height); + self->SetOrigin (pos, true); + self->floorz = parent->floorz; + self->ceilingz = parent->ceilingz; return 0; } @@ -411,10 +391,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpeedBalls) // //============================================================================ -void A_SlowBalls(AActor *actor) +void A_SlowBalls(AActor *self) { - actor->args[3] = SORC_DECELERATE; // slow mode - actor->args[2] = SORCBALL_INITIAL_SPEED; // target speed + self->args[3] = SORC_DECELERATE; // slow mode + self->args[2] = SORCBALL_INITIAL_SPEED; // target speed } //============================================================================ @@ -428,23 +408,23 @@ void A_SlowBalls(AActor *actor) void A_StopBalls(AActor *scary) { - AHeresiarch *actor = static_cast (scary); + AHeresiarch *self = static_cast (scary); int chance = pr_heresiarch(); - actor->args[3] = SORC_STOPPING; // stopping mode - actor->args[1] = 0; // Reset rotation counter + self->args[3] = SORC_STOPPING; // stopping mode + self->args[1] = 0; // Reset rotation counter - if ((actor->args[0] <= 0) && (chance < 200)) + if ((self->args[0] <= 0) && (chance < 200)) { - actor->StopBall = RUNTIME_CLASS(ASorcBall2); // Blue + self->StopBall = RUNTIME_CLASS(ASorcBall2); // Blue } - else if((actor->health < (actor->SpawnHealth() >> 1)) && + else if((self->health < (self->SpawnHealth() >> 1)) && (chance < 200)) { - actor->StopBall = RUNTIME_CLASS(ASorcBall3); // Green + self->StopBall = RUNTIME_CLASS(ASorcBall3); // Green } else { - actor->StopBall = RUNTIME_CLASS(ASorcBall1); // Yellow + self->StopBall = RUNTIME_CLASS(ASorcBall1); // Yellow } } @@ -456,9 +436,9 @@ void A_StopBalls(AActor *scary) // //============================================================================ -void A_AccelBalls(AActor *actor) +void A_AccelBalls(AActor *self) { - AActor *sorc = actor->target; + AActor *sorc = self->target; if (sorc->args[4] < sorc->args[2]) { @@ -483,9 +463,9 @@ void A_AccelBalls(AActor *actor) // //============================================================================ -void A_DecelBalls(AActor *actor) +void A_DecelBalls(AActor *self) { - AActor *sorc = actor->target; + AActor *sorc = self->target; if (sorc->args[4] > sorc->args[2]) { @@ -506,7 +486,7 @@ void A_DecelBalls(AActor *actor) void ASorcBall1::SorcUpdateBallAngle () { - target->special1 += ANGLE_1*target->args[4]; + barrier_cast(target)->BallAngle += target->args[4]; } //============================================================================ @@ -551,7 +531,7 @@ void ASorcBall2::CastSorcererSpell () AActor *parent = target; AActor *mo; - mo = Spawn("SorcFX2", PosPlusZ(-parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT), ALLOW_REPLACE); + mo = Spawn("SorcFX2", PosPlusZ(parent->Floorclip + SORC_DEFENSE_HEIGHT), ALLOW_REPLACE); parent->flags2 |= MF2_REFLECTIVE|MF2_INVULNERABLE; parent->args[0] = SORC_DEFENSE_TIME; if (mo) mo->target = parent; @@ -570,24 +550,24 @@ void ASorcBall3::CastSorcererSpell () Super::CastSorcererSpell (); AActor *mo; - angle_t ang1, ang2; + DAngle ang1, ang2; AActor *parent = target; - ang1 = angle - ANGLE_45; - ang2 = angle + ANGLE_45; + ang1 = Angles.Yaw.Degrees - 45; + ang2 = Angles.Yaw.Degrees + 45; PClassActor *cls = PClass::FindActor("SorcFX3"); if (health < (SpawnHealth()/3)) { // Spawn 2 at a time - mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT); + mo = P_SpawnMissileAngle(parent, cls, ang1, 4.); if (mo) mo->target = parent; - mo = P_SpawnMissileAngle(parent, cls, ang2, 4*FRACUNIT); + mo = P_SpawnMissileAngle(parent, cls, ang2, 4.); if (mo) mo->target = parent; } else { if (pr_heresiarch() < 128) ang1 = ang2; - mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT); + mo = P_SpawnMissileAngle(parent, cls, ang1, 4.); if (mo) mo->target = parent; } } @@ -596,12 +576,12 @@ void ASorcBall3::CastSorcererSpell () /* void A_SpawnReinforcements(AActor *actor) { - AActor *parent = actor->target; + AActor *parent = self->target; AActor *mo; - angle_t ang; + DAngle ang; - ang = ANGLE_1 * P_Random(); - mo = P_SpawnMissileAngle(actor, MT_SORCFX3, ang, 5*FRACUNIT); + ang = P_Random(); + mo = P_SpawnMissileAngle(actor, MT_SORCFX3, ang, 5.); if (mo) mo->target = parent; } */ @@ -619,11 +599,11 @@ void ASorcBall1::CastSorcererSpell () Super::CastSorcererSpell (); AActor *mo; - angle_t ang1, ang2; + DAngle ang1, ang2; AActor *parent = target; - ang1 = angle + ANGLE_1*70; - ang2 = angle - ANGLE_1*70; + ang1 = Angles.Yaw.Degrees + 70; + ang2 = Angles.Yaw.Degrees - 70; PClassActor *cls = PClass::FindActor("SorcFX1"); mo = P_SpawnMissileAngle (parent, cls, ang1, 0); if (mo) @@ -651,14 +631,15 @@ void ASorcBall1::CastSorcererSpell () // //============================================================================ -void A_SorcOffense2(AActor *actor) +void A_SorcOffense2(AActor *self) { - angle_t ang1; + DAngle ang1; AActor *mo; - int delta, index; - AActor *parent = actor->target; + double delta; + int index; + AActor *parent = self->target; AActor *dest = parent->target; - int dist; + double dist; // [RH] If no enemy, then don't try to shoot. if (dest == NULL) @@ -666,18 +647,17 @@ void A_SorcOffense2(AActor *actor) return; } - index = actor->args[4] << 5; - actor->args[4] = (actor->args[4] + 15) & 255; - delta = (finesine[index])*SORCFX4_SPREAD_ANGLE; - delta = (delta>>FRACBITS)*ANGLE_1; - ang1 = actor->angle + delta; + index = self->args[4]; + self->args[4] = (self->args[4] + 15) & 255; + delta = DAngle(index * (360 / 256.f)).Sin() * SORCFX4_SPREAD_ANGLE; + + ang1 = self->Angles.Yaw + delta; mo = P_SpawnMissileAngle(parent, PClass::FindActor("SorcFX4"), ang1, 0); if (mo) { mo->special2 = 35*5/2; // 5 seconds - dist = mo->AproxDistance(dest) / mo->Speed; - if(dist < 1) dist = 1; - mo->vel.z = (dest->Z() - mo->Z()) / dist; + dist = mo->DistanceBySpeed(dest, mo->Speed); + mo->Vel.Z = (dest->Z() - mo->Z()) / dist; } } @@ -709,22 +689,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBossAttack) DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle) { PARAM_ACTION_PROLOGUE; - fixed_t dist = 5*FRACUNIT; - fixed_t speed = self->Speed >> FRACBITS; - angle_t rangle; + int speed = (int)self->Speed; + DAngle rangle; AActor *mo; int ix; - fixedvec3 pos = self->Vec3Angle(dist, self->angle, -self->floorclip + (self->height >> 1)); + DVector3 pos = self->Vec3Angle(5., self->Angles.Yaw, -self->Floorclip + self->Height / 2. ); for (ix=0; ix<5; ix++) { mo = Spawn("SorcSpark1", pos, ALLOW_REPLACE); if (mo) { - rangle = (self->angle >> ANGLETOFINESHIFT) + ((pr_heresiarch()%5) << 1); - mo->vel.x = FixedMul(pr_heresiarch()%speed, finecosine[rangle]); - mo->vel.y = FixedMul(pr_heresiarch()%speed, finesine[rangle]); - mo->vel.z = FRACUNIT*2; + rangle = self->Angles.Yaw + (pr_heresiarch() % 5) * (4096 / 360.); + mo->Vel.X = (pr_heresiarch() % speed) * rangle.Cos(); + mo->Vel.Y = (pr_heresiarch() % speed) * rangle.Sin(); + mo->Vel.Z = 2; } } return 0; @@ -744,7 +723,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek) PARAM_ACTION_PROLOGUE; A_DoBounceCheck (self, "SorcererHeadScream"); - P_SeekerMissile (self,ANGLE_1*2,ANGLE_1*6); + P_SeekerMissile(self, 2, 6); return 0; } @@ -758,7 +737,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX1Seek) //============================================================================ // // FX2 Variables -// special1 current angle +// specialf1 current angle // special2 // args[0] 0 = CW, 1 = CCW // args[1] @@ -776,7 +755,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split) { mo->target = self->target; mo->args[0] = 0; // CW - mo->special1 = self->angle; // Set angle + mo->specialf1 = self->Angles.Yaw.Degrees; // Set angle mo->SetState (mo->FindState("Orbit")); } mo = Spawn(self->GetClass(), self->Pos(), NO_REPLACE); @@ -784,7 +763,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split) { mo->target = self->target; mo->args[0] = 1; // CCW - mo->special1 = self->angle; // Set angle + mo->specialf1 = self->Angles.Yaw.Degrees; // Set angle mo->SetState (mo->FindState("Orbit")); } self->Destroy (); @@ -803,8 +782,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit) { PARAM_ACTION_PROLOGUE; - angle_t angle; - fixedvec3 pos; + DAngle angle; + DVector3 pos; AActor *parent = self->target; // [RH] If no parent, then disappear @@ -814,7 +793,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit) return 0; } - fixed_t dist = parent->radius; + double dist = parent->radius; if ((parent->health <= 0) || // Sorcerer is dead (!parent->args[0])) // Time expired @@ -835,25 +814,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit) // Move to new position based on angle if (self->args[0]) // Counter clock-wise { - self->special1 += ANGLE_1*10; - angle = ((angle_t)self->special1) >> ANGLETOFINESHIFT; - pos = parent->Vec3Offset( - FixedMul(dist, finecosine[angle]), - FixedMul(dist, finesine[angle]), - parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT); - pos.z += FixedMul(15*FRACUNIT,finecosine[angle]); + self->specialf1 += 10; + angle = self->specialf1; + pos = parent->Vec3Angle(dist, angle, parent->Floorclip + SORC_DEFENSE_HEIGHT); + pos.Z += 15 * angle.Cos(); // Spawn trailer Spawn("SorcFX2T1", pos, ALLOW_REPLACE); } else // Clock wise { - self->special1 -= ANGLE_1*10; - angle = ((angle_t)self->special1) >> ANGLETOFINESHIFT; - pos = parent->Vec3Offset( - FixedMul(dist, finecosine[angle]), - FixedMul(dist, finesine[angle]), - parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT); - pos.z += FixedMul(20*FRACUNIT,finesine[angle]); + self->specialf1 -= 10; + pos = parent->Vec3Angle(dist, angle, parent->Floorclip + SORC_DEFENSE_HEIGHT); + pos.Z += 20 * angle.Sin(); // Spawn trailer Spawn("SorcFX2T1", pos, ALLOW_REPLACE); } @@ -943,11 +915,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallPop) S_Sound (self, CHAN_BODY, "SorcererBallPop", 1, ATTN_NONE); self->flags &= ~MF_NOGRAVITY; - self->gravity = FRACUNIT/8; - self->vel.x = ((pr_heresiarch()%10)-5) << FRACBITS; - self->vel.y = ((pr_heresiarch()%10)-5) << FRACBITS; - self->vel.z = (2+(pr_heresiarch()%3)) << FRACBITS; - self->special2 = 4*FRACUNIT; // Initial bounce factor + self->Gravity = 1. / 8;; + + self->Vel.X = ((pr_heresiarch()%10)-5); + self->Vel.Y = ((pr_heresiarch()%10)-5); + self->Vel.Z = (2+(pr_heresiarch()%3)); self->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit self->args[3] = 5; // Bounce time in seconds return 0; diff --git a/src/g_hexen/a_hexenglobal.h b/src/g_hexen/a_hexenglobal.h index 5544afb24..3455b684d 100644 --- a/src/g_hexen/a_hexenglobal.h +++ b/src/g_hexen/a_hexenglobal.h @@ -10,7 +10,7 @@ class AHolySpirit : public AActor DECLARE_CLASS (AHolySpirit, AActor) public: bool Slam (AActor *thing); - bool SpecialBlastHandling (AActor *source, fixed_t strength); + bool SpecialBlastHandling (AActor *source, double strength); }; class AFighterWeapon : public AWeapon diff --git a/src/g_hexen/a_hexenspecialdecs.cpp b/src/g_hexen/a_hexenspecialdecs.cpp index 2e9304cdc..28de8d46a 100644 --- a/src/g_hexen/a_hexenspecialdecs.cpp +++ b/src/g_hexen/a_hexenspecialdecs.cpp @@ -66,9 +66,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode) if (mo) { mo->SetState (mo->SpawnState + (pr_pottery()%5)); - mo->vel.z = ((pr_pottery()&7)+5)*(3*FRACUNIT/4); - mo->vel.x = (pr_pottery.Random2())<<(FRACBITS-6); - mo->vel.y = (pr_pottery.Random2())<<(FRACBITS-6); + mo->Vel.X = pr_pottery.Random2() / 64.; + mo->Vel.Y = pr_pottery.Random2() / 64.; + mo->Vel.Z = ((pr_pottery() & 7) + 5) * 0.75; } } S_Sound (mo, CHAN_BODY, "PotteryExplode", 1, ATTN_NORM); @@ -117,7 +117,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryCheck) if (playeringame[i]) { AActor *pmo = players[i].mo; - if (P_CheckSight (self, pmo) && (absangle(pmo->AngleTo(self) - pmo->angle) <= ANGLE_45)) + if (P_CheckSight (self, pmo) && (absangle(pmo->AngleTo(self), pmo->Angles.Yaw) <= 45)) { // Previous state (pottery bit waiting state) self->SetState (self->state - 1); return 0; @@ -141,7 +141,7 @@ IMPLEMENT_CLASS (AZCorpseLynchedNoHeart) void AZCorpseLynchedNoHeart::PostBeginPlay () { Super::PostBeginPlay (); - Spawn ("BloodPool", X(), Y(), floorz, ALLOW_REPLACE); + Spawn ("BloodPool", PosAtZ(floorz), ALLOW_REPLACE); } //============================================================================ @@ -156,7 +156,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseBloodDrip) if (pr_drip() <= 128) { - Spawn ("CorpseBloodDrip", self->PosPlusZ(self->height/2), ALLOW_REPLACE); + Spawn ("CorpseBloodDrip", self->PosPlusZ(self->Height / 2), ALLOW_REPLACE); } return 0; } @@ -180,9 +180,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode) if (mo) { mo->SetState (mo->SpawnState + (pr_foo()%3)); - mo->vel.z = ((pr_foo()&7)+5)*(3*FRACUNIT/4); - mo->vel.x = pr_foo.Random2()<<(FRACBITS-6); - mo->vel.y = pr_foo.Random2()<<(FRACBITS-6); + mo->Vel.X = pr_foo.Random2() / 64.; + mo->Vel.Y = pr_foo.Random2() / 64.; + mo->Vel.Z = ((pr_foo() & 7) + 5) * 0.75; } } // Spawn a skull @@ -190,9 +190,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode) if (mo) { mo->SetState (mo->SpawnState + 3); - mo->vel.z = ((pr_foo()&7)+5)*(3*FRACUNIT/4); - mo->vel.x = pr_foo.Random2()<<(FRACBITS-6); - mo->vel.y = pr_foo.Random2()<<(FRACBITS-6); + mo->Vel.X = pr_foo.Random2() / 64.; + mo->Vel.Y = pr_foo.Random2() / 64.; + mo->Vel.Z = ((pr_foo() & 7) + 5) * 0.75; } S_Sound (self, CHAN_BODY, self->DeathSound, 1, ATTN_IDLE); self->Destroy (); @@ -214,15 +214,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn) for (i = (pr_leaf()&3)+1; i; i--) { - fixed_t xo = (pr_leaf.Random2() << 14); - fixed_t yo = (pr_leaf.Random2() << 14); - fixed_t zo = (pr_leaf() << 14); + double xo = pr_leaf.Random2() / 4.; + double yo = pr_leaf.Random2() / 4.; + double zo = pr_leaf() / 4.; mo = Spawn (pr_leaf()&1 ? PClass::FindActor ("Leaf1") : PClass::FindActor ("Leaf2"), self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { - P_ThrustMobj (mo, self->angle, (pr_leaf()<<9)+3*FRACUNIT); + mo->Thrust(pr_leaf() / 128. + 3); mo->target = self; mo->special1 = 0; } @@ -242,7 +242,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafThrust) if (pr_leafthrust() <= 96) { - self->vel.z += (pr_leafthrust()<<9)+FRACUNIT; + self->Vel.Z += pr_leafthrust() / 128. + 1; } return 0; } @@ -263,18 +263,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck) self->SetState (NULL); return 0; } - angle_t ang = self->target ? self->target->angle : self->angle; + DAngle ang = self->target ? self->target->Angles.Yaw : self->Angles.Yaw; if (pr_leafcheck() > 64) { - if (!self->vel.x && !self->vel.y) + if (self->Vel.X == 0 && self->Vel.Y == 0) { - P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+FRACUNIT); + self->Thrust(ang, pr_leafcheck() / 128. + 1); } return 0; } self->SetState (self->SpawnState + 7); - self->vel.z = (pr_leafcheck()<<9)+FRACUNIT; - P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+2*FRACUNIT); + self->Vel.Z = pr_leafcheck() / 128. + 1; + self->Thrust(ang, pr_leafcheck() / 128. + 2); self->flags |= MF_MISSILE; return 0; } @@ -289,7 +289,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonShroom) { PARAM_ACTION_PROLOGUE; - self->tics = 128+(pr_shroom()<<1); + self->tics = 128 + (pr_shroom() << 1); return 0; } @@ -308,16 +308,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode) for (i = 0; i < 10; i++) { - fixed_t xo = ((pr_soaexplode() - 128) << 12); - fixed_t yo = ((pr_soaexplode() - 128) << 12); - fixed_t zo = (pr_soaexplode()*self->height / 256); + double xo = (pr_soaexplode() - 128) / 16.; + double yo = (pr_soaexplode() - 128) / 16.; + double zo = pr_soaexplode()*self->Height / 256.; mo = Spawn ("ZArmorChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { mo->SetState (mo->SpawnState + i); - mo->vel.z = ((pr_soaexplode()&7)+5)*FRACUNIT; - mo->vel.x = pr_soaexplode.Random2()<<(FRACBITS-6); - mo->vel.y = pr_soaexplode.Random2()<<(FRACBITS-6); + mo->Vel.X = pr_soaexplode.Random2() / 64.; + mo->Vel.Y = pr_soaexplode.Random2() / 64.; + mo->Vel.Z = (pr_soaexplode() & 7) + 5; } } // Spawn an item? @@ -365,7 +365,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset1) PARAM_ACTION_PROLOGUE; self->flags |= MF_NOGRAVITY; - self->height <<= 2; + self->Height *= 4; if (self->special) { // Initiate death action P_ExecuteSpecial(self->special, NULL, NULL, false, self->args[0], diff --git a/src/g_hexen/a_iceguy.cpp b/src/g_hexen/a_iceguy.cpp index babc14f8f..d00e86041 100644 --- a/src/g_hexen/a_iceguy.cpp +++ b/src/g_hexen/a_iceguy.cpp @@ -28,19 +28,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook) { PARAM_ACTION_PROLOGUE; - fixed_t dist; - fixed_t an; + double dist; + DAngle an; CALL_ACTION(A_Look, self); if (pr_iceguylook() < 64) { - dist = ((pr_iceguylook()-128)*self->radius)>>7; - an = (self->angle+ANG90)>>ANGLETOFINESHIFT; - - Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Offset( - FixedMul(dist, finecosine[an]), - FixedMul(dist, finesine[an]), - 60 * FRACUNIT), ALLOW_REPLACE); + dist = (pr_iceguylook() - 128) * self->radius / 128.; + an = self->Angles.Yaw + 90; + Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Angle(dist, an, 60.), ALLOW_REPLACE); } return 0; } @@ -55,25 +51,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase) { PARAM_ACTION_PROLOGUE; - fixed_t dist; - fixed_t an; + double dist; + DAngle an; AActor *mo; - A_Chase (stack, self); + A_Chase(stack, self); if (pr_iceguychase() < 128) { - dist = ((pr_iceguychase()-128)*self->radius)>>7; - an = (self->angle+ANG90)>>ANGLETOFINESHIFT; - - mo = Spawn(WispTypes[pr_iceguychase() & 1], self->Vec3Offset( - FixedMul(dist, finecosine[an]), - FixedMul(dist, finesine[an]), - 60 * FRACUNIT), ALLOW_REPLACE); + dist = (pr_iceguychase() - 128) * self->radius / 128.; + an = self->Angles.Yaw + 90; + mo = Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Angle(dist, an, 60.), ALLOW_REPLACE); if (mo) { - mo->vel.x = self->vel.x; - mo->vel.y = self->vel.y; - mo->vel.z = self->vel.z; + mo->Vel = self->Vel; mo->target = self; } } @@ -94,8 +84,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyAttack) { return 0; } - P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle+ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX")); - P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle-ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX")); + P_SpawnMissileXYZ(self->Vec3Angle(self->radius / 2, self->Angles.Yaw + 90, 40.), self, self->target, PClass::FindActor("IceGuyFX")); + P_SpawnMissileXYZ(self->Vec3Angle(self->radius / 2, self->Angles.Yaw - 90, 40.), self, self->target, PClass::FindActor("IceGuyFX")); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); return 0; } @@ -110,10 +100,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyDie) { PARAM_ACTION_PROLOGUE; - self->vel.x = 0; - self->vel.y = 0; - self->vel.z = 0; - self->height = self->GetDefault()->height; + self->Vel.Zero(); + self->Height = self->GetDefault()->Height; CALL_ACTION(A_FreezeDeathChunks, self); return 0; } @@ -133,8 +121,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyMissileExplode) for (i = 0; i < 8; i++) { - mo = P_SpawnMissileAngleZ (self, self->Z()+3*FRACUNIT, - PClass::FindActor("IceGuyFX2"), i*ANG45, (fixed_t)(-0.3*FRACUNIT)); + mo = P_SpawnMissileAngleZ (self, self->Z()+3, PClass::FindActor("IceGuyFX2"), DAngle(i*45.), -0.3); if (mo) { mo->target = self->target; diff --git a/src/g_hexen/a_korax.cpp b/src/g_hexen/a_korax.cpp index fdcf95365..2597fe8cd 100644 --- a/src/g_hexen/a_korax.cpp +++ b/src/g_hexen/a_korax.cpp @@ -37,18 +37,18 @@ const int KORAX_TID = 245; const int KORAX_FIRST_TELEPORT_TID = 248; const int KORAX_TELEPORT_TID = 249; -const int KORAX_DELTAANGLE = 85*ANGLE_1; +const int KORAX_DELTAANGLE = 85; const int KORAX_ARM_EXTENSION_SHORT = 40; const int KORAX_ARM_EXTENSION_LONG = 55; -const int KORAX_ARM1_HEIGHT = 108*FRACUNIT; -const int KORAX_ARM2_HEIGHT = 82*FRACUNIT; -const int KORAX_ARM3_HEIGHT = 54*FRACUNIT; -const int KORAX_ARM4_HEIGHT = 104*FRACUNIT; -const int KORAX_ARM5_HEIGHT = 86*FRACUNIT; -const int KORAX_ARM6_HEIGHT = 53*FRACUNIT; +const int KORAX_ARM1_HEIGHT = 108; +const int KORAX_ARM2_HEIGHT = 82; +const int KORAX_ARM3_HEIGHT = 54; +const int KORAX_ARM4_HEIGHT = 104; +const int KORAX_ARM5_HEIGHT = 86; +const int KORAX_ARM6_HEIGHT = 53; -const int KORAX_BOLT_HEIGHT = 48*FRACUNIT; +const double KORAX_BOLT_HEIGHT = 48.; const int KORAX_BOLT_LIFETIME = 3; @@ -76,8 +76,7 @@ void A_KBoltRaise (AActor *); void KoraxFire (AActor *actor, PClassActor *type, int arm); void KSpiritInit (AActor *spirit, AActor *korax); -AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z, - AActor *source, AActor *dest, PClassActor *type); +AActor *P_SpawnKoraxMissile (const DVector3 &pos, AActor *source, AActor *dest, PClassActor *type); extern void SpawnSpiritTail (AActor *spirit); @@ -99,7 +98,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase) spot = iterator.Next (); if (spot != NULL) { - P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, TELF_SOURCEFOG | TELF_DESTFOG); + P_Teleport (self, spot->PosAtZ(ONFLOORZ), spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG); } P_StartScript (self, NULL, 249, NULL, NULL, 0, 0); @@ -141,7 +140,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase) self->tracer = spot; if (spot) { - P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, TELF_SOURCEFOG | TELF_DESTFOG); + P_Teleport (self, spot->PosAtZ(ONFLOORZ), spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG); } } } @@ -164,7 +163,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxBonePop) // Spawn 6 spirits equalangularly for (i = 0; i < 6; ++i) { - mo = P_SpawnMissileAngle (self, PClass::FindActor("KoraxSpirit"), ANGLE_60*i, 5*FRACUNIT); + mo = P_SpawnMissileAngle (self, PClass::FindActor("KoraxSpirit"), DAngle(60.*i), 5.); if (mo) { KSpiritInit (mo, self); @@ -186,7 +185,7 @@ void KSpiritInit (AActor *spirit, AActor *korax) spirit->health = KORAX_SPIRIT_LIFETIME; spirit->tracer = korax; // Swarm around korax - spirit->special2 = FINEANGLES/2 + pr_kspiritinit(8 << BOBTOFINESHIFT); // Float bob index + spirit->WeaveIndexZ = 32 + (pr_kspiritinit() & 7); // Float bob index spirit->args[0] = 10; // initial turn value spirit->args[1] = 0; // initial look angle @@ -235,23 +234,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile) { "SerpentFX", "CentaurLeaderAttack" } }; - int type = pr_koraxmissile()%6; + int type = pr_koraxmissile() % 6; int i; PClassActor *info; - S_Sound (self, CHAN_VOICE, "KoraxAttack", 1, ATTN_NORM); + S_Sound(self, CHAN_VOICE, "KoraxAttack", 1, ATTN_NORM); info = PClass::FindActor(choices[type].type); if (info == NULL) { - I_Error ("Unknown Korax missile: %s\n", choices[type].type); + I_Error("Unknown Korax missile: %s\n", choices[type].type); } // Fire all 6 missiles at once - S_Sound (self, CHAN_WEAPON, choices[type].sound, 1, ATTN_NONE); + S_Sound(self, CHAN_WEAPON, choices[type].sound, 1, ATTN_NONE); for (i = 0; i < 6; ++i) { - KoraxFire (self, info, i); + KoraxFire(self, info, i); } return 0; } @@ -267,17 +266,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxMissile) DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand) { PARAM_ACTION_PROLOGUE; - angle_t ang; + DAngle ang; int numcommands; S_Sound (self, CHAN_VOICE, "KoraxCommand", 1, ATTN_NORM); // Shoot stream of lightning to ceiling - ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; - fixedvec3 pos = self->Vec3Offset( - KORAX_COMMAND_OFFSET * finecosine[ang], - KORAX_COMMAND_OFFSET * finesine[ang], - KORAX_COMMAND_HEIGHT*FRACUNIT); + ang = self->Angles.Yaw - 90; + DVector3 pos = self->Vec3Angle(KORAX_COMMAND_OFFSET, ang, KORAX_COMMAND_HEIGHT); Spawn("KoraxBolt", pos, ALLOW_REPLACE); if (self->health <= (self->SpawnHealth() >> 1)) @@ -319,7 +315,7 @@ void KoraxFire (AActor *actor, PClassActor *type, int arm) KORAX_ARM_EXTENSION_LONG, KORAX_ARM_EXTENSION_LONG }; - static const fixed_t armheight[6] = + static const int armheight[6] = { KORAX_ARM1_HEIGHT, KORAX_ARM2_HEIGHT, @@ -329,40 +325,24 @@ void KoraxFire (AActor *actor, PClassActor *type, int arm) KORAX_ARM6_HEIGHT }; - angle_t ang; - - ang = (actor->angle + (arm < 3 ? -KORAX_DELTAANGLE : KORAX_DELTAANGLE)) >> ANGLETOFINESHIFT; - fixedvec3 pos = actor->Vec3Offset( - extension[arm] * finecosine[ang], - extension[arm] * finesine[ang], - -actor->floorclip + armheight[arm]); - P_SpawnKoraxMissile (pos.x, pos.y, pos.z, actor, actor->target, type); + DAngle ang = actor->Angles.Yaw + (arm < 3 ? -KORAX_DELTAANGLE : KORAX_DELTAANGLE); + DVector3 pos = actor->Vec3Angle(extension[arm], ang, armheight[arm] - actor->Floorclip); + P_SpawnKoraxMissile (pos, actor, actor->target, type); } -//============================================================================ -// -// A_KSpiritWeave -// [BL] Was identical to CHolyWeave so lets just use that -// -//============================================================================ - -void CHolyWeave (AActor *actor, FRandom &pr_random); - //============================================================================ // // A_KSpiritSeeker // //============================================================================ -void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax) +static void A_KSpiritSeeker (AActor *actor, DAngle thresh, DAngle turnMax) { int dir; - int dist; - angle_t delta; - angle_t angle; + DAngle delta; AActor *target; - fixed_t newZ; - fixed_t deltaZ; + double newZ; + double deltaZ; target = actor->tracer; if (target == NULL) @@ -372,7 +352,7 @@ void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax) dir = P_FaceMobj (actor, target, &delta); if (delta > thresh) { - delta >>= 1; + delta /= 2; if(delta > turnMax) { delta = turnMax; @@ -380,39 +360,33 @@ void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax) } if(dir) { // Turn clockwise - actor->angle += delta; + actor->Angles.Yaw += delta; } else { // Turn counter clockwise - actor->angle -= delta; + actor->Angles.Yaw -= delta; } - angle = actor->angle>>ANGLETOFINESHIFT; - actor->vel.x = FixedMul (actor->Speed, finecosine[angle]); - actor->vel.y = FixedMul (actor->Speed, finesine[angle]); + actor->VelFromAngle(); if (!(level.time&15) - || actor->Z() > target->Z()+(target->GetDefault()->height) + || actor->Z() > target->Z() + target->GetDefault()->Height || actor->Top() < target->Z()) { - newZ = target->Z()+((pr_kspiritseek()*target->GetDefault()->height)>>8); + newZ = target->Z() + pr_kspiritseek() * target->GetDefault()->Height / 256; deltaZ = newZ-actor->Z(); - if (abs(deltaZ) > 15*FRACUNIT) + + if (fabs(deltaZ) > 15) { if(deltaZ > 0) { - deltaZ = 15*FRACUNIT; + deltaZ = 15; } else { - deltaZ = -15*FRACUNIT; + deltaZ = -15; } } - dist = actor->AproxDistance (target) / actor->Speed; - if (dist < 1) - { - dist = 1; - } - actor->vel.z = deltaZ/dist; + actor->Vel.Z = deltaZ + actor->DistanceBySpeed(target, actor->Speed); } return; } @@ -436,10 +410,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_KSpiritRoam) { if (self->tracer) { - A_KSpiritSeeker (self, self->args[0]*ANGLE_1, - self->args[0]*ANGLE_1*2); + A_KSpiritSeeker(self, (double)self->args[0], self->args[0] * 2.); } - CHolyWeave(self, pr_kspiritweave); + int xyspeed = (pr_kspiritweave() % 5); + int zspeed = (pr_kspiritweave() % 5); + A_Weave(self, xyspeed, zspeed, 4., 2.); + if (pr_kspiritroam()<50) { S_Sound (self, CHAN_VOICE, "SpiritActive", 1, ATTN_NONE); @@ -477,14 +453,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise) PARAM_ACTION_PROLOGUE; AActor *mo; - fixed_t z; // Spawn a child upward - z = self->Z() + KORAX_BOLT_HEIGHT; + double z = self->Z() + KORAX_BOLT_HEIGHT; if ((z + KORAX_BOLT_HEIGHT) < self->ceilingz) { - mo = Spawn("KoraxBolt", self->X(), self->Y(), z, ALLOW_REPLACE); + mo = Spawn("KoraxBolt", self->PosAtZ(z), ALLOW_REPLACE); if (mo) { mo->special1 = KORAX_BOLT_LIFETIME; @@ -503,30 +478,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise) // //============================================================================ -AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z, - AActor *source, AActor *dest, PClassActor *type) +AActor *P_SpawnKoraxMissile (const DVector3 &pos, AActor *source, AActor *dest, PClassActor *type) { AActor *th; - angle_t an; - int dist; + DAngle an; + double dist; - z -= source->floorclip; - th = Spawn (type, x, y, z, ALLOW_REPLACE); + th = Spawn (type, source->PosPlusZ(-source->Floorclip), ALLOW_REPLACE); th->target = source; // Originator an = th->AngleTo(dest); if (dest->flags & MF_SHADOW) { // Invisible target - an += pr_kmissile.Random2()<<21; + an += pr_kmissile.Random2() * (45/256.); } - th->angle = an; - an >>= ANGLETOFINESHIFT; - th->vel.x = FixedMul (th->Speed, finecosine[an]); - th->vel.y = FixedMul (th->Speed, finesine[an]); - dist = dest->AproxDistance (th) / th->Speed; - if (dist < 1) - { - dist = 1; - } - th->vel.z = (dest->Z()-z+(30*FRACUNIT))/dist; + th->Angles.Yaw = an; + th->VelFromAngle(); + dist = dest->DistanceBySpeed(th, th->Speed); + th->Vel.Z = (dest->Z() - pos.Z + 30) / dist; return (P_CheckMissileSpawn(th, source->radius) ? th : NULL); } diff --git a/src/g_hexen/a_magecone.cpp b/src/g_hexen/a_magecone.cpp index 69cc31f4f..f31e57e58 100644 --- a/src/g_hexen/a_magecone.cpp +++ b/src/g_hexen/a_magecone.cpp @@ -53,9 +53,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; int i; AActor *mo; bool conedone=false; @@ -78,11 +78,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1) damage = 90+(pr_cone()&15); for (i = 0; i < 16; i++) { - angle = self->angle+i*(ANG45/16); - slope = P_AimLineAttack (self, angle, MELEERANGE, &t, 0, ALF_CHECK3D); + angle = self->Angles.Yaw + i*(45./16); + slope = P_AimLineAttack (self, angle, MELEERANGE, &t, 0., ALF_CHECK3D); if (t.linetarget) { - P_DamageMobj (t.linetarget, self, self, damage, NAME_Ice, DMG_USEANGLE, t.angleFromSource); + P_DamageMobj (t.linetarget, self, self, damage, NAME_Ice, DMG_USEANGLE, t.angleFromSource.Degrees); conedone = true; break; } @@ -128,35 +128,35 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard) // every so many calls, spawn a new missile in its set directions if (spawndir & SHARDSPAWN_LEFT) { - mo = P_SpawnMissileAngleZSpeed (self, self->Z(), RUNTIME_CLASS(AFrostMissile), self->angle+(ANG45/9), - 0, (20+2*spermcount)<target); + mo = P_SpawnMissileAngleZSpeed(self, self->Z(), RUNTIME_CLASS(AFrostMissile), + self->Angles.Yaw + 5, 0, (20. + 2 * spermcount), self->target); if (mo) { mo->special1 = SHARDSPAWN_LEFT; mo->special2 = spermcount; - mo->vel.z = self->vel.z; + mo->Vel.Z = self->Vel.Z; mo->args[0] = (spermcount==3)?2:0; } } if (spawndir & SHARDSPAWN_RIGHT) { - mo = P_SpawnMissileAngleZSpeed (self, self->Z(), RUNTIME_CLASS(AFrostMissile), self->angle-(ANG45/9), - 0, (20+2*spermcount)<target); + mo = P_SpawnMissileAngleZSpeed(self, self->Z(), RUNTIME_CLASS(AFrostMissile), + self->Angles.Yaw - 5, 0, (20. + 2 * spermcount), self->target); if (mo) { mo->special1 = SHARDSPAWN_RIGHT; mo->special2 = spermcount; - mo->vel.z = self->vel.z; + mo->Vel.Z = self->Vel.Z; mo->args[0] = (spermcount==3)?2:0; } } if (spawndir & SHARDSPAWN_UP) { - mo = P_SpawnMissileAngleZSpeed (self, self->Z()+8*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->angle, - 0, (15+2*spermcount)<target); + mo = P_SpawnMissileAngleZSpeed(self, self->Z() + 8., RUNTIME_CLASS(AFrostMissile), + self->Angles.Yaw, 0, (15. + 2 * spermcount), self->target); if (mo) { - mo->vel.z = self->vel.z; + mo->Vel.Z = self->Vel.Z; if (spermcount & 1) // Every other reproduction mo->special1 = SHARDSPAWN_UP | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT; else @@ -167,11 +167,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard) } if (spawndir & SHARDSPAWN_DOWN) { - mo = P_SpawnMissileAngleZSpeed (self, self->Z()-4*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->angle, - 0, (15+2*spermcount)<target); + mo = P_SpawnMissileAngleZSpeed(self, self->Z() - 4., RUNTIME_CLASS(AFrostMissile), + self->Angles.Yaw, 0, (15. + 2 * spermcount), self->target); if (mo) { - mo->vel.z = self->vel.z; + mo->Vel.Z = self->Vel.Z; if (spermcount & 1) // Every other reproduction mo->special1 = SHARDSPAWN_DOWN | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT; else diff --git a/src/g_hexen/a_magelightning.cpp b/src/g_hexen/a_magelightning.cpp index 2c9b0d8c1..b5718f4d7 100644 --- a/src/g_hexen/a_magelightning.cpp +++ b/src/g_hexen/a_magelightning.cpp @@ -14,7 +14,7 @@ #include "g_level.h" */ -#define ZAGSPEED FRACUNIT +#define ZAGSPEED 1. static FRandom pr_lightningready ("LightningReady"); static FRandom pr_lightningclip ("LightningClip"); @@ -42,8 +42,8 @@ int ALightning::SpecialMissileHit (AActor *thing) { if (thing->Mass != INT_MAX) { - thing->vel.x += vel.x>>4; - thing->vel.y += vel.y>>4; + thing->Vel.X += Vel.X / 16; + thing->Vel.Y += Vel.Y / 16; } if ((!thing->player && !(thing->flags2&MF2_BOSS)) || !(level.time&1)) @@ -161,7 +161,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip) } else if (self->flags3 & MF3_CEILINGHUGGER) { - self->SetZ(self->ceilingz-self->height); + self->SetZ(self->ceilingz - self->Height); target = self->tracer; } if (self->flags3 & MF3_FLOORHUGGER) @@ -170,19 +170,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip) zigZag = pr_lightningclip(); if((zigZag > 128 && self->special1 < 2) || self->special1 < -2) { - P_ThrustMobj(self, self->angle+ANG90, ZAGSPEED); + self->Thrust(self->Angles.Yaw + 90, ZAGSPEED); if(cMo) { - P_ThrustMobj(cMo, self->angle+ANG90, ZAGSPEED); + cMo->Thrust(self->Angles.Yaw + 90, ZAGSPEED); } self->special1++; } else { - P_ThrustMobj(self, self->angle-ANG90, ZAGSPEED); + self->Thrust(self->Angles.Yaw - 90, ZAGSPEED); if(cMo) { - P_ThrustMobj(cMo, cMo->angle-ANG90, ZAGSPEED); + cMo->Thrust(self->Angles.Yaw - 90, ZAGSPEED); } self->special1--; } @@ -195,10 +195,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip) } else { - self->angle = self->AngleTo(target); - self->vel.x = 0; - self->vel.y = 0; - P_ThrustMobj (self, self->angle, self->Speed>>1); + self->Angles.Yaw = self->AngleTo(target); + self->VelFromAngle(self->Speed / 2); } } return 0; @@ -217,7 +215,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap) PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName); AActor *mo; - fixed_t deltaZ; if (lightning == NULL) { @@ -232,32 +229,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap) self->SetState (self->FindState(NAME_Death)); return 0; } - if (self->flags3 & MF3_FLOORHUGGER) - { - deltaZ = 10*FRACUNIT; - } - else - { - deltaZ = -10*FRACUNIT; - } - fixed_t xo = ((pr_zap() - 128)*self->radius / 256); - fixed_t yo = ((pr_zap() - 128)*self->radius / 256); + double deltaX = (pr_zap() - 128) * self->radius / 256; + double deltaY = (pr_zap() - 128) * self->radius / 256; + double deltaZ = (self->flags3 & MF3_FLOORHUGGER) ? 10 : -10; - mo = Spawn(lightning, self->Vec3Offset(xo, yo, deltaZ), ALLOW_REPLACE); + mo = Spawn(lightning, self->Vec3Offset(deltaX, deltaY, deltaZ), ALLOW_REPLACE); if (mo) { mo->lastenemy = self; - mo->vel.x = self->vel.x; - mo->vel.y = self->vel.y; + mo->Vel.X = self->Vel.X; + mo->Vel.Y = self->Vel.Y; + mo->Vel.Z = (self->flags3 & MF3_FLOORHUGGER) ? 20 : -20; mo->target = self->target; - if (self->flags3 & MF3_FLOORHUGGER) - { - mo->vel.z = 20*FRACUNIT; - } - else - { - mo->vel.z = -20*FRACUNIT; - } } if ((self->flags3 & MF3_FLOORHUGGER) && pr_zapf() < 160) { @@ -328,8 +311,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic) } else { - self->vel.x = mo->vel.x; - self->vel.y = mo->vel.y; + self->Vel.X = mo->Vel.X; + self->Vel.Y = mo->Vel.Y; } } return 0; @@ -356,7 +339,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LastZap) if (mo) { mo->SetState (mo->FindState (NAME_Death)); - mo->vel.z = 40*FRACUNIT; + mo->Vel.Z = 40; mo->Damage = NULL; } return 0; diff --git a/src/g_hexen/a_magestaff.cpp b/src/g_hexen/a_magestaff.cpp index ee31257d6..1bd20715d 100644 --- a/src/g_hexen/a_magestaff.cpp +++ b/src/g_hexen/a_magestaff.cpp @@ -64,7 +64,7 @@ class AMageStaffFX2 : public AActor DECLARE_CLASS(AMageStaffFX2, AActor) public: int SpecialMissileHit (AActor *victim); - bool SpecialBlastHandling (AActor *source, fixed_t strength); + bool SpecialBlastHandling (AActor *source, double strength); }; IMPLEMENT_CLASS (AMageStaffFX2) @@ -81,7 +81,7 @@ int AMageStaffFX2::SpecialMissileHit (AActor *victim) return -1; } -bool AMageStaffFX2::SpecialBlastHandling (AActor *source, fixed_t strength) +bool AMageStaffFX2::SpecialBlastHandling (AActor *source, double strength) { // Reflect to originator tracer = target; @@ -97,13 +97,12 @@ bool AMageStaffFX2::SpecialBlastHandling (AActor *source, fixed_t strength) // //============================================================================ -void MStaffSpawn (AActor *pmo, angle_t angle, AActor *alttarget) +void MStaffSpawn (AActor *pmo, DAngle angle, AActor *alttarget) { AActor *mo; FTranslatedLineTarget t; - mo = P_SpawnPlayerMissile (pmo, 0, 0, 8*FRACUNIT, - RUNTIME_CLASS(AMageStaffFX2), angle, &t); + mo = P_SpawnPlayerMissile (pmo, 0, 0, 8, RUNTIME_CLASS(AMageStaffFX2), angle, &t); if (mo) { mo->target = pmo; @@ -124,7 +123,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; player_t *player; FTranslatedLineTarget t; @@ -139,21 +138,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - angle = self->angle; + angle = self->Angles.Yaw; // [RH] Let's try and actually track what the player aimed at - P_AimLineAttack (self, angle, PLAYERMISSILERANGE, &t, ANGLE_1*32); + P_AimLineAttack (self, angle, PLAYERMISSILERANGE, &t, 32.); if (t.linetarget == NULL) { BlockCheckLine.x = self->X(); BlockCheckLine.y = self->Y(); - BlockCheckLine.dx = -finesine[angle >> ANGLETOFINESHIFT]; - BlockCheckLine.dy = -finecosine[angle >> ANGLETOFINESHIFT]; + BlockCheckLine.dx = -angle.Sin(); + BlockCheckLine.dy = -angle.Cos(); t.linetarget = P_BlockmapSearch (self, 10, FrontBlockCheck); } MStaffSpawn (self, angle, t.linetarget); - MStaffSpawn (self, angle-ANGLE_1*5, t.linetarget); - MStaffSpawn (self, angle+ANGLE_1*5, t.linetarget); + MStaffSpawn (self, angle-5, t.linetarget); + MStaffSpawn (self, angle+5, t.linetarget); S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM); weapon->MStaffCount = 3; return 0; @@ -194,7 +193,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffTrack) { self->tracer = P_RoughMonsterSearch (self, 10, true); } - P_SeekerMissile (self, ANGLE_1*2, ANGLE_1*10); + P_SeekerMissile(self, 2, 10); return 0; } @@ -214,7 +213,7 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *) { if (link->Me != mo) { - if (P_PointOnDivlineSide (link->Me->X(), link->Me->Y(), &BlockCheckLine) == 0 && + if (P_PointOnDivlineSide(link->Me->X(), link->Me->Y(), &BlockCheckLine) == 0 && mo->IsOkayToAttack (link->Me)) { return link->Me; @@ -230,12 +229,11 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *) // //============================================================================ -void MStaffSpawn2 (AActor *actor, angle_t angle) +void MStaffSpawn2 (AActor *actor, DAngle angle) { AActor *mo; - mo = P_SpawnMissileAngleZ (actor, actor->Z()+40*FRACUNIT, - RUNTIME_CLASS(AMageStaffFX2), angle, 0); + mo = P_SpawnMissileAngleZ (actor, actor->Z()+40, RUNTIME_CLASS(AMageStaffFX2), angle, 0.); if (mo) { mo->target = actor; @@ -257,11 +255,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_MageAttack) { return 0; } - angle_t angle; - angle = self->angle; - MStaffSpawn2 (self, angle); - MStaffSpawn2 (self, angle-ANGLE_1*5); - MStaffSpawn2 (self, angle+ANGLE_1*5); - S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM); + DAngle angle = self->Angles.Yaw; + MStaffSpawn2(self, angle); + MStaffSpawn2(self, angle - 5); + MStaffSpawn2(self, angle + 5); + S_Sound(self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM); return 0; } diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index 4d3201ac4..b53442c14 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -35,7 +35,7 @@ void APigPlayer::MorphPlayerThink () { return; } - if(!(vel.x | vel.y) && pr_pigplayerthink() < 64) + if(Vel.X == 0 && Vel.Y == 0 && pr_pigplayerthink() < 64) { // Snout sniff if (player->ReadyWeapon != NULL) { @@ -60,9 +60,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; player_t *player; AActor *puff; FTranslatedLineTarget t; @@ -73,7 +73,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack) } damage = 3+(pr_snoutattack()&3); - angle = player->mo->angle; + angle = player->mo->Angles.Yaw; slope = P_AimLineAttack(player->mo, angle, MELEERANGE); puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "SnoutPuff", true, &t); S_Sound(player->mo, CHAN_VOICE, "PigActive", 1, ATTN_NORM); @@ -101,7 +101,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PigPain) CALL_ACTION(A_Pain, self); if (self->Z() <= self->floorz) { - self->vel.z = FRACUNIT*7/2; + self->Vel.Z = 3.5; } return 0; } diff --git a/src/g_hexen/a_serpent.cpp b/src/g_hexen/a_serpent.cpp index 07863edd7..998466053 100644 --- a/src/g_hexen/a_serpent.cpp +++ b/src/g_hexen/a_serpent.cpp @@ -28,7 +28,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentUnHide) PARAM_ACTION_PROLOGUE; self->renderflags &= ~RF_INVISIBLE; - self->floorclip = 24*FRACUNIT; + self->Floorclip = 24; return 0; } @@ -43,7 +43,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentHide) PARAM_ACTION_PROLOGUE; self->renderflags |= RF_INVISIBLE; - self->floorclip = 0; + self->Floorclip = 0; return 0; } @@ -58,7 +58,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentRaiseHump) { PARAM_ACTION_PROLOGUE; - self->floorclip -= 4*FRACUNIT; + self->Floorclip -= 4; return 0; } @@ -72,7 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentLowerHump) { PARAM_ACTION_PROLOGUE; - self->floorclip += 4*FRACUNIT; + self->Floorclip += 4; return 0; } @@ -228,17 +228,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs) for (int i = countof(GibTypes)-1; i >= 0; --i) { - fixedvec2 pos = self->Vec2Offset( - ((pr_serpentgibs() - 128) << 12), - ((pr_serpentgibs() - 128) << 12)); + double x = (pr_serpentgibs() - 128) / 16.; + double y = (pr_serpentgibs() - 128) / 16.; - mo = Spawn (GibTypes[i], pos.x, pos.y, - self->floorz+FRACUNIT, ALLOW_REPLACE); + mo = Spawn (GibTypes[i], self->Vec2OffsetZ(x, y, self->floorz + 1), ALLOW_REPLACE); if (mo) { - mo->vel.x = (pr_serpentgibs()-128)<<6; - mo->vel.y = (pr_serpentgibs()-128)<<6; - mo->floorclip = 6*FRACUNIT; + mo->Vel.X = (pr_serpentgibs() - 128) / 1024.f; + mo->Vel.Y = (pr_serpentgibs() - 128) / 1024.f; + mo->Floorclip = 6; } } return 0; @@ -254,7 +252,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FloatGib) { PARAM_ACTION_PROLOGUE; - self->floorclip -= FRACUNIT; + self->Floorclip -= 1; return 0; } @@ -268,7 +266,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SinkGib) { PARAM_ACTION_PROLOGUE; - self->floorclip += FRACUNIT; + self->Floorclip += 1;; return 0; } diff --git a/src/g_hexen/a_spike.cpp b/src/g_hexen/a_spike.cpp index 3943bee30..4770f5d3a 100644 --- a/src/g_hexen/a_spike.cpp +++ b/src/g_hexen/a_spike.cpp @@ -82,7 +82,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitUp) self->special2 = 5; // Raise speed self->args[0] = 1; // Mark as up - self->floorclip = 0; + self->Floorclip = 0; self->flags = MF_SOLID; self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP; self->special1 = 0L; @@ -95,7 +95,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitDn) self->special2 = 5; // Raise speed self->args[0] = 0; // Mark as down - self->floorclip = self->GetDefault()->height; + self->Floorclip = self->GetDefault()->Height; self->flags = 0; self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP; self->renderflags = RF_INVISIBLE; @@ -111,7 +111,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise) AThrustFloor *actor = static_cast(self); - if (A_RaiseMobj (actor, self->special2*FRACUNIT)) + if (A_RaiseMobj (actor, self->special2)) { // Reached it's target height actor->args[0] = 1; if (actor->args[1]) @@ -121,7 +121,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise) } // Lose the dirt clump - if ((actor->floorclip < actor->height) && actor->DirtClump) + if ((actor->Floorclip < actor->Height) && actor->DirtClump) { actor->DirtClump->Destroy (); actor->DirtClump = NULL; @@ -138,7 +138,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower) { PARAM_ACTION_PROLOGUE; - if (A_SinkMobj (self, 6*FRACUNIT)) + if (A_SinkMobj (self, 6)) { self->args[0] = 0; if (self->args[1]) @@ -160,8 +160,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale) FMultiBlockThingsIterator::CheckResult cres; while (it.Next(&cres)) { - fixed_t blockdist = self->radius + cres.thing->radius; - if (abs(cres.thing->X() - cres.position.x) >= blockdist || abs(cres.thing->Y() - cres.position.y) >= blockdist) + double blockdist = self->radius + cres.thing->radius; + if (fabs(cres.thing->X() - cres.Position.X) >= blockdist || fabs(cres.thing->Y() - cres.Position.Y) >= blockdist) continue; // Q: Make this z-aware for everything? It never was before. diff --git a/src/g_hexen/a_summon.cpp b/src/g_hexen/a_summon.cpp index d50682dc9..eb5d825bf 100644 --- a/src/g_hexen/a_summon.cpp +++ b/src/g_hexen/a_summon.cpp @@ -36,7 +36,7 @@ bool AArtiDarkServant::Use (bool pickup) { mo->target = Owner; mo->tracer = Owner; - mo->vel.z = 5*FRACUNIT; + mo->Vel.Z = 5; } return true; } @@ -53,13 +53,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon) AMinotaurFriend *mo; - mo = Spawn (self->Pos(), ALLOW_REPLACE); + mo = Spawn(self->Pos(), ALLOW_REPLACE); if (mo) { if (P_TestMobjLocation(mo) == false || !self->tracer) { // Didn't fit - change back to artifact - mo->Destroy (); - AActor *arti = Spawn (self->Pos(), ALLOW_REPLACE); + mo->Destroy(); + AActor *arti = Spawn(self->Pos(), ALLOW_REPLACE); if (arti) arti->flags |= MF_DROPPED; return 0; } @@ -72,14 +72,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon) else { mo->tracer = self->tracer; // Pointer to master - AInventory *power = Spawn (0, 0, 0, NO_REPLACE); - power->CallTryPickup (self->tracer); + AInventory *power = Spawn(); + power->CallTryPickup(self->tracer); mo->SetFriendPlayer(self->tracer->player); } // Make smoke puff - Spawn ("MinotaurSmoke", self->Pos(), ALLOW_REPLACE); - S_Sound (self, CHAN_VOICE, mo->ActiveSound, 1, ATTN_NORM); + Spawn("MinotaurSmoke", self->Pos(), ALLOW_REPLACE); + S_Sound(self, CHAN_VOICE, mo->ActiveSound, 1, ATTN_NORM); } return 0; } diff --git a/src/g_hexen/a_teleportother.cpp b/src/g_hexen/a_teleportother.cpp index 3daca2103..7333d9d91 100644 --- a/src/g_hexen/a_teleportother.cpp +++ b/src/g_hexen/a_teleportother.cpp @@ -55,11 +55,9 @@ static void TeloSpawn (AActor *source, const char *type) if (fx) { fx->special1 = TELEPORT_LIFE; // Lifetime countdown - fx->angle = source->angle; + fx->Angles.Yaw = source->Angles.Yaw; fx->target = source->target; - fx->vel.x = source->vel.x >> 1; - fx->vel.y = source->vel.y >> 1; - fx->vel.z = source->vel.z >> 1; + fx->Vel = source->Vel / 2; } } @@ -166,14 +164,12 @@ int ATelOtherFX1::DoSpecialDamage (AActor *target, int damage, FName damagetype) void P_TeleportToPlayerStarts (AActor *victim) { - fixed_t destX,destY; - angle_t destAngle; + DVector3 dest; FPlayerStart *start = G_PickPlayerStart(0, PPS_FORCERANDOM | PPS_NOBLOCKINGCHECK); - destX = start->x; - destY = start->y; - destAngle = ANG45 * (start->angle/45); - P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG); + dest = start->pos; + dest.Z = ONFLOORZ; + P_Teleport (victim, dest, (double)start->angle, TELF_SOURCEFOG | TELF_DESTFOG); } //=========================================================================== @@ -185,17 +181,15 @@ void P_TeleportToPlayerStarts (AActor *victim) void P_TeleportToDeathmatchStarts (AActor *victim) { unsigned int i, selections; - fixed_t destX,destY; - angle_t destAngle; + DVector3 dest; selections = deathmatchstarts.Size (); if (selections > 0) { i = pr_teledm() % selections; - destX = deathmatchstarts[i].x; - destY = deathmatchstarts[i].y; - destAngle = ANG45 * (deathmatchstarts[i].angle/45); - P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG); + dest = deathmatchstarts[i].pos; + dest.Z = ONFLOORZ; + P_Teleport (victim, dest, (double)deathmatchstarts[i].angle, TELF_SOURCEFOG | TELF_DESTFOG); } else { diff --git a/src/g_hexen/a_wraith.cpp b/src/g_hexen/a_wraith.cpp index 44aa2c308..24ae22afd 100644 --- a/src/g_hexen/a_wraith.cpp +++ b/src/g_hexen/a_wraith.cpp @@ -15,12 +15,6 @@ static FRandom pr_wraithfx2 ("WraithFX2"); static FRandom pr_wraithfx3 ("WraithFX3"); static FRandom pr_wraithfx4 ("WraithFX4"); -//============================================================================ -// Wraith Variables -// -// special1 Internal index into floatbob -//============================================================================ - //============================================================================ // // A_WraithInit @@ -31,15 +25,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithInit) { PARAM_ACTION_PROLOGUE; - self->AddZ(48<AddZ(48); // [RH] Make sure the wraith didn't go into the ceiling if (self->Top() > self->ceilingz) { - self->SetZ(self->ceilingz - self->height); + self->SetZ(self->ceilingz - self->Height); } - self->special1 = 0; // index into floatbob + self->WeaveIndexZ = 0; // index into floatbob return 0; } @@ -57,7 +51,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaiseInit) self->flags2 &= ~MF2_NONSHOOTABLE; self->flags3 &= ~MF3_DONTBLAST; self->flags |= MF_SHOOTABLE|MF_SOLID; - self->floorclip = self->height; + self->Floorclip = self->Height; return 0; } @@ -71,7 +65,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaise) { PARAM_ACTION_PROLOGUE; - if (A_RaiseMobj (self, 2*FRACUNIT)) + if (A_RaiseMobj (self, 2)) { // Reached it's target height // [RH] Once a buried wraith is fully raised, it should be @@ -119,7 +113,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2) PARAM_ACTION_PROLOGUE; AActor *mo; - angle_t angle; + DAngle angle; int i; for (i = 2; i; --i) @@ -127,21 +121,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2) mo = Spawn ("WraithFX2", self->Pos(), ALLOW_REPLACE); if(mo) { - if (pr_wraithfx2 ()<128) + angle = pr_wraithfx2() * (360 / 1024.f); + if (pr_wraithfx2() >= 128) { - angle = self->angle+(pr_wraithfx2()<<22); + angle = -angle; } - else - { - angle = self->angle-(pr_wraithfx2()<<22); - } - mo->vel.z = 0; - mo->vel.x = FixedMul((pr_wraithfx2()<<7)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->vel.y = FixedMul((pr_wraithfx2()<<7)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); + angle += self->Angles.Yaw; + mo->Vel.X = ((pr_wraithfx2() << 7) + 1) * angle.Cos(); + mo->Vel.Y = ((pr_wraithfx2() << 7) + 1) * angle.Sin(); + mo->Vel.Z = 0; mo->target = self; - mo->floorclip = 10*FRACUNIT; + mo->Floorclip = 10; } } return 0; @@ -160,15 +150,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX3) PARAM_ACTION_PROLOGUE; AActor *mo; - int numdropped = pr_wraithfx3()%15; + int numdropped = pr_wraithfx3() % 15; while (numdropped-- > 0) { - fixed_t xo = (pr_wraithfx3() - 128) << 11; - fixed_t yo = (pr_wraithfx3() - 128) << 11; - fixed_t zo = pr_wraithfx3() << 10; + double xo = (pr_wraithfx3() - 128) / 32.; + double yo = (pr_wraithfx3() - 128) / 32.; + double zo = pr_wraithfx3() / 64.; - mo = Spawn ("WraithFX3", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); + mo = Spawn("WraithFX3", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { mo->floorz = self->floorz; @@ -216,9 +206,9 @@ void A_WraithFX4 (AActor *self) if (spawn4) { - fixed_t xo = (pr_wraithfx4() - 128) << 12; - fixed_t yo = (pr_wraithfx4() - 128) << 12; - fixed_t zo = (pr_wraithfx4() << 10); + double xo = (pr_wraithfx4() - 128) / 16.; + double yo = (pr_wraithfx4() - 128) / 16.; + double zo = (pr_wraithfx4() / 64.); mo = Spawn ("WraithFX4", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) @@ -230,9 +220,9 @@ void A_WraithFX4 (AActor *self) } if (spawn5) { - fixed_t xo = (pr_wraithfx4() - 128) << 11; - fixed_t yo = (pr_wraithfx4() - 128) << 11; - fixed_t zo = (pr_wraithfx4()<<10); + double xo = (pr_wraithfx4() - 128) / 32.; + double yo = (pr_wraithfx4() - 128) / 32.; + double zo = (pr_wraithfx4() / 64.); mo = Spawn ("WraithFX5", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) @@ -254,10 +244,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithChase) { PARAM_ACTION_PROLOGUE; - int weaveindex = self->special1; - self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8); - self->special1 = (weaveindex + 2) & 63; -// if (self->floorclip > 0) + int weaveindex = self->WeaveIndexZ; + self->AddZ(BobSin(weaveindex)); + self->WeaveIndexZ = (weaveindex + 2) & 63; +// if (self->Floorclip > 0) // { // P_SetMobjState(self, S_WRAITH_RAISE2); // return; diff --git a/src/g_level.cpp b/src/g_level.cpp index 1a626a40c..9d4069a9a 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1228,7 +1228,7 @@ void G_FinishTravel () { Printf(TEXTCOLOR_RED "No player %d start to travel to!\n", pnum + 1); // Move to the coordinates this player had when they left the level. - pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z()); + pawn->SetXYZ(pawndup->Pos()); } } oldpawn = pawndup; @@ -1240,13 +1240,10 @@ void G_FinishTravel () { if (!(changeflags & CHANGELEVEL_KEEPFACING)) { - pawn->angle = pawndup->angle; - pawn->pitch = pawndup->pitch; + pawn->Angles = pawndup->Angles; } - pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z()); - pawn->vel.x = pawndup->vel.x; - pawn->vel.y = pawndup->vel.y; - pawn->vel.z = pawndup->vel.z; + pawn->SetXYZ(pawndup->Pos()); + pawn->Vel = pawndup->Vel; pawn->Sector = pawndup->Sector; pawn->floorz = pawndup->floorz; pawn->ceilingz = pawndup->ceilingz; @@ -1256,7 +1253,7 @@ void G_FinishTravel () pawn->floorterrain = pawndup->floorterrain; pawn->ceilingsector = pawndup->ceilingsector; pawn->ceilingpic = pawndup->ceilingpic; - pawn->floorclip = pawndup->floorclip; + pawn->Floorclip = pawndup->Floorclip; pawn->waterlevel = pawndup->waterlevel; } else @@ -1316,7 +1313,7 @@ void G_InitLevelLocals () NormalLight.ChangeColor (PalEntry (255, 255, 255), 0); level.gravity = sv_gravity * 35/TICRATE; - level.aircontrol = (fixed_t)(sv_aircontrol * 65536.f); + level.aircontrol = sv_aircontrol; level.teamdamage = teamdamage; level.flags = 0; level.flags2 = 0; @@ -1357,7 +1354,7 @@ void G_InitLevelLocals () } if (info->aircontrol != 0.f) { - level.aircontrol = (fixed_t)(info->aircontrol * 65536.f); + level.aircontrol = info->aircontrol; } if (info->teamdamage != 0.f) { @@ -1462,15 +1459,14 @@ FString CalcMapName (int episode, int level) void G_AirControlChanged () { - if (level.aircontrol <= 256) + if (level.aircontrol <= 1/256.) { - level.airfriction = FRACUNIT; + level.airfriction = 1.; } else { // Friction is inversely proportional to the amount of control - float fric = ((float)level.aircontrol/65536.f) * -0.0941f + 1.0004f; - level.airfriction = (fixed_t)(fric * 65536.f); + level.airfriction = level.aircontrol * -0.0941 + 1.0004; } } @@ -1497,26 +1493,11 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) << level.maptime << i; - if (SaveVersion >= 3313) - { - // This is a player property now - int nextmusic; - arc << nextmusic; - } - // Hub transitions must keep the current total time if (!hubLoad) level.totaltime = i; - if (SaveVersion >= 4507) - { - arc << level.skytexture1 << level.skytexture2; - } - else - { - level.skytexture1 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); - level.skytexture2 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); - } + arc << level.skytexture1 << level.skytexture2; if (arc.IsLoading()) { sky1texture = level.skytexture1; @@ -1557,12 +1538,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) P_SerializeSubsectors(arc); StatusBar->Serialize (arc); - if (SaveVersion >= 4222) - { // This must be done *after* thinkers are serialized. - arc << level.DefaultSkybox; - } - - arc << level.total_monsters << level.total_items << level.total_secrets; + arc << level.DefaultSkybox << level.total_monsters << level.total_items << level.total_secrets; // Does this level have custom translations? FRemapTable *trans; @@ -1792,8 +1768,6 @@ void G_WriteSnapshots (FILE *file) void G_ReadSnapshots (PNGHandle *png) { DWORD chunkLen; - BYTE namelen; - char mapname[256]; FString MapName; level_info_t *i; @@ -1806,14 +1780,7 @@ void G_ReadSnapshots (PNGHandle *png) DWORD snapver; arc << snapver; - if (SaveVersion < 4508) - { - arc << namelen; - arc.Read(mapname, namelen); - mapname[namelen] = 0; - MapName = mapname; - } - else arc << MapName; + arc << MapName; i = FindLevelInfo (MapName); i->snapshotVer = snapver; i->snapshot = new FCompressedMemFile; @@ -1828,14 +1795,7 @@ void G_ReadSnapshots (PNGHandle *png) DWORD snapver; arc << snapver; - if (SaveVersion < 4508) - { - arc << namelen; - arc.Read(mapname, namelen); - mapname[namelen] = 0; - MapName = mapname; - } - else arc << MapName; + arc << MapName; TheDefaultLevelInfo.snapshotVer = snapver; TheDefaultLevelInfo.snapshot = new FCompressedMemFile; TheDefaultLevelInfo.snapshot->Serialize (arc); @@ -1846,25 +1806,10 @@ void G_ReadSnapshots (PNGHandle *png) { FPNGChunkArchive arc (png->File->GetFile(), VIST_ID, chunkLen); - if (SaveVersion < 4508) + while (arc << MapName, MapName.Len() > 0) { - arc << namelen; - while (namelen != 0) - { - arc.Read(mapname, namelen); - mapname[namelen] = 0; - i = FindLevelInfo(mapname); - i->flags |= LEVEL_VISITED; - arc << namelen; - } - } - else - { - while (arc << MapName, MapName.Len() > 0) - { - i = FindLevelInfo(MapName); - i->flags |= LEVEL_VISITED; - } + i = FindLevelInfo(MapName); + i->flags |= LEVEL_VISITED; } } @@ -1960,8 +1905,6 @@ void P_WriteACSDefereds (FILE *file) void P_ReadACSDefereds (PNGHandle *png) { - BYTE namelen; - char mapname[256]; FString MapName; size_t chunklen; @@ -1971,33 +1914,14 @@ void P_ReadACSDefereds (PNGHandle *png) { FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen); - if (SaveVersion < 4508) + while (arc << MapName, MapName.Len() > 0) { - arc << namelen; - while (namelen != 0) + level_info_t *i = FindLevelInfo(MapName); + if (i == NULL) { - arc.Read(mapname, namelen); - mapname[namelen] = 0; - level_info_t *i = FindLevelInfo(mapname); - if (i == NULL) - { - I_Error("Unknown map '%s' in savegame", mapname); - } - arc << i->defered; - arc << namelen; - } - } - else - { - while (arc << MapName, MapName.Len() > 0) - { - level_info_t *i = FindLevelInfo(MapName); - if (i == NULL) - { - I_Error("Unknown map '%s' in savegame", MapName.GetChars()); - } - arc << i->defered; + I_Error("Unknown map '%s' in savegame", MapName.GetChars()); } + arc << i->defered; } } png->File->ResetFilePtr(); diff --git a/src/g_level.h b/src/g_level.h index 17a2a1920..b12a3acea 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -304,8 +304,8 @@ struct level_info_t DWORD outsidefog; int cdtrack; unsigned int cdid; - float gravity; - float aircontrol; + double gravity; + double aircontrol; int WarpTrans; int airsupply; DWORD compatflags, compatflags2; @@ -329,7 +329,7 @@ struct level_info_t FString SoundInfo; FString SndSeq; - float teamdamage; + double teamdamage; FOptData optdata; FMusicMap MusicMap; @@ -377,7 +377,7 @@ struct level_info_t // [RH] These get zeroed every tic and are updated by thinkers. struct FSectorScrollValues { - fixed_t ScrollX, ScrollY; + DVector2 Scroll; }; struct FLevelLocals @@ -429,9 +429,9 @@ struct FLevelLocals int total_monsters; int killed_monsters; - float gravity; - fixed_t aircontrol; - fixed_t airfriction; + double gravity; + double aircontrol; + double airfriction; int airsupply; int DefaultEnvironment; // Default sound environment. @@ -444,7 +444,7 @@ struct FLevelLocals bool FromSnapshot; // The current map was restored from a snapshot - float teamdamage; + double teamdamage; bool IsJumpingAllowed() const; bool IsCrouchingAllowed() const; @@ -545,28 +545,33 @@ void G_ClearHubInfo(); enum ESkillProperty { - SKILLP_AmmoFactor, - SKILLP_DropAmmoFactor, - SKILLP_DamageFactor, SKILLP_FastMonsters, SKILLP_Respawn, SKILLP_RespawnLimit, - SKILLP_Aggressiveness, SKILLP_DisableCheats, SKILLP_AutoUseHealth, SKILLP_SpawnFilter, SKILLP_EasyBossBrain, SKILLP_ACSReturn, - SKILLP_MonsterHealth, - SKILLP_FriendlyHealth, SKILLP_NoPain, - SKILLP_ArmorFactor, - SKILLP_HealthFactor, SKILLP_EasyKey, SKILLP_SlowMonsters, SKILLP_Infight, }; +enum EFSkillProperty // floating point properties +{ + SKILLP_AmmoFactor, + SKILLP_DropAmmoFactor, + SKILLP_ArmorFactor, + SKILLP_HealthFactor, + SKILLP_DamageFactor, + SKILLP_Aggressiveness, + SKILLP_MonsterHealth, + SKILLP_FriendlyHealth, +}; + int G_SkillProperty(ESkillProperty prop); +double G_SkillProperty(EFSkillProperty prop); const char * G_SkillName(); typedef TMap SkillMenuNames; @@ -576,8 +581,11 @@ typedef TMap SkillActorReplacement; struct FSkillInfo { FName Name; - fixed_t AmmoFactor, DoubleAmmoFactor, DropAmmoFactor; - fixed_t DamageFactor; + double AmmoFactor, DoubleAmmoFactor, DropAmmoFactor; + double DamageFactor; + double ArmorFactor; + double HealthFactor; + bool FastMonsters; bool SlowMonsters; bool DisableCheats; @@ -587,7 +595,7 @@ struct FSkillInfo bool EasyKey; int RespawnCounter; int RespawnLimit; - fixed_t Aggressiveness; + double Aggressiveness; int SpawnFilter; int ACSReturn; FString MenuName; @@ -599,12 +607,10 @@ struct FSkillInfo FString TextColor; SkillActorReplacement Replace; SkillActorReplacement Replaced; - fixed_t MonsterHealth; - fixed_t FriendlyHealth; + double MonsterHealth; + double FriendlyHealth; bool NoPain; int Infighting; - fixed_t ArmorFactor; - fixed_t HealthFactor; FSkillInfo() {} FSkillInfo(const FSkillInfo &other) diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index fb1ae933f..b6c3a376a 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -989,14 +989,14 @@ DEFINE_MAP_OPTION(gravity, true) { parse.ParseAssign(); parse.sc.MustGetFloat(); - info->gravity = float(parse.sc.Float); + info->gravity = parse.sc.Float; } DEFINE_MAP_OPTION(aircontrol, true) { parse.ParseAssign(); parse.sc.MustGetFloat(); - info->aircontrol = float(parse.sc.Float); + info->aircontrol = parse.sc.Float; } DEFINE_MAP_OPTION(airsupply, true) @@ -1150,7 +1150,7 @@ DEFINE_MAP_OPTION(teamdamage, true) { parse.ParseAssign(); parse.sc.MustGetFloat(); - info->teamdamage = float(parse.sc.Float); + info->teamdamage = parse.sc.Float; } DEFINE_MAP_OPTION(mapbackground, true) diff --git a/src/g_raven/a_artitele.cpp b/src/g_raven/a_artitele.cpp index 88739492d..9a43f8518 100644 --- a/src/g_raven/a_artitele.cpp +++ b/src/g_raven/a_artitele.cpp @@ -27,26 +27,24 @@ IMPLEMENT_CLASS (AArtiTeleport) bool AArtiTeleport::Use (bool pickup) { - fixed_t destX; - fixed_t destY; - angle_t destAngle; + DVector3 dest; + int destAngle; if (deathmatch) { unsigned int selections = deathmatchstarts.Size (); unsigned int i = pr_tele() % selections; - destX = deathmatchstarts[i].x; - destY = deathmatchstarts[i].y; - destAngle = ANG45 * (deathmatchstarts[i].angle/45); + dest = deathmatchstarts[i].pos; + destAngle = deathmatchstarts[i].angle; } else { FPlayerStart *start = G_PickPlayerStart(int(Owner->player - players)); - destX = start->x; - destY = start->y; - destAngle = ANG45 * (start->angle/45); + dest = start->pos; + destAngle = start->angle; } - P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG); + dest.Z = ONFLOORZ; + P_Teleport (Owner, dest, (double)destAngle, TELF_SOURCEFOG | TELF_DESTFOG); bool canlaugh = true; if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE)) { // Teleporting away will undo any morph effects (pig) diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index 8bd648f66..34ecfd161 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -161,7 +161,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1) if ((player = self->target->player) != NULL && player->mo == self->target) { // Squish the player - player->deltaviewheight = -16*FRACUNIT; + player->deltaviewheight = -16; } } return 0; @@ -175,16 +175,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1) // //---------------------------------------------------------------------------- -#define MNTR_CHARGE_SPEED (13*FRACUNIT) +#define MNTR_CHARGE_SPEED (13.) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide) { PARAM_ACTION_PROLOGUE; bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER); - angle_t angle; AActor *target; - int dist; + double dist; target = self->target; if (!target) @@ -195,11 +194,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide) { S_Sound (self, CHAN_WEAPON, "minotaur/sight", 1, ATTN_NORM); } - dist = self->AproxDistance (target); + dist = self->Distance2D(target); if (target->Top() > self->Z() && target->Top() < self->Top() - && dist < (friendly ? 16*64*FRACUNIT : 8*64*FRACUNIT) - && dist > 1*64*FRACUNIT + && dist < (friendly ? 16*64. : 8*64.) + && dist > 1*64. && pr_minotaurdecide() < 150) { // Charge attack // Don't call the state function right away @@ -210,13 +209,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide) self->flags2 |= MF2_INVULNERABLE; } A_FaceTarget (self); - angle = self->angle>>ANGLETOFINESHIFT; - self->vel.x = FixedMul (MNTR_CHARGE_SPEED, finecosine[angle]); - self->vel.y = FixedMul (MNTR_CHARGE_SPEED, finesine[angle]); + self->VelFromAngle(MNTR_CHARGE_SPEED); self->special1 = TICRATE/2; // Charge duration } else if (target->Z() == target->floorz - && dist < 9*64*FRACUNIT + && dist < 9*64. && pr_minotaurdecide() < (friendly ? 100 : 220)) { // Floor fire attack self->SetState (self->FindState ("Hammer")); @@ -260,7 +257,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurCharge) type = PClass::FindActor("PunchPuff"); } puff = Spawn (type, self->Pos(), ALLOW_REPLACE); - puff->vel.z = 2*FRACUNIT; + puff->Vel.Z = 2; self->special1--; } else @@ -285,9 +282,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2) PARAM_ACTION_PROLOGUE; AActor *mo; - angle_t angle; - fixed_t vz; - fixed_t z; + DAngle angle; + double vz; + double z; bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER); if (self->target == NULL) @@ -303,7 +300,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2) P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return 0; } - z = self->Z() + 40*FRACUNIT; + z = self->Z() + 40; PClassActor *fx = PClass::FindActor("MinotaurFX1"); if (fx) { @@ -311,12 +308,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2) if (mo != NULL) { // S_Sound (mo, CHAN_WEAPON, "minotaur/attack2", 1, ATTN_NORM); - vz = mo->vel.z; - angle = mo->angle; - P_SpawnMissileAngleZ (self, z, fx, angle-(ANG45/8), vz); - P_SpawnMissileAngleZ (self, z, fx, angle+(ANG45/8), vz); - P_SpawnMissileAngleZ (self, z, fx, angle-(ANG45/16), vz); - P_SpawnMissileAngleZ (self, z, fx, angle+(ANG45/16), vz); + vz = mo->Vel.Z; + angle = mo->Angles.Yaw; + P_SpawnMissileAngleZ (self, z, fx, angle-(45./8), vz); + P_SpawnMissileAngleZ (self, z, fx, angle+(45./8), vz); + P_SpawnMissileAngleZ (self, z, fx, angle-(45./16), vz); + P_SpawnMissileAngleZ (self, z, fx, angle+(45./16), vz); } } return 0; @@ -353,12 +350,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3) if ((player = self->target->player) != NULL && player->mo == self->target) { // Squish the player - player->deltaviewheight = -16*FRACUNIT; + player->deltaviewheight = -16; } } else { - if (self->floorclip > 0 && (i_compatflags & COMPATF_MINOTAUR)) + if (self->Floorclip > 0 && (i_compatflags & COMPATF_MINOTAUR)) { // only play the sound. S_Sound (self, CHAN_WEAPON, "minotaur/fx2hit", 1, ATTN_NORM); @@ -393,12 +390,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire) AActor *mo; self->SetZ(self->floorz); - fixedvec2 pos = self->Vec2Offset( - (pr_fire.Random2 () << 10), - (pr_fire.Random2 () << 10)); - mo = Spawn("MinotaurFX3", pos.x, pos.y, self->floorz, ALLOW_REPLACE); + double x = pr_fire.Random2() / 64.; + double y = pr_fire.Random2() / 64.; + + mo = Spawn("MinotaurFX3", self->Vec2OffsetZ(x, y, self->floorz), ALLOW_REPLACE); mo->target = self->target; - mo->vel.x = 1; // Force block checking + mo->Vel.X = MinVel; // Force block checking P_CheckMissileSpawn (mo, self->radius); return 0; } @@ -411,18 +408,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire) void P_MinotaurSlam (AActor *source, AActor *target) { - angle_t angle; - fixed_t thrust; + DAngle angle; + double thrust; int damage; angle = source->AngleTo(target); - angle >>= ANGLETOFINESHIFT; - thrust = 16*FRACUNIT+(pr_minotaurslam()<<10); - target->vel.x += FixedMul (thrust, finecosine[angle]); - target->vel.y += FixedMul (thrust, finesine[angle]); + thrust = 16 + pr_minotaurslam() / 64.; + target->VelFromAngle(angle, thrust); damage = pr_minotaurslam.HitDice (static_cast(source) ? 4 : 6); int newdam = P_DamageMobj (target, NULL, NULL, damage, NAME_Melee); - P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0); + P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0.); if (target->player) { target->reactiontime = 14+(pr_minotaurslam()&7); @@ -491,7 +486,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurRoam) // // Look for enemy of player //---------------------------------------------------------------------------- -#define MINOTAUR_LOOK_DIST (16*54*FRACUNIT) +#define MINOTAUR_LOOK_DIST (16*54.) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook) { @@ -505,7 +500,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook) AActor *mo = NULL; player_t *player; - fixed_t dist; + double dist; int i; AActor *master = self->tracer; @@ -519,7 +514,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook) mo = player->mo; if (mo == master) continue; if (mo->health <= 0) continue; - dist = self->AproxDistance(mo); + dist = self->Distance2D(mo); if (dist > MINOTAUR_LOOK_DIST) continue; self->target = mo; break; @@ -544,7 +539,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook) if (!(mo->flags3 & MF3_ISMONSTER)) continue; if (mo->health <= 0) continue; if (!(mo->flags & MF_SHOOTABLE)) continue; - dist = self->AproxDistance(mo); + dist = self->Distance2D(mo); if (dist > MINOTAUR_LOOK_DIST) continue; if ((mo == master) || (mo == self)) continue; if ((mo->flags5 & MF5_SUMMONEDMONSTER) && (mo->tracer == master)) continue; diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index 29335e618..0e333a46e 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -63,7 +63,7 @@ void A_Unblock(AActor *self, bool drop) // [RH] Andy Baker's stealth monsters if (self->flags & MF_STEALTH) { - self->alpha = OPAQUE; + self->Alpha = 1.; self->visdir = 0; } @@ -142,7 +142,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnSetFloorClip) PARAM_ACTION_PROLOGUE; self->flags2 &= ~MF2_FLOORCLIP; - self->floorclip = 0; + self->Floorclip = 0; return 0; } @@ -189,7 +189,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath) self->flags |= MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD|MF_ICECORPSE; self->flags2 |= MF2_PUSHABLE|MF2_TELESTOMP|MF2_PASSMOBJ|MF2_SLIDE; self->flags3 |= MF3_CRASHED; - self->height = self->GetDefault()->height; + self->Height = self->GetDefault()->Height; // Remove fuzz effects from frozen actors. if (self->RenderStyle.BlendOp >= STYLEOP_Fuzz && self->RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub) { @@ -201,7 +201,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath) // [RH] Andy Baker's stealth monsters if (self->flags & MF_STEALTH) { - self->alpha = OPAQUE; + self->Alpha = 1; self->visdir = 0; } @@ -274,12 +274,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) int numChunks; AActor *mo; - if ((self->vel.x || self->vel.y || self->vel.z) && !(self->flags6 & MF6_SHATTERING)) + if (!self->Vel.isZero() && !(self->flags6 & MF6_SHATTERING)) { self->tics = 3*TICRATE; return 0; } - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); S_Sound (self, CHAN_BODY, "misc/icebreak", 1, ATTN_NORM); // [RH] In Hexen, this creates a random number of shards (range [24,56]) @@ -287,23 +287,24 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) // base the number of shards on the size of the dead thing, so bigger // things break up into more shards than smaller things. // An actor with radius 20 and height 64 creates ~40 chunks. - numChunks = MAX (4, (self->radius>>FRACBITS)*(self->height>>FRACBITS)/32); + numChunks = MAX(4, int(self->radius * self->Height)/32); i = (pr_freeze.Random2()) % (numChunks/4); for (i = MAX (24, numChunks + i); i >= 0; i--) { - fixed_t xo = (((pr_freeze() - 128)*self->radius) >> 7); - fixed_t yo = (((pr_freeze() - 128)*self->radius) >> 7); - fixed_t zo = (pr_freeze()*self->height / 255); + double xo = (pr_freeze() - 128)*self->radius / 128; + double yo = (pr_freeze() - 128)*self->radius / 128; + double zo = (pr_freeze()*self->Height / 255); + mo = Spawn("IceChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { - mo->SetState (mo->SpawnState + (pr_freeze()%3)); - mo->vel.z = FixedDiv(mo->Z() - self->Z(), self->height)<<2; - mo->vel.x = pr_freeze.Random2 () << (FRACBITS-7); - mo->vel.y = pr_freeze.Random2 () << (FRACBITS-7); + mo->SetState (mo->SpawnState + (pr_freeze()%3)); + mo->Vel.X = pr_freeze.Random2() / 128.; + mo->Vel.Y = pr_freeze.Random2() / 128.; + mo->Vel.Z = (mo->Z() - self->Z()) / self->Height * 4; CALL_ACTION(A_IceSetTics, mo); // set a random tic wait mo->RenderStyle = self->RenderStyle; - mo->alpha = self->alpha; + mo->Alpha = self->Alpha; } } if (self->player) @@ -311,11 +312,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) AActor *head = Spawn("IceChunkHead", self->PosPlusZ(self->player->mo->ViewHeight), ALLOW_REPLACE); if (head != NULL) { - head->vel.z = FixedDiv(head->Z() - self->Z(), self->height)<<2; - head->vel.x = pr_freeze.Random2 () << (FRACBITS-7); - head->vel.y = pr_freeze.Random2 () << (FRACBITS-7); + head->Vel.X = pr_freeze.Random2() / 128.; + head->Vel.Y = pr_freeze.Random2() / 128.; + head->Vel.Z = (mo->Z() - self->Z()) / self->Height * 4; + head->health = self->health; - head->angle = self->angle; + head->Angles.Yaw = self->Angles.Yaw; if (head->IsKindOf(RUNTIME_CLASS(APlayerPawn))) { head->player = self->player; @@ -323,9 +325,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) self->player = NULL; head->ObtainInventory (self); } - head->pitch = 0; + head->Angles.Pitch = 0.; head->RenderStyle = self->RenderStyle; - head->alpha = self->alpha; + head->Alpha = self->Alpha; if (head->player->camera == self) { head->player->camera = head; @@ -611,7 +613,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Gravity) PARAM_ACTION_PROLOGUE; self->flags &= ~MF_NOGRAVITY; - self->gravity = FRACUNIT; + self->Gravity = 1; return 0; } @@ -626,7 +628,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LowGravity) PARAM_ACTION_PROLOGUE; self->flags &= ~MF_NOGRAVITY; - self->gravity = FRACUNIT/8; + self->Gravity = 1. / 8;; return 0; } @@ -636,34 +638,33 @@ DEFINE_ACTION_FUNCTION(AActor, A_LowGravity) // //=========================================================================== -void FaceMovementDirection (AActor *actor) +void FaceMovementDirection(AActor *actor) { switch (actor->movedir) { case DI_EAST: - actor->angle = 0<<24; + actor->Angles.Yaw = 0.; break; case DI_NORTHEAST: - actor->angle = 32<<24; + actor->Angles.Yaw = 45.; break; case DI_NORTH: - actor->angle = 64<<24; + actor->Angles.Yaw = 90.; break; case DI_NORTHWEST: - actor->angle = 96<<24; + actor->Angles.Yaw = 135.; break; case DI_WEST: - actor->angle = 128<<24; + actor->Angles.Yaw = 180.; break; case DI_SOUTHWEST: - actor->angle = 160<<24; + actor->Angles.Yaw = 225.; break; case DI_SOUTH: - actor->angle = 192<<24; + actor->Angles.Yaw = 270.; break; case DI_SOUTHEAST: - actor->angle = 224<<24; + actor->Angles.Yaw = 315.; break; } } - diff --git a/src/g_shared/a_armor.cpp b/src/g_shared/a_armor.cpp index 30ada14cc..2b783e380 100644 --- a/src/g_shared/a_armor.cpp +++ b/src/g_shared/a_armor.cpp @@ -24,12 +24,7 @@ IMPLEMENT_CLASS (AHexenArmor) void ABasicArmor::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << SavePercent << BonusCount << MaxAbsorb << MaxFullAbsorb << AbsorbCount << ArmorType; - - if (SaveVersion >= 4511) - { - arc << ActualSaveAmount; - } + arc << SavePercent << BonusCount << MaxAbsorb << MaxFullAbsorb << AbsorbCount << ArmorType << ActualSaveAmount; } //=========================================================================== @@ -67,8 +62,8 @@ AInventory *ABasicArmor::CreateCopy (AActor *other) { // BasicArmor that is in use is stored in the inventory as BasicArmor. // BasicArmor that is in reserve is not. - ABasicArmor *copy = Spawn (0, 0, 0, NO_REPLACE); - copy->SavePercent = SavePercent != 0 ? SavePercent : FRACUNIT/3; + ABasicArmor *copy = Spawn (); + copy->SavePercent = SavePercent != 0 ? SavePercent : 0.33335; // slightly more than 1/3 to avoid roundoff errors. copy->Amount = Amount; copy->MaxAmount = MaxAmount; copy->Icon = Icon; @@ -96,13 +91,13 @@ bool ABasicArmor::HandlePickup (AInventory *item) { ABasicArmorBonus *armor = static_cast(item); - armor->SaveAmount = FixedMul(armor->SaveAmount, G_SkillProperty(SKILLP_ArmorFactor)); + armor->SaveAmount = int(armor->SaveAmount * G_SkillProperty(SKILLP_ArmorFactor)); } else if (item->IsKindOf(RUNTIME_CLASS(ABasicArmorPickup)) && !(item->ItemFlags & IF_IGNORESKILL)) { ABasicArmorPickup *armor = static_cast(item); - armor->SaveAmount = FixedMul(armor->SaveAmount, G_SkillProperty(SKILLP_ArmorFactor)); + armor->SaveAmount = int(armor->SaveAmount * G_SkillProperty(SKILLP_ArmorFactor)); } if (Inventory != NULL) { @@ -130,7 +125,7 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) } else { - saved = full + FixedMul (damage - full, SavePercent); + saved = full + int((damage - full) * SavePercent); if (MaxAbsorb > 0 && saved + AbsorbCount > MaxAbsorb) { saved = MAX(0, MaxAbsorb - AbsorbCount); @@ -179,15 +174,10 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) // This code is taken and adapted from APowerProtection::ModifyDamage(). // The differences include not using a default value, and of course the way // the damage factor info is obtained. - const fixed_t *pdf = NULL; DmgFactors *df = PClass::FindActor(ArmorType)->DamageFactors; - if (df != NULL && df->CountUsed() != 0) + if (df != NULL) { - pdf = df->CheckFactor(damageType); - if (pdf != NULL) - { - damage = newdamage = FixedMul(damage, *pdf); - } + damage = newdamage = df->Apply(damageType, damage); } } if (Inventory != NULL) @@ -221,7 +211,7 @@ AInventory *ABasicArmorPickup::CreateCopy (AActor *other) if (!(ItemFlags & IF_IGNORESKILL)) { - SaveAmount = FixedMul(SaveAmount, G_SkillProperty(SKILLP_ArmorFactor)); + SaveAmount = int(SaveAmount * G_SkillProperty(SKILLP_ArmorFactor)); } copy->SavePercent = SavePercent; @@ -249,7 +239,7 @@ bool ABasicArmorPickup::Use (bool pickup) if (armor == NULL) { - armor = Spawn (0,0,0, NO_REPLACE); + armor = Spawn (); armor->BecomeItem (); Owner->AddInventory (armor); } @@ -303,7 +293,7 @@ AInventory *ABasicArmorBonus::CreateCopy (AActor *other) if (!(ItemFlags & IF_IGNORESKILL)) { - SaveAmount = FixedMul(SaveAmount, G_SkillProperty(SKILLP_ArmorFactor)); + SaveAmount = int(SaveAmount * G_SkillProperty(SKILLP_ArmorFactor)); } copy->SavePercent = SavePercent; @@ -332,7 +322,7 @@ bool ABasicArmorBonus::Use (bool pickup) if (armor == NULL) { - armor = Spawn (0,0,0, NO_REPLACE); + armor = Spawn (); armor->BecomeItem (); armor->Amount = 0; armor->MaxAmount = MaxSaveAmount; @@ -401,7 +391,7 @@ AInventory *AHexenArmor::CreateCopy (AActor *other) // Like BasicArmor, HexenArmor is used in the inventory but not the map. // health is the slot this armor occupies. // Amount is the quantity to give (0 = normal max). - AHexenArmor *copy = Spawn (0, 0, 0, NO_REPLACE); + AHexenArmor *copy = Spawn (); copy->AddArmorToSlot (other, health, Amount); GoAwayAndDie (); return copy; @@ -452,7 +442,7 @@ bool AHexenArmor::HandlePickup (AInventory *item) bool AHexenArmor::AddArmorToSlot (AActor *actor, int slot, int amount) { APlayerPawn *ppawn; - int hits; + double hits; if (actor->player != NULL) { @@ -478,9 +468,9 @@ bool AHexenArmor::AddArmorToSlot (AActor *actor, int slot, int amount) } else { - hits = amount * 5 * FRACUNIT; - fixed_t total = Slots[0]+Slots[1]+Slots[2]+Slots[3]+Slots[4]; - fixed_t max = SlotsIncrement[0]+SlotsIncrement[1]+SlotsIncrement[2]+SlotsIncrement[3]+Slots[4]+4*5*FRACUNIT; + hits = amount * 5; + auto total = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4]; + auto max = SlotsIncrement[0] + SlotsIncrement[1] + SlotsIncrement[2] + SlotsIncrement[3] + Slots[4] + 4 * 5; if (total < max) { Slots[slot] += hits; @@ -500,13 +490,13 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) { if (!DamageTypeDefinition::IgnoreArmor(damageType)) { - fixed_t savedPercent = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4]; + double savedPercent = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4]; if (savedPercent) { // armor absorbed some damage - if (savedPercent > 100*FRACUNIT) + if (savedPercent > 100) { - savedPercent = 100*FRACUNIT; + savedPercent = 100; } for (int i = 0; i < 4; i++) { @@ -516,15 +506,8 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) // with the dragon skin bracers. if (damage < 10000) { -#if __APPLE__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 1 - // -O1 optimizer bug work around. Only needed for - // GCC 4.2.1 on OS X for 10.4/10.5 tools compatibility. - volatile fixed_t tmp = 300; - Slots[i] -= Scale (damage, SlotsIncrement[i], tmp); -#else - Slots[i] -= Scale (damage, SlotsIncrement[i], 300); -#endif - if (Slots[i] < 2*FRACUNIT) + Slots[i] -= damage * SlotsIncrement[i] / 300.; + if (Slots[i] < 2) { Slots[i] = 0; } @@ -535,10 +518,10 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) } } } - int saved = Scale (damage, savedPercent, 100*FRACUNIT); - if (saved > savedPercent >> (FRACBITS-1)) + int saved = int(damage * savedPercent / 100.); + if (saved > savedPercent*2) { - saved = savedPercent >> (FRACBITS-1); + saved = int(savedPercent*2); } newdamage -= saved; damage = newdamage; diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 25646ba35..1efb4e8ee 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -66,7 +66,7 @@ bool APowerupGiver::Use (bool pickup) { if (PowerupType == NULL) return true; // item is useless - APowerup *power = static_cast (Spawn (PowerupType, 0, 0, 0, NO_REPLACE)); + APowerup *power = static_cast (Spawn (PowerupType)); if (EffectTics != 0) { @@ -415,28 +415,28 @@ void APowerInvulnerable::DoEffect () // Don't mess with the translucency settings if an // invisibility powerup is active. Owner->RenderStyle = STYLE_Translucent; - if (!(level.time & 7) && Owner->alpha > 0 && Owner->alpha < OPAQUE) + if (!(level.time & 7) && Owner->Alpha > 0 && Owner->Alpha < 1) { - if (Owner->alpha == HX_SHADOW) + if (Owner->Alpha == HX_SHADOW) { - Owner->alpha = HX_ALTSHADOW; + Owner->Alpha = HX_ALTSHADOW; } else { - Owner->alpha = 0; + Owner->Alpha = 0; Owner->flags2 |= MF2_NONSHOOTABLE; } } if (!(level.time & 31)) { - if (Owner->alpha == 0) + if (Owner->Alpha == 0) { Owner->flags2 &= ~MF2_NONSHOOTABLE; - Owner->alpha = HX_ALTSHADOW; + Owner->Alpha = HX_ALTSHADOW; } else { - Owner->alpha = HX_SHADOW; + Owner->Alpha = HX_SHADOW; } } } @@ -472,7 +472,7 @@ void APowerInvulnerable::EndEffect () // Don't mess with the translucency settings if an // invisibility powerup is active. Owner->RenderStyle = STYLE_Normal; - Owner->alpha = OPAQUE; + Owner->Alpha = 1.; } } else if (Mode == NAME_Reflective) @@ -499,8 +499,7 @@ int APowerInvulnerable::AlterWeaponSprite (visstyle_t *vis) { if (Mode == NAME_Ghost && !(Owner->flags & MF_SHADOW)) { - fixed_t wp_alpha = MIN(FRACUNIT/4 + Owner->alpha*3/4, FRACUNIT); - if (wp_alpha != FIXED_MAX) vis->alpha = wp_alpha; + vis->Alpha = MIN(0.25f + (float)Owner->Alpha*0.75f, 1.f); } } return changed; @@ -616,8 +615,10 @@ void APowerInvisibility::DoEffect () Super::DoEffect(); // Due to potential interference with other PowerInvisibility items // the effect has to be refreshed each tic. - fixed_t ts = (Strength/100) * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; - Owner->alpha = clamp((OPAQUE - ts), 0, OPAQUE); + double ts = (Strength / 100) * (special1 + 1); + + if (ts > 1.) ts = 1.; + Owner->Alpha = clamp((1. - ts), 0., 1.); switch (Mode) { case (NAME_Fuzzy): @@ -645,7 +646,7 @@ void APowerInvisibility::DoEffect () break; default: // Something's wrong Owner->RenderStyle = STYLE_Normal; - Owner->alpha = OPAQUE; + Owner->Alpha = 1.; break; } } @@ -666,7 +667,7 @@ void APowerInvisibility::EndEffect () Owner->flags5 &= ~(flags5 & INVISIBILITY_FLAGS5); Owner->RenderStyle = STYLE_Normal; - Owner->alpha = OPAQUE; + Owner->Alpha = 1.; // Check whether there are other invisibility items and refresh their effect. // If this isn't done there will be one incorrectly drawn frame when this @@ -696,14 +697,14 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis) if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8)) { vis->RenderStyle = STYLE_Normal; - vis->alpha = OPAQUE; + vis->Alpha = 1.f; return 1; } else if (changed == 1) { // something else set the weapon sprite back to opaque but this item is still active. - fixed_t ts = (Strength/100) * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; - vis->alpha = clamp((OPAQUE - ts), 0, OPAQUE); + float ts = float((Strength / 100) * (special1 + 1)); + vis->Alpha = clamp<>((1.f - ts), 0.f, 1.f); switch (Mode) { case (NAME_Fuzzy): @@ -733,9 +734,9 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis) } } // Handling of Strife-like cumulative invisibility powerups, the weapon itself shouldn't become invisible - if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0)) + if ((vis->Alpha < 0.25f && special1 > 0) || (vis->Alpha == 0)) { - vis->alpha = clamp((OPAQUE - (Strength/100)), 0, OPAQUE); + vis->Alpha = clamp((1.f - float(Strength/100)), 0.f, 1.f); vis->colormap = SpecialColormaps[INVERSECOLORMAP].Colormap; } return -1; // This item is valid so another one shouldn't reset the translucency @@ -752,7 +753,7 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis) bool APowerInvisibility::HandlePickup (AInventory *item) { - if (Mode == NAME_Cumulative && ((Strength * special1) < FRACUNIT) && item->GetClass() == GetClass()) + if (Mode == NAME_Cumulative && ((Strength * special1) < 1.) && item->GetClass() == GetClass()) { APowerup *power = static_cast(item); if (power->EffectTics == 0) @@ -981,9 +982,9 @@ void APowerFlight::InitEffect () Owner->flags |= MF_NOGRAVITY; if (Owner->Z() <= Owner->floorz) { - Owner->vel.z = 4*FRACUNIT; // thrust the player in the air a bit + Owner->Vel.Z = 4;; // thrust the player in the air a bit } - if (Owner->vel.z <= -35*FRACUNIT) + if (Owner->Vel.Z <= -35) { // stop falling scream S_StopSound (Owner, CHAN_VOICE); } @@ -1180,14 +1181,14 @@ IMPLEMENT_CLASS (APlayerSpeedTrail) void APlayerSpeedTrail::Tick () { - const int fade = OPAQUE*6/10/8; - if (alpha <= fade) + const double fade = .6 / 8; + if (Alpha <= fade) { Destroy (); } else { - alpha -= fade; + Alpha -= fade; } } @@ -1204,14 +1205,7 @@ IMPLEMENT_CLASS (APowerSpeed) void APowerSpeed::Serialize(FArchive &arc) { Super::Serialize (arc); - if (SaveVersion < 4146) - { - SpeedFlags = 0; - } - else - { - arc << SpeedFlags; - } + arc << SpeedFlags; } //=========================================================================== @@ -1220,10 +1214,10 @@ void APowerSpeed::Serialize(FArchive &arc) // //=========================================================================== -fixed_t APowerSpeed ::GetSpeedFactor () +double APowerSpeed ::GetSpeedFactor () { if (Inventory != NULL) - return FixedMul(Speed, Inventory->GetSpeedFactor()); + return Speed * Inventory->GetSpeedFactor(); else return Speed; } @@ -1261,22 +1255,21 @@ void APowerSpeed::DoEffect () } } - if (P_AproxDistance (Owner->vel.x, Owner->vel.y) <= 12*FRACUNIT) + if (Owner->Vel.LengthSquared() <= 12*12) return; AActor *speedMo = Spawn (Owner->Pos(), NO_REPLACE); if (speedMo) { - speedMo->angle = Owner->angle; + speedMo->Angles.Yaw = Owner->Angles.Yaw; speedMo->Translation = Owner->Translation; speedMo->target = Owner; speedMo->sprite = Owner->sprite; speedMo->frame = Owner->frame; - speedMo->floorclip = Owner->floorclip; + speedMo->Floorclip = Owner->Floorclip; // [BC] Also get the scale from the owner. - speedMo->scaleX = Owner->scaleX; - speedMo->scaleY = Owner->scaleY; + speedMo->Scale = Owner->Scale; if (Owner == players[consoleplayer].camera && !(Owner->player->cheats & CF_CHASECAM)) @@ -1317,10 +1310,10 @@ void APowerTargeter::InitEffect () P_SetPsprite (player, ps_targetright, state + 2); } - player->psprites[ps_targetcenter].sx = (160-3)*FRACUNIT; + player->psprites[ps_targetcenter].sx = (160-3); player->psprites[ps_targetcenter].sy = player->psprites[ps_targetleft].sy = - player->psprites[ps_targetright].sy = (100-3)*FRACUNIT; + player->psprites[ps_targetright].sy = (100-3); PositionAccuracy (); } @@ -1383,8 +1376,8 @@ void APowerTargeter::PositionAccuracy () if (player != NULL) { - player->psprites[ps_targetleft].sx = (160-3)*FRACUNIT - ((100 - player->mo->accuracy) << FRACBITS); - player->psprites[ps_targetright].sx = (160-3)*FRACUNIT + ((100 - player->mo->accuracy) << FRACBITS); + player->psprites[ps_targetleft].sx = (160-3) - ((100 - player->mo->accuracy)); + player->psprites[ps_targetright].sx = (160-3)+ ((100 - player->mo->accuracy)); } } @@ -1630,25 +1623,20 @@ void APowerDamage::EndEffect( ) void APowerDamage::ModifyDamage(int damage, FName damageType, int &newdamage, bool passive) { - static const fixed_t def = 4*FRACUNIT; if (!passive && damage > 0) { - const fixed_t *pdf = NULL; + int newdam; DmgFactors *df = GetClass()->DamageFactors; if (df != NULL && df->CountUsed() != 0) { - pdf = df->CheckFactor(damageType); + newdam = MIN(1, df->Apply(damageType, damage));// don't allow zero damage as result of an underflow } else { - pdf = &def; - } - if (pdf != NULL) - { - damage = newdamage = FixedMul(damage, *pdf); - if (*pdf > 0 && damage == 0) damage = newdamage = 1; // don't allow zero damage as result of an underflow - if (Owner != NULL && *pdf > FRACUNIT) S_Sound(Owner, 5, ActiveSound, 1.0f, ATTN_NONE); + newdam = damage * 4; } + if (Owner != NULL && newdam > damage) S_Sound(Owner, 5, ActiveSound, 1.0f, ATTN_NONE); + newdamage = newdam; } if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive); } @@ -1710,22 +1698,20 @@ void APowerProtection::EndEffect( ) void APowerProtection::ModifyDamage(int damage, FName damageType, int &newdamage, bool passive) { - static const fixed_t def = FRACUNIT/4; if (passive && damage > 0) { - const fixed_t *pdf = NULL; + int newdam; DmgFactors *df = GetClass()->DamageFactors; if (df != NULL && df->CountUsed() != 0) { - pdf = df->CheckFactor(damageType); + newdam = MIN(0, df->Apply(damageType, damage)); } - else pdf = &def; - - if (pdf != NULL) + else { - damage = newdamage = FixedMul(damage, *pdf); - if (Owner != NULL && *pdf < FRACUNIT) S_Sound(Owner, CHAN_AUTO, ActiveSound, 1.0f, ATTN_NONE); + newdam = damage / 4; } + if (Owner != NULL && newdam < damage) S_Sound(Owner, CHAN_AUTO, ActiveSound, 1.0f, ATTN_NONE); + newdamage = newdam; } if (Inventory != NULL) { @@ -1788,7 +1774,7 @@ void APowerRegeneration::DoEffect() Super::DoEffect(); if (Owner != NULL && Owner->health > 0 && (level.time & 31) == 0) { - if (P_GiveBody(Owner, Strength/FRACUNIT)) + if (P_GiveBody(Owner, int(Strength))) { S_Sound(Owner, CHAN_ITEM, "*regenerate", 1, ATTN_NORM ); } diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index a355cb924..9ed285ca5 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -25,7 +25,7 @@ public: int EffectTics; PalEntry BlendColor; FNameNoInit Mode; - fixed_t Strength; + double Strength; protected: virtual void InitEffect (); @@ -58,7 +58,7 @@ public: int EffectTics; // Non-0 to override the powerup's default tics PalEntry BlendColor; // Non-0 to override the powerup's default blend FNameNoInit Mode; // Meaning depends on powerup - used for Invulnerability and Invisibility - fixed_t Strength; // Meaning depends on powerup - currently used only by Invisibility + double Strength; // Meaning depends on powerup - currently used only by Invisibility }; class APowerInvulnerable : public APowerup @@ -91,8 +91,6 @@ protected: void DoEffect (); void EndEffect (); int AlterWeaponSprite (visstyle_t *vis); -// FRenderStyle OwnersNormalStyle; -// fixed_t OwnersNormalAlpha; }; class APowerIronFeet : public APowerup @@ -158,7 +156,7 @@ class APowerSpeed : public APowerup protected: void DoEffect (); void Serialize(FArchive &arc); - fixed_t GetSpeedFactor(); + double GetSpeedFactor(); public: int SpeedFlags; }; diff --git a/src/g_shared/a_bridge.cpp b/src/g_shared/a_bridge.cpp index 3b1b34d71..178f004ca 100644 --- a/src/g_shared/a_bridge.cpp +++ b/src/g_shared/a_bridge.cpp @@ -48,13 +48,13 @@ void ACustomBridge::BeginPlay () if (args[2]) // Hexen bridge if there are balls { SetState(SeeState); - radius = args[0] ? args[0] << FRACBITS : 32 * FRACUNIT; - height = args[1] ? args[1] << FRACBITS : 2 * FRACUNIT; + radius = args[0] ? args[0] : 32; + Height = args[1] ? args[1] : 2; } else // No balls? Then a Doom bridge. { - radius = args[0] ? args[0] << FRACBITS : 36 * FRACUNIT; - height = args[1] ? args[1] << FRACBITS : 4 * FRACUNIT; + radius = args[0] ? args[0] : 36; + Height = args[1] ? args[1] : 4; RenderStyle = STYLE_Normal; } } @@ -101,18 +101,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit) } // Set default values // Every five tics, Hexen moved the ball 3/256th of a revolution. - int rotationspeed = ANGLE_45/32*3/5; - int rotationradius = ORBIT_RADIUS * FRACUNIT; + DAngle rotationspeed = 45./32*3/5; + double rotationradius = ORBIT_RADIUS; // If the bridge is custom, set non-default values if any. // Set angular speed; 1--128: counterclockwise rotation ~=1--180°; 129--255: clockwise rotation ~= 180--1° - if (self->target->args[3] > 128) rotationspeed = ANGLE_45/32 * (self->target->args[3]-256) / TICRATE; - else if (self->target->args[3] > 0) rotationspeed = ANGLE_45/32 * (self->target->args[3]) / TICRATE; + if (self->target->args[3] > 128) rotationspeed = 45./32 * (self->target->args[3]-256) / TICRATE; + else if (self->target->args[3] > 0) rotationspeed = 45./32 * (self->target->args[3]) / TICRATE; // Set rotation radius if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->radius) / 100); - self->angle += rotationspeed; - self->SetOrigin(self->target->Vec3Angle(rotationradius, self->angle, 0), true); + self->Angles.Yaw += rotationspeed; + self->SetOrigin(self->target->Vec3Angle(rotationradius, self->Angles.Yaw, 0), true); self->floorz = self->target->floorz; self->ceilingz = self->target->ceilingz; return 0; @@ -124,7 +124,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit) PARAM_ACTION_PROLOGUE; PARAM_CLASS_OPT(balltype, AActor) { balltype = NULL; } - angle_t startangle; AActor *ball; if (balltype == NULL) @@ -132,7 +131,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit) balltype = PClass::FindActor("BridgeBall"); } - startangle = pr_orbit() << 24; + DAngle startangle = pr_orbit() * (360./256.); // Spawn triad into world -- may be more than a triad now. int ballcount = self->args[2]==0 ? 3 : self->args[2]; @@ -140,7 +139,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit) for (int i = 0; i < ballcount; i++) { ball = Spawn(balltype, self->Pos(), ALLOW_REPLACE); - ball->angle = startangle + (ANGLE_45/32) * (256/ballcount) * i; + ball->Angles.Yaw = startangle + (45./32) * (256/ballcount) * i; ball->target = self; CALL_ACTION(A_BridgeOrbit, ball); } @@ -163,8 +162,8 @@ void AInvisibleBridge::BeginPlay () { Super::BeginPlay (); if (args[0]) - radius = args[0] << FRACBITS; + radius = args[0]; if (args[1]) - height = args[1] << FRACBITS; + Height = args[1]; } diff --git a/src/g_shared/a_camera.cpp b/src/g_shared/a_camera.cpp index 7febf80d1..64868231b 100644 --- a/src/g_shared/a_camera.cpp +++ b/src/g_shared/a_camera.cpp @@ -37,6 +37,7 @@ #include "a_sharedglobal.h" #include "p_local.h" #include "farchive.h" +#include "math/cmath.h" /* == SecurityCamera @@ -56,10 +57,10 @@ public: void Serialize (FArchive &arc); protected: - angle_t Center; - angle_t Acc; - angle_t Delta; - angle_t Range; + DAngle Center; + DAngle Acc; + DAngle Delta; + DAngle Range; }; IMPLEMENT_CLASS (ASecurityCamera) @@ -73,29 +74,25 @@ void ASecurityCamera::Serialize (FArchive &arc) void ASecurityCamera::PostBeginPlay () { Super::PostBeginPlay (); - Center = angle; + Center = Angles.Yaw; if (args[2]) - Delta = ANGLE_MAX / (args[2] * TICRATE / 8); + Delta = 360. / (args[2] * TICRATE / 8); else - Delta = 0; + Delta = 0.; if (args[1]) Delta /= 2; - Acc = 0; - pitch = (signed int)((char)args[0]) * ANGLE_1; - if (pitch <= -ANGLE_90) - pitch = -ANGLE_90 + ANGLE_1; - else if (pitch >= ANGLE_90) - pitch = ANGLE_90 - ANGLE_1; - Range = FLOAT2ANGLE(args[1]); + Acc = 0.; + Angles.Pitch = (double)clamp((signed char)args[0], -89, 89); + Range = (double)args[1]; } void ASecurityCamera::Tick () { Acc += Delta; - if (Range) - angle = Center + FixedMul (Range, finesine[Acc >> ANGLETOFINESHIFT]); - else if (Delta) - angle = Acc; + if (Range != 0) + Angles.Yaw = Center + Range * Acc.Sin(); + else if (Delta != 0) + Angles.Yaw = Acc; } /* @@ -119,7 +116,7 @@ public: void Serialize (FArchive &arc); protected: - int MaxPitchChange; + DAngle MaxPitchChange; }; IMPLEMENT_CLASS (AAimingCamera) @@ -136,7 +133,7 @@ void AAimingCamera::PostBeginPlay () args[2] = 0; Super::PostBeginPlay (); - MaxPitchChange = FLOAT2ANGLE(changepitch * TICRATE); + MaxPitchChange = double(changepitch / TICRATE); Range /= TICRATE; TActorIterator iterator (args[3]); @@ -160,7 +157,7 @@ void AAimingCamera::Tick () } if (tracer != NULL) { - angle_t delta; + DAngle delta; int dir = P_FaceMobj (this, tracer, &delta); if (delta > Range) { @@ -168,31 +165,30 @@ void AAimingCamera::Tick () } if (dir) { - angle += delta; + Angles.Yaw += delta; } else { - angle -= delta; + Angles.Yaw -= delta; } - if (MaxPitchChange) + if (MaxPitchChange != 0) { // Aim camera's pitch; use floats for precision - fixedvec2 fv3 = tracer->Vec2To(this); - DVector2 vect(fv3.x, fv3.y); - double dz = Z() - tracer->Z() - tracer->height/2; + DVector2 vect = tracer->Vec2To(this); + double dz = Z() - tracer->Z() - tracer->Height/2; double dist = vect.Length(); - double ang = dist != 0.f ? atan2 (dz, dist) : 0; - int desiredpitch = (int)RAD2ANGLE(ang); - if (abs (desiredpitch - pitch) < MaxPitchChange) + DAngle desiredPitch = dist != 0.f ? VecToAngle(dist, dz) : 0.; + DAngle diff = deltaangle(Angles.Pitch, desiredPitch); + if (fabs (diff) < MaxPitchChange) { - pitch = desiredpitch; + Angles.Pitch = desiredPitch; } - else if (desiredpitch < pitch) + else if (diff < 0) { - pitch -= MaxPitchChange; + Angles.Pitch -= MaxPitchChange; } else { - pitch += MaxPitchChange; + Angles.Pitch += MaxPitchChange; } } } diff --git a/src/g_shared/a_debris.cpp b/src/g_shared/a_debris.cpp index b5785eb9e..895c3b170 100644 --- a/src/g_shared/a_debris.cpp +++ b/src/g_shared/a_debris.cpp @@ -15,7 +15,7 @@ public: { if (!Super::FloorBounceMissile (plane)) { - if (abs (vel.z) < (FRACUNIT/2)) + if (fabs (Vel.Z) < 0.5) { Destroy (); } @@ -29,13 +29,13 @@ IMPLEMENT_CLASS(AGlassShard) // Dirt stuff -void P_SpawnDirt (AActor *actor, fixed_t radius) +void P_SpawnDirt (AActor *actor, double radius) { PClassActor *dtype = NULL; AActor *mo; - fixed_t zo = (pr_dirt() << 9) + FRACUNIT; - fixedvec3 pos = actor->Vec3Angle(radius, pr_dirt() << 24, zo); + double zo = pr_dirt() / 128. + 1; + DVector3 pos = actor->Vec3Angle(radius, pr_dirt() * (360./256), zo); char fmt[8]; mysnprintf(fmt, countof(fmt), "Dirt%d", 1 + pr_dirt()%6); @@ -45,7 +45,7 @@ void P_SpawnDirt (AActor *actor, fixed_t radius) mo = Spawn (dtype, pos, ALLOW_REPLACE); if (mo) { - mo->vel.z = pr_dirt()<<10; + mo->Vel.Z = pr_dirt() / 64.; } } } diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index d37250887..cdf3c2b2e 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -47,8 +47,8 @@ #include "farchive.h" #include "doomdata.h" -static fixed_t DecalWidth, DecalLeft, DecalRight; -static fixed_t SpreadZ; +static double DecalWidth, DecalLeft, DecalRight; +static double SpreadZ; static const DBaseDecal *SpreadSource; static const FDecalTemplate *SpreadTemplate; static TArray SpreadStack; @@ -65,25 +65,25 @@ IMPLEMENT_CLASS (DImpactDecal) DBaseDecal::DBaseDecal () : DThinker(STAT_DECAL), - WallNext(0), WallPrev(0), LeftDistance(0), Z(0), ScaleX(FRACUNIT), ScaleY(FRACUNIT), Alpha(FRACUNIT), + WallNext(0), WallPrev(0), LeftDistance(0), Z(0), ScaleX(1.), ScaleY(1.), Alpha(1.), AlphaColor(0), Translation(0), RenderFlags(0) { RenderStyle = STYLE_None; PicNum.SetInvalid(); } -DBaseDecal::DBaseDecal (fixed_t z) +DBaseDecal::DBaseDecal (double z) : DThinker(STAT_DECAL), - WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(FRACUNIT), ScaleY(FRACUNIT), Alpha(FRACUNIT), + WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(1.), ScaleY(1.), Alpha(1.), AlphaColor(0), Translation(0), RenderFlags(0) { RenderStyle = STYLE_None; PicNum.SetInvalid(); } -DBaseDecal::DBaseDecal (int statnum, fixed_t z) +DBaseDecal::DBaseDecal (int statnum, double z) : DThinker(statnum), - WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(FRACUNIT), ScaleY(FRACUNIT), Alpha(FRACUNIT), + WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(1.), ScaleY(1.), Alpha(1.), AlphaColor(0), Translation(0), RenderFlags(0) { RenderStyle = STYLE_None; @@ -92,8 +92,8 @@ DBaseDecal::DBaseDecal (int statnum, fixed_t z) DBaseDecal::DBaseDecal (const AActor *basis) : DThinker(STAT_DECAL), - WallNext(0), WallPrev(0), LeftDistance(0), Z(basis->Z()), ScaleX(basis->scaleX), ScaleY(basis->scaleY), - Alpha(basis->alpha), AlphaColor(basis->fillcolor), Translation(basis->Translation), PicNum(basis->picnum), + WallNext(0), WallPrev(0), LeftDistance(0), Z(basis->Z()), ScaleX(basis->Scale.X), ScaleY(basis->Scale.Y), + Alpha(basis->Alpha), AlphaColor(basis->fillcolor), Translation(basis->Translation), PicNum(basis->picnum), RenderFlags(basis->renderflags), RenderStyle(basis->RenderStyle) { } @@ -101,7 +101,7 @@ DBaseDecal::DBaseDecal (const AActor *basis) DBaseDecal::DBaseDecal (const DBaseDecal *basis) : DThinker(STAT_DECAL), WallNext(0), WallPrev(0), LeftDistance(basis->LeftDistance), Z(basis->Z), ScaleX(basis->ScaleX), - ScaleY(basis->ScaleY), Alpha(basis->Alpha), AlphaColor(basis->AlphaColor), Translation(basis->Translation), + ScaleY(basis->ScaleY), Alpha(basis->Alpha), AlphaColor(basis->AlphaColor), Translation(basis->Translation), PicNum(basis->PicNum), RenderFlags(basis->RenderFlags), RenderStyle(basis->RenderStyle) { } @@ -174,7 +174,7 @@ void DBaseDecal::SerializeChain (FArchive &arc, DBaseDecal **first) } } -void DBaseDecal::GetXY (side_t *wall, fixed_t &ox, fixed_t &oy) const +void DBaseDecal::GetXY (side_t *wall, double &ox, double &oy) const { line_t *line = wall->linedef; vertex_t *v1, *v2; @@ -190,11 +190,11 @@ void DBaseDecal::GetXY (side_t *wall, fixed_t &ox, fixed_t &oy) const v2 = line->v1; } - fixed_t dx = v2->x - v1->x; - fixed_t dy = v2->y - v1->y; + double dx = v2->fX() - v1->fX(); + double dy = v2->fY() - v1->fY(); - ox = v1->x + MulScale30 (LeftDistance, dx); - oy = v1->y + MulScale30 (LeftDistance, dy); + ox = v1->fX() + LeftDistance * dx; + oy = v1->fY() + LeftDistance * dy; } void DBaseDecal::SetShade (DWORD rgb) @@ -209,7 +209,7 @@ void DBaseDecal::SetShade (int r, int g, int b) } // Returns the texture the decal stuck to. -FTextureID DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y, F3DFloor *ffloor) +FTextureID DBaseDecal::StickToWall (side_t *wall, double x, double y, F3DFloor *ffloor) { // Stick the decal at the end of the chain so it appears on top DBaseDecal *next, **prev; @@ -250,27 +250,27 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y, F3DFloor { RenderFlags |= RF_RELMID; if (line->flags & ML_DONTPEGBOTTOM) - Z -= front->GetPlaneTexZ(sector_t::floor); + Z -= front->GetPlaneTexZF(sector_t::floor); else - Z -= front->GetPlaneTexZ(sector_t::ceiling); + Z -= front->GetPlaneTexZF(sector_t::ceiling); tex = wall->GetTexture(side_t::mid); } else if (back->floorplane.ZatPoint (x, y) >= Z) { RenderFlags |= RF_RELLOWER|RF_CLIPLOWER; if (line->flags & ML_DONTPEGBOTTOM) - Z -= front->GetPlaneTexZ(sector_t::ceiling); + Z -= front->GetPlaneTexZF(sector_t::ceiling); else - Z -= back->GetPlaneTexZ(sector_t::floor); + Z -= back->GetPlaneTexZF(sector_t::floor); tex = wall->GetTexture(side_t::bottom); } else if (back->ceilingplane.ZatPoint (x, y) <= Z) { RenderFlags |= RF_RELUPPER|RF_CLIPUPPER; if (line->flags & ML_DONTPEGTOP) - Z -= front->GetPlaneTexZ(sector_t::ceiling); + Z -= front->GetPlaneTexZF(sector_t::ceiling); else - Z -= back->GetPlaneTexZ(sector_t::ceiling); + Z -= back->GetPlaneTexZF(sector_t::ceiling); tex = wall->GetTexture(side_t::top); } else if (ffloor) // this is a 3d-floor segment - do this only if we know which one! @@ -278,9 +278,9 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y, F3DFloor Sector=ffloor->model; RenderFlags |= RF_RELMID|RF_CLIPMID; if (line->flags & ML_DONTPEGBOTTOM) - Z -= Sector->GetPlaneTexZ(sector_t::floor); + Z -= Sector->GetPlaneTexZF(sector_t::floor); else - Z -= Sector->GetPlaneTexZ(sector_t::ceiling); + Z -= Sector->GetPlaneTexZF(sector_t::ceiling); if (ffloor->flags & FF_UPPERTEXTURE) { @@ -308,7 +308,7 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y, F3DFloor return tex; } -fixed_t DBaseDecal::GetRealZ (const side_t *wall) const +double DBaseDecal::GetRealZ (const side_t *wall) const { const line_t *line = wall->linedef; const sector_t *front, *back; @@ -335,34 +335,34 @@ fixed_t DBaseDecal::GetRealZ (const side_t *wall) const case RF_RELUPPER: if (line->flags & ML_DONTPEGTOP) { - return Z + front->GetPlaneTexZ(sector_t::ceiling); + return Z + front->GetPlaneTexZF(sector_t::ceiling); } else { - return Z + back->GetPlaneTexZ(sector_t::ceiling); + return Z + back->GetPlaneTexZF(sector_t::ceiling); } case RF_RELLOWER: if (line->flags & ML_DONTPEGBOTTOM) { - return Z + front->GetPlaneTexZ(sector_t::ceiling); + return Z + front->GetPlaneTexZF(sector_t::ceiling); } else { - return Z + back->GetPlaneTexZ(sector_t::floor); + return Z + back->GetPlaneTexZF(sector_t::floor); } case RF_RELMID: if (line->flags & ML_DONTPEGBOTTOM) { - return Z + front->GetPlaneTexZ(sector_t::floor); + return Z + front->GetPlaneTexZF(sector_t::floor); } else { - return Z + front->GetPlaneTexZ(sector_t::ceiling); + return Z + front->GetPlaneTexZF(sector_t::ceiling); } } } -void DBaseDecal::CalcFracPos (side_t *wall, fixed_t x, fixed_t y) +void DBaseDecal::CalcFracPos (side_t *wall, double x, double y) { line_t *line = wall->linedef; vertex_t *v1, *v2; @@ -378,16 +378,16 @@ void DBaseDecal::CalcFracPos (side_t *wall, fixed_t x, fixed_t y) v2 = line->v1; } - fixed_t dx = v2->x - v1->x; - fixed_t dy = v2->y - v1->y; + double dx = v2->fX() - v1->fX(); + double dy = v2->fY() - v1->fY(); - if (abs(dx) > abs(dy)) + if (fabs(dx) > fabs(dy)) { - LeftDistance = SafeDivScale30 (x - v1->x, dx); + LeftDistance = (x - v1->fX()) / dx; } else if (dy != 0) { - LeftDistance = SafeDivScale30 (y - v1->y, dy); + LeftDistance = (y - v1->fY()) / dy; } else { @@ -395,26 +395,26 @@ void DBaseDecal::CalcFracPos (side_t *wall, fixed_t x, fixed_t y) } } -static void GetWallStuff (side_t *wall, vertex_t *&v1, fixed_t &ldx, fixed_t &ldy) +static void GetWallStuff (side_t *wall, vertex_t *&v1, double &ldx, double &ldy) { line_t *line = wall->linedef; if (line->sidedef[0] == wall) { v1 = line->v1; - ldx = line->dx; - ldy = line->dy; + ldx = line->Delta().X; + ldy = line->Delta().Y; } else { v1 = line->v2; - ldx = -line->dx; - ldy = -line->dy; + ldx = -line->Delta().X; + ldy = -line->Delta().Y; } } -static fixed_t Length (fixed_t dx, fixed_t dy) +static double Length (double dx, double dy) { - return (fixed_t)sqrt ((double)dx*(double)dx+(double)dy*(double)dy); + return DVector2(dx, dy).Length(); } static side_t *NextWall (const side_t *wall) @@ -435,25 +435,25 @@ static side_t *NextWall (const side_t *wall) return NULL; } -void DBaseDecal::SpreadLeft (fixed_t r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor) +void DBaseDecal::SpreadLeft (double r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor) { - fixed_t ldx, ldy; + double ldx, ldy; SpreadStack.Push (feelwall); while (r < 0 && feelwall->LeftSide != NO_SIDE) { - fixed_t startr = r; + double startr = r; - fixed_t x = v1->x; - fixed_t y = v1->y; + double x = v1->fX(); + double y = v1->fY(); feelwall = &sides[feelwall->LeftSide]; GetWallStuff (feelwall, v1, ldx, ldy); - fixed_t wallsize = Length (ldx, ldy); + double wallsize = Length (ldx, ldy); r += DecalLeft; - x += Scale (r, ldx, wallsize); - y += Scale (r, ldy, wallsize); + x += r*ldx / wallsize; + y += r*ldy / wallsize; r = wallsize + startr; SpreadSource->CloneSelf (SpreadTemplate, x, y, SpreadZ, feelwall, ffloor); SpreadStack.Push (feelwall); @@ -479,10 +479,10 @@ void DBaseDecal::SpreadLeft (fixed_t r, vertex_t *v1, side_t *feelwall, F3DFloor } } -void DBaseDecal::SpreadRight (fixed_t r, side_t *feelwall, fixed_t wallsize, F3DFloor *ffloor) +void DBaseDecal::SpreadRight (double r, side_t *feelwall, double wallsize, F3DFloor *ffloor) { vertex_t *v1; - fixed_t x, y, ldx, ldy; + double x, y, ldx, ldy; SpreadStack.Push (feelwall); @@ -508,25 +508,25 @@ void DBaseDecal::SpreadRight (fixed_t r, side_t *feelwall, fixed_t wallsize, F3D r = DecalWidth - r + wallsize - DecalLeft; GetWallStuff (feelwall, v1, ldx, ldy); - x = v1->x; - y = v1->y; + x = v1->fX(); + y = v1->fY(); wallsize = Length (ldx, ldy); - x -= Scale (r, ldx, wallsize); - y -= Scale (r, ldy, wallsize); + x -= r*ldx / wallsize; + y -= r*ldy / wallsize; r = DecalRight - r; SpreadSource->CloneSelf (SpreadTemplate, x, y, SpreadZ, feelwall, ffloor); SpreadStack.Push (feelwall); } } -void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, fixed_t x, fixed_t y, fixed_t z, F3DFloor * ffloor) +void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, double y, double z, F3DFloor * ffloor) { FTexture *tex; vertex_t *v1; - fixed_t rorg, ldx, ldy; + double rorg, ldx, ldy; GetWallStuff (wall, v1, ldx, ldy); - rorg = Length (x - v1->x, y - v1->y); + rorg = Length (x - v1->fX(), y - v1->fY()); if ((tex = TexMan[PicNum]) == NULL) { @@ -548,11 +548,11 @@ void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, fixed_t x, fix // Then try spreading right SpreadRight (rorg + DecalRight, wall, - Length (wall->linedef->dx, wall->linedef->dy), ffloor); + Length (wall->linedef->Delta().X, wall->linedef->Delta().Y), ffloor); SpreadStack.Clear (); } -DBaseDecal *DBaseDecal::CloneSelf (const FDecalTemplate *tpl, fixed_t ix, fixed_t iy, fixed_t iz, side_t *wall, F3DFloor * ffloor) const +DBaseDecal *DBaseDecal::CloneSelf (const FDecalTemplate *tpl, double ix, double iy, double iz, side_t *wall, F3DFloor * ffloor) const { DBaseDecal *decal = new DBaseDecal(iz); if (decal != NULL) @@ -615,12 +615,12 @@ void DImpactDecal::Serialize (FArchive &arc) } DImpactDecal::DImpactDecal () -: DBaseDecal (STAT_AUTODECAL, 0) +: DBaseDecal (STAT_AUTODECAL, 0.) { ImpactCount++; } -DImpactDecal::DImpactDecal (fixed_t z) +DImpactDecal::DImpactDecal (double z) : DBaseDecal (STAT_AUTODECAL, z) { ImpactCount++; @@ -638,7 +638,7 @@ void DImpactDecal::CheckMax () } } -DImpactDecal *DImpactDecal::StaticCreate (const char *name, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color) +DImpactDecal *DImpactDecal::StaticCreate (const char *name, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color) { if (cl_maxdecals > 0) { @@ -652,7 +652,7 @@ DImpactDecal *DImpactDecal::StaticCreate (const char *name, const fixedvec3 &pos return NULL; } -DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color) +DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color) { DImpactDecal *decal = NULL; if (tpl != NULL && cl_maxdecals > 0 && !(wall->Flags & WALLF_NOAUTODECALS)) @@ -669,13 +669,13 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const fixed StaticCreate (tpl_low, pos, wall, ffloor, lowercolor); } DImpactDecal::CheckMax(); - decal = new DImpactDecal (pos.z); + decal = new DImpactDecal (pos.Z); if (decal == NULL) { return NULL; } - if (!decal->StickToWall (wall, pos.x, pos.y, ffloor).isValid()) + if (!decal->StickToWall (wall, pos.X, pos.Y, ffloor).isValid()) { return NULL; } @@ -692,12 +692,12 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const fixed } // Spread decal to nearby walls if it does not all fit on this one - decal->Spread (tpl, wall, pos.x, pos.y, pos.z, ffloor); + decal->Spread (tpl, wall, pos.X, pos.Y, pos.Z, ffloor); } return decal; } -DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, fixed_t ix, fixed_t iy, fixed_t iz, side_t *wall, F3DFloor * ffloor) const +DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, double ix, double iy, double iz, side_t *wall, F3DFloor * ffloor) const { if (wall->Flags & WALLF_NOAUTODECALS) { @@ -758,7 +758,7 @@ CCMD (spray) Net_WriteString (argv[1]); } -DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, fixed_t x, fixed_t y, fixed_t z, angle_t angle, fixed_t tracedist, bool permanent) +DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent) { if (tpl == NULL || (tpl = tpl->GetDecal()) == NULL) { @@ -769,24 +769,20 @@ DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t * DBaseDecal *decal; side_t *wall; - angle >>= ANGLETOFINESHIFT; - - Trace(x, y, z, sec, - finecosine[angle], finesine[angle], 0, - tracedist, 0, 0, NULL, trace, TRACE_NoSky); + Trace(DVector3(x,y,z), sec, DVector3(angle.ToVector(), 0), tracedist, 0, 0, NULL, trace, TRACE_NoSky); if (trace.HitType == TRACE_HitWall) { if (permanent) { - decal = new DBaseDecal(trace.HitPos.z); + decal = new DBaseDecal(trace.HitPos.Z); wall = trace.Line->sidedef[trace.Side]; - decal->StickToWall(wall, trace.HitPos.x, trace.HitPos.y, trace.ffloor); + decal->StickToWall(wall, trace.HitPos.X, trace.HitPos.Y, trace.ffloor); tpl->ApplyToDecal(decal, wall); // Spread decal to nearby walls if it does not all fit on this one if (cl_spreaddecals) { - decal->Spread(tpl, wall, trace.HitPos.x, trace.HitPos.y, trace.HitPos.z, trace.ffloor); + decal->Spread(tpl, wall, trace.HitPos.X, trace.HitPos.Y, trace.HitPos.Z, trace.ffloor); } return decal; } @@ -820,22 +816,22 @@ void ADecal::BeginPlay () { if (!tpl->PicNum.Exists()) { - Printf("Decal actor at (%d,%d) does not have a valid texture\n", X()>>FRACBITS, Y()>>FRACBITS); + Printf("Decal actor at (%f,%f) does not have a valid texture\n", X(), Y()); } else { // Look for a wall within 64 units behind the actor. If none can be // found, then no decal is created, and this actor is destroyed // without effectively doing anything. - if (NULL == ShootDecal(tpl, this, Sector, X(), Y(), Z(), angle + ANGLE_180, 64*FRACUNIT, true)) + if (NULL == ShootDecal(tpl, this, Sector, X(), Y(), Z(), Angles.Yaw + 180, 64., true)) { - DPrintf ("Could not find a wall to stick decal to at (%d,%d)\n", X()>>FRACBITS, Y()>>FRACBITS); + DPrintf ("Could not find a wall to stick decal to at (%f,%f)\n", X(), Y()); } } } else { - DPrintf ("Decal actor at (%d,%d) does not have a good template\n", X()>>FRACBITS, Y()>>FRACBITS); + DPrintf ("Decal actor at (%f,%f) does not have a good template\n", X(), Y()); } // This actor doesn't need to stick around anymore. Destroy(); diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index bf35157b3..8c7d63b74 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -22,13 +22,11 @@ IMPLEMENT_CLASS(AFastProjectile) void AFastProjectile::Tick () { int i; - fixed_t xfrac; - fixed_t yfrac; - fixed_t zfrac; + DVector3 frac; int changexy; ClearInterpolation(); - fixed_t oldz = Z(); + double oldz = Z(); if (!(flags5 & MF5_NOTIMEFREEZE)) { @@ -43,26 +41,22 @@ void AFastProjectile::Tick () // [RH] Ripping is a little different than it was in Hexen FCheckPosition tm(!!(flags2 & MF2_RIP)); - int shift = 3; int count = 8; if (radius > 0) { - while ( ((abs(vel.x) >> shift) > radius) || ((abs(vel.y) >> shift) > radius)) + while ( fabs(Vel.X) > radius * count || fabs(Vel.Y) > radius * count) { // we need to take smaller steps. - shift++; - count<<=1; + count += count; } } // Handle movement - if (vel.x || vel.y || (Z() != floorz) || vel.z) + if (!Vel.isZero() || (Z() != floorz)) { - xfrac = vel.x >> shift; - yfrac = vel.y >> shift; - zfrac = vel.z >> shift; - changexy = xfrac || yfrac; - int ripcount = count >> 3; + frac = Vel / count; + changexy = frac.X != 0 || frac.Y != 0; + int ripcount = count / 8; for (i = 0; i < count; i++) { if (changexy) @@ -72,7 +66,7 @@ void AFastProjectile::Tick () tm.LastRipped.Clear(); // [RH] Do rip damage each step, like Hexen } - if (!P_TryMove (this, X() + xfrac,Y() + yfrac, true, NULL, tm)) + if (!P_TryMove (this, Pos() + frac, true, NULL, tm)) { // Blocked move if (!(flags3 & MF3_SKYEXPLODE)) { @@ -98,10 +92,10 @@ void AFastProjectile::Tick () return; } } - AddZ(zfrac); - UpdateWaterLevel (oldz); + AddZ(frac.Z); + UpdateWaterLevel (); oldz = Z(); - if (Z() <= floorz) + if (oldz <= floorz) { // Hit the floor if (floorpic == skyflatnum && !(flags3 & MF3_SKYEXPLODE)) @@ -126,7 +120,7 @@ void AFastProjectile::Tick () return; } - SetZ(ceilingz - height); + SetZ(ceilingz - Height); P_ExplodeMissile (this, NULL, NULL); return; } @@ -156,28 +150,25 @@ void AFastProjectile::Tick () void AFastProjectile::Effect() { - //if (pr_smoke() < 128) // [RH] I think it looks better if it's consistent + FName name = GetClass()->MissileName; + if (name != NAME_None) { - FName name = GetClass()->MissileName; - if (name != NAME_None) - { - fixed_t hitz = Z()-8*FRACUNIT; + double hitz = Z()-8; - if (hitz < floorz) - { - hitz = floorz; - } - // Do not clip this offset to the floor. - hitz += GetClass()->MissileHeight; + if (hitz < floorz) + { + hitz = floorz; + } + // Do not clip this offset to the floor. + hitz += GetClass()->MissileHeight; - PClassActor *trail = PClass::FindActor(name); - if (trail != NULL) + PClassActor *trail = PClass::FindActor(name); + if (trail != NULL) + { + AActor *act = Spawn (trail, PosAtZ(hitz), ALLOW_REPLACE); + if (act != NULL) { - AActor *act = Spawn (trail, X(), Y(), hitz, ALLOW_REPLACE); - if (act != NULL) - { - act->angle = this->angle; - } + act->Angles.Yaw = Angles.Yaw; } } } diff --git a/src/g_shared/a_hatetarget.cpp b/src/g_shared/a_hatetarget.cpp index 53cec29f9..4d0d9a8e7 100644 --- a/src/g_shared/a_hatetarget.cpp +++ b/src/g_shared/a_hatetarget.cpp @@ -40,22 +40,20 @@ class AHateTarget : public AActor { - DECLARE_CLASS (AHateTarget, AActor) + DECLARE_CLASS(AHateTarget, AActor) public: - void BeginPlay (); - int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype); + void BeginPlay(); + int TakeSpecialDamage(AActor *inflictor, AActor *source, int damage, FName damagetype); }; -IMPLEMENT_CLASS (AHateTarget) +IMPLEMENT_CLASS(AHateTarget) -void AHateTarget::BeginPlay () +void AHateTarget::BeginPlay() { - Super::BeginPlay (); - if (angle != 0) + Super::BeginPlay(); + if (SpawnAngle != 0) { // Each degree translates into 10 units of health - health = Scale (angle >> 1, 1800, 0x40000000); - // Round to the nearest 10 because of inaccuracy above - health = (health + 5) / 10 * 10; + health = SpawnAngle * 10; } else { @@ -64,7 +62,7 @@ void AHateTarget::BeginPlay () } } -int AHateTarget::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype) +int AHateTarget::TakeSpecialDamage(AActor *inflictor, AActor *source, int damage, FName damagetype) { if (special2 != 0) { diff --git a/src/g_shared/a_lightning.cpp b/src/g_shared/a_lightning.cpp index 5a53bea37..2f2c4e235 100644 --- a/src/g_shared/a_lightning.cpp +++ b/src/g_shared/a_lightning.cpp @@ -44,26 +44,6 @@ void DLightningThinker::Serialize (FArchive &arc) arc << Stopped << NextLightningFlash << LightningFlashCount; - if (SaveVersion < 3243) - { - // Do nothing with old savegames and just keep whatever the constructor made - // but read the obsolete data from the savegame - for (i = (numsectors + (numsectors+7)/8); i > 0; --i) - { - if (SaveVersion < 3223) - { - BYTE bytelight; - arc << bytelight; - } - else - { - short shortlight; - arc << shortlight; - } - } - return; - } - if (arc.IsLoading ()) { if (LightningLightLevels != NULL) diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index acd5f6f5c..174bfd4a2 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -88,7 +88,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp actor->RemoveFromHash (); actor->tid = 0; } - morphed->angle = actor->angle; + morphed->Angles.Yaw = actor->Angles.Yaw; morphed->target = actor->target; morphed->tracer = actor; morphed->Score = actor->Score; @@ -120,7 +120,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp p->MorphExitFlash = (exit_flash) ? exit_flash : RUNTIME_CLASS(ATeleportFog); p->health = morphed->health; p->mo = morphed; - p->vel.x = p->vel.y = 0; + p->Vel.X = p->Vel.Y = 0; morphed->ObtainInventory (actor); // Remove all armor for (item = morphed->Inventory; item != NULL; ) @@ -168,7 +168,6 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, AWeapon *beastweap; APlayerPawn *mo; APlayerPawn *pmo; - angle_t angle; pmo = player->mo; // [MH] @@ -223,15 +222,13 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, mo->tid = pmo->tid; mo->AddToHash (); } - mo->angle = pmo->angle; + mo->Angles.Yaw = pmo->Angles.Yaw; mo->player = player; mo->reactiontime = 18; mo->flags = ActorFlags::FromInt (pmo->special2) & ~MF_JUSTHIT; - mo->vel.x = 0; - mo->vel.y = 0; - player->vel.x = 0; - player->vel.y = 0; - mo->vel.z = pmo->vel.z; + mo->Vel.X = mo->Vel.Y = 0; + player->Vel.Zero(); + mo->Vel.Z = pmo->Vel.Z; if (!(pmo->special2 & MF_JUSTHIT)) { mo->renderflags &= ~RF_INVISIBLE; @@ -307,11 +304,10 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, } } - angle = mo->angle >> ANGLETOFINESHIFT; AActor *eflash = NULL; if (exit_flash != NULL) { - eflash = Spawn(exit_flash, pmo->Vec3Offset(20*finecosine[angle], 20*finesine[angle], TELEFOGHEIGHT), ALLOW_REPLACE); + eflash = Spawn(exit_flash, pmo->Vec3Angle(20., mo->Angles.Yaw, TELEFOGHEIGHT), ALLOW_REPLACE); if (eflash) eflash->target = mo; } mo->SetupWeaponSlots(); // Use original class's weapon slots. @@ -385,9 +381,9 @@ bool P_MorphMonster (AActor *actor, PClassActor *spawntype, int duration, int st morphed = static_cast(Spawn (spawntype, actor->Pos(), NO_REPLACE)); DObject::StaticPointerSubstitution (actor, morphed); morphed->tid = actor->tid; - morphed->angle = actor->angle; + morphed->Angles.Yaw = actor->Angles.Yaw; morphed->UnmorphedMe = actor; - morphed->alpha = actor->alpha; + morphed->Alpha = actor->Alpha; morphed->RenderStyle = actor->RenderStyle; morphed->Score = actor->Score; @@ -450,7 +446,7 @@ bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force) beast->UnmorphTime = level.time + 5*TICRATE; // Next try in 5 seconds return false; } - actor->angle = beast->angle; + actor->Angles.Yaw = beast->Angles.Yaw; actor->target = beast->target; actor->FriendPlayer = beast->FriendPlayer; actor->flags = beast->FlagsSave & ~MF_JUSTHIT; @@ -461,9 +457,7 @@ bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force) if (!(beast->FlagsSave & MF_JUSTHIT)) actor->renderflags &= ~RF_INVISIBLE; actor->health = actor->SpawnHealth(); - actor->vel.x = beast->vel.x; - actor->vel.y = beast->vel.y; - actor->vel.z = beast->vel.z; + actor->Vel = beast->Vel; actor->tid = beast->tid; actor->special = beast->special; actor->Score = beast->Score; diff --git a/src/g_shared/a_movingcamera.cpp b/src/g_shared/a_movingcamera.cpp index b67e7f8e3..202e1823f 100644 --- a/src/g_shared/a_movingcamera.cpp +++ b/src/g_shared/a_movingcamera.cpp @@ -102,11 +102,7 @@ void AInterpolationPoint::FormChain () if (Next == NULL && (args[3] | args[4])) Printf ("Can't find target for camera node %d\n", tid); - pitch = (signed int)((char)args[0]) * ANGLE_1; - if (pitch <= -ANGLE_90) - pitch = -ANGLE_90 + ANGLE_1; - else if (pitch >= ANGLE_90) - pitch = ANGLE_90 - ANGLE_1; + Angles.Pitch = (double)clamp((signed char)args[0], -89, 89); if (Next != NULL) Next->FormChain (); @@ -302,7 +298,7 @@ void APathFollower::Tick () if (CurrNode->args[2]) { HoldTime = level.time + CurrNode->args[2] * TICRATE / 8; - SetXYZ(CurrNode->X(), CurrNode->Y(), CurrNode->Z()); + SetXYZ(CurrNode->Pos()); } } @@ -356,37 +352,32 @@ void APathFollower::NewNode () bool APathFollower::Interpolate () { - fixed_t dx = 0, dy = 0, dz = 0; + DVector3 dpos(0, 0, 0); if ((args[2] & 8) && Time > 0.f) { - dx = X(); - dy = Y(); - dz = Z(); + dpos = Pos(); } if (CurrNode->Next==NULL) return false; UnlinkFromWorld (); - fixed_t x, y, z; + DVector3 newpos; if (args[2] & 1) { // linear - x = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->X()), FIXED2DBL(CurrNode->Next->X()))); - y = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->Y()), FIXED2DBL(CurrNode->Next->Y()))); - z = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->Z()), FIXED2DBL(CurrNode->Next->Z()))); + newpos.X = Lerp(CurrNode->X(), CurrNode->Next->X()); + newpos.Y = Lerp(CurrNode->Y(), CurrNode->Next->Y()); + newpos.Z = Lerp(CurrNode->Z(), CurrNode->Next->Z()); } else { // spline if (CurrNode->Next->Next==NULL) return false; - x = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->X()), FIXED2DBL(CurrNode->X()), - FIXED2DBL(CurrNode->Next->X()), FIXED2DBL(CurrNode->Next->Next->X()))); - y = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->Y()), FIXED2DBL(CurrNode->Y()), - FIXED2DBL(CurrNode->Next->Y()), FIXED2DBL(CurrNode->Next->Next->Y()))); - z = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->Z()), FIXED2DBL(CurrNode->Z()), - FIXED2DBL(CurrNode->Next->Z()), FIXED2DBL(CurrNode->Next->Next->Z()))); + newpos.X = Splerp(PrevNode->X(), CurrNode->X(), CurrNode->Next->X(), CurrNode->Next->Next->X()); + newpos.Y = Splerp(PrevNode->Y(), CurrNode->Y(), CurrNode->Next->Y(), CurrNode->Next->Next->Y()); + newpos.Z = Splerp(PrevNode->Z(), CurrNode->Z(), CurrNode->Next->Z(), CurrNode->Next->Next->Z()); } - SetXYZ(x, y, z); + SetXYZ(newpos); LinkToWorld (); if (args[2] & 6) @@ -395,97 +386,58 @@ bool APathFollower::Interpolate () { if (args[2] & 1) { // linear - dx = CurrNode->Next->X() - CurrNode->X(); - dy = CurrNode->Next->Y() - CurrNode->Y(); - dz = CurrNode->Next->Z() - CurrNode->Z(); + dpos.X = CurrNode->Next->X() - CurrNode->X(); + dpos.Y = CurrNode->Next->Y() - CurrNode->Y(); + dpos.Z = CurrNode->Next->Z() - CurrNode->Z(); } else if (Time > 0.f) { // spline - dx = x - dx; - dy = y - dy; - dz = z - dz; + dpos = newpos - dpos; } else { int realarg = args[2]; args[2] &= ~(2|4|8); Time += 0.1f; - dx = x; - dy = y; - dz = z; + dpos = newpos; Interpolate (); Time -= 0.1f; args[2] = realarg; - dx = x - dx; - dy = y - dy; - dz = z - dz; - x -= dx; - y -= dy; - z -= dz; - SetXYZ(x, y, z); + dpos = newpos - dpos; + newpos -= dpos; + SetXYZ(newpos); } if (args[2] & 2) { // adjust yaw - angle = R_PointToAngle2 (0, 0, dx, dy); + Angles.Yaw = dpos.Angle(); } if (args[2] & 4) { // adjust pitch; use floats for precision - double fdx = FIXED2DBL(dx); - double fdy = FIXED2DBL(dy); - double fdz = FIXED2DBL(-dz); - double dist = sqrt (fdx*fdx + fdy*fdy); - double ang = dist != 0.f ? atan2 (fdz, dist) : 0; - pitch = (fixed_t)RAD2ANGLE(ang); + double dist = dpos.XY().Length(); + Angles.Pitch = dist != 0.f ? VecToAngle(dist, -dpos.Z) : 0.; } } else { if (args[2] & 2) { // interpolate angle - double angle1 = (double)CurrNode->angle; - double angle2 = (double)CurrNode->Next->angle; - if (angle2 - angle1 <= -2147483648.f) - { - double lerped = Lerp (angle1, angle2 + 4294967296.f); - if (lerped >= 4294967296.f) - { - angle = xs_CRoundToUInt(lerped - 4294967296.f); - } - else - { - angle = xs_CRoundToUInt(lerped); - } - } - else if (angle2 - angle1 >= 2147483648.f) - { - double lerped = Lerp (angle1, angle2 - 4294967296.f); - if (lerped < 0.f) - { - angle = xs_CRoundToUInt(lerped + 4294967296.f); - } - else - { - angle = xs_CRoundToUInt(lerped); - } - } - else - { - angle = xs_CRoundToUInt(Lerp (angle1, angle2)); - } + DAngle angle1 = CurrNode->Angles.Yaw.Normalized180(); + DAngle angle2 = angle1 + deltaangle(angle1, CurrNode->Next->Angles.Yaw); + Angles.Yaw = Lerp(angle1.Degrees, angle2.Degrees); } if (args[2] & 1) { // linear if (args[2] & 4) { // interpolate pitch - pitch = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->pitch), FIXED2DBL(CurrNode->Next->pitch))); + Angles.Pitch = Lerp(CurrNode->Angles.Pitch.Degrees, CurrNode->Next->Angles.Pitch.Degrees); } } else { // spline if (args[2] & 4) { // interpolate pitch - pitch = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->pitch), FIXED2DBL(CurrNode->pitch), - FIXED2DBL(CurrNode->Next->pitch), FIXED2DBL(CurrNode->Next->Next->pitch))); + Angles.Pitch = Splerp(PrevNode->Angles.Pitch.Degrees, CurrNode->Angles.Pitch.Degrees, + CurrNode->Next->Angles.Pitch.Degrees, CurrNode->Next->Next->Angles.Pitch.Degrees); } } } @@ -549,18 +501,18 @@ bool AActorMover::Interpolate () if (Super::Interpolate ()) { - fixed_t savedz = tracer->Z(); + double savedz = tracer->Z(); tracer->SetZ(Z()); - if (!P_TryMove (tracer, X(), Y(), true)) + if (!P_TryMove (tracer, Pos(), true)) { tracer->SetZ(savedz); return false; } if (args[2] & 2) - tracer->angle = angle; + tracer->Angles.Yaw = Angles.Yaw; if (args[2] & 4) - tracer->pitch = pitch; + tracer->Angles.Pitch = Angles.Pitch; return true; } @@ -665,16 +617,13 @@ bool AMovingCamera::Interpolate () if (Super::Interpolate ()) { - angle = AngleTo(tracer, true); + Angles.Yaw = AngleTo(tracer, true); if (args[2] & 4) - { // Also aim camera's pitch; use floats for precision - double dx = FIXED2DBL(X() - tracer->X()); - double dy = FIXED2DBL(Y() - tracer->Y()); - double dz = FIXED2DBL(Z() - tracer->Z() - tracer->height/2); - double dist = sqrt (dx*dx + dy*dy); - double ang = dist != 0.f ? atan2 (dz, dist) : 0; - pitch = RAD2ANGLE(ang); + { // Also aim camera's pitch; + DVector3 diff = Pos() - tracer->PosPlusZ(tracer->Height / 2); + double dist = diff.XY().Length(); + Angles.Pitch = dist != 0.f ? VecToAngle(dist, diff.Z) : 0.; } return true; diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index b2a80cbc2..6ad8e6e4a 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -141,7 +141,7 @@ bool AAmmo::HandlePickup (AInventory *item) if (!(item->ItemFlags & IF_IGNORESKILL)) { // extra ammo in baby mode and nightmare mode - receiving = FixedMul(receiving, G_SkillProperty(SKILLP_AmmoFactor)); + receiving = int(receiving * G_SkillProperty(SKILLP_AmmoFactor)); } int oldamount = Amount; @@ -193,7 +193,7 @@ AInventory *AAmmo::CreateCopy (AActor *other) // extra ammo in baby mode and nightmare mode if (!(ItemFlags&IF_IGNORESKILL)) { - amount = FixedMul(amount, G_SkillProperty(SKILLP_AmmoFactor)); + amount = int(amount * G_SkillProperty(SKILLP_AmmoFactor)); } if (GetClass()->ParentClass != RUNTIME_CLASS(AAmmo) && GetClass() != RUNTIME_CLASS(AAmmo)) @@ -204,7 +204,7 @@ AInventory *AAmmo::CreateCopy (AActor *other) Destroy (); } - copy = static_cast(Spawn (type, 0, 0, 0, NO_REPLACE)); + copy = static_cast(Spawn (type)); copy->Amount = amount; copy->BecomeItem (); } @@ -298,7 +298,7 @@ bool P_GiveBody (AActor *actor, int num, int max) { if (player->health < max) { - num = FixedMul(num, G_SkillProperty(SKILLP_HealthFactor)); + num = int(num * G_SkillProperty(SKILLP_HealthFactor)); if (num < 1) num = 1; player->health += num; if (player->health > max) @@ -413,28 +413,25 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) PARAM_ACTION_PROLOGUE; // Move item back to its original location - fixed_t _x, _y; - - _x = self->SpawnPoint[0]; - _y = self->SpawnPoint[1]; + DVector2 sp = self->SpawnPoint; self->UnlinkFromWorld(); - self->SetXY(_x, _y); + self->SetXY(sp); self->LinkToWorld(true); - self->SetZ(self->Sector->floorplane.ZatPoint(_x, _y)); + self->SetZ(self->Sector->floorplane.ZatPoint(sp)); P_FindFloorCeiling(self, FFCF_ONLYSPAWNPOS | FFCF_NOPORTALS); // no portal checks here so that things get spawned in this sector. if (self->flags & MF_SPAWNCEILING) { - self->SetZ(self->ceilingz - self->height - self->SpawnPoint[2]); + self->SetZ(self->ceilingz - self->Height - self->SpawnPoint.Z); } else if (self->flags2 & MF2_SPAWNFLOAT) { - fixed_t space = self->ceilingz - self->height - self->floorz; - if (space > 48*FRACUNIT) + double space = self->ceilingz - self->Height - self->floorz; + if (space > 48) { - space -= 40*FRACUNIT; - self->SetZ(((space * pr_restore())>>8) + self->floorz + 40*FRACUNIT); + space -= 40; + self->SetZ((space * pr_restore()) / 256. + self->floorz + 40); } else { @@ -443,7 +440,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) } else { - self->SetZ(self->SpawnPoint[2] + self->floorz); + self->SetZ(self->SpawnPoint.Z + self->floorz); } // Redo floor/ceiling check, in case of 3D floors and portals P_FindFloorCeiling(self, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); @@ -454,7 +451,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) } if ((self->flags & MF_SOLID) && (self->Top() > self->ceilingz)) { // Do the same for the ceiling. - self->SetZ(self->ceilingz - self->height); + self->SetZ(self->ceilingz - self->Height); } // Do not interpolate from the position the actor was at when it was // picked up, in case that is different from where it is now. @@ -747,7 +744,7 @@ AInventory *AInventory::CreateCopy (AActor *other) Amount = MIN(Amount, MaxAmount); if (GoAway ()) { - copy = static_cast(Spawn (GetClass(), 0, 0, 0, NO_REPLACE)); + copy = static_cast(Spawn (GetClass())); copy->Amount = Amount; copy->MaxAmount = MaxAmount; } @@ -902,7 +899,7 @@ void AInventory::ModifyDamage (int damage, FName damageType, int &newdamage, boo // //=========================================================================== -fixed_t AInventory::GetSpeedFactor () +double AInventory::GetSpeedFactor () { if (Inventory != NULL) { @@ -910,7 +907,7 @@ fixed_t AInventory::GetSpeedFactor () } else { - return FRACUNIT; + return 1.; } } @@ -1856,12 +1853,12 @@ AInventory *ABackpackItem::CreateCopy (AActor *other) // extra ammo in baby mode and nightmare mode if (!(ItemFlags&IF_IGNORESKILL)) { - amount = FixedMul(amount, G_SkillProperty(SKILLP_AmmoFactor)); + amount = int(amount * G_SkillProperty(SKILLP_AmmoFactor)); } if (amount < 0) amount = 0; if (ammo == NULL) { // The player did not have the ammo. Add it. - ammo = static_cast(Spawn(atype, 0, 0, 0, NO_REPLACE)); + ammo = static_cast(Spawn(atype)); ammo->Amount = bDepleted ? 0 : amount; if (ammo->BackpackMaxAmount > ammo->MaxAmount) { @@ -1919,7 +1916,7 @@ bool ABackpackItem::HandlePickup (AInventory *item) // extra ammo in baby mode and nightmare mode if (!(item->ItemFlags&IF_IGNORESKILL)) { - amount = FixedMul(amount, G_SkillProperty(SKILLP_AmmoFactor)); + amount = int(amount * G_SkillProperty(SKILLP_AmmoFactor)); } probe->Amount += amount; if (probe->Amount > probe->MaxAmount && !sv_unlimited_pickup) diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 933b235dd..26b27e202 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -46,7 +46,7 @@ private: struct WeaponInfo { PClassWeapon *Type; - fixed_t Position; + int Position; }; void SetInitialPositions(); void Sort(); @@ -207,7 +207,7 @@ public: virtual void AbsorbDamage (int damage, FName damageType, int &newdamage); virtual void ModifyDamage (int damage, FName damageType, int &newdamage, bool passive); - virtual fixed_t GetSpeedFactor(); + virtual double GetSpeedFactor(); virtual bool GetNoTeleportFreeze(); virtual int AlterWeaponSprite (visstyle_t *vis); @@ -274,7 +274,7 @@ public: virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass); int SlotNumber; - fixed_t SlotPriority; + int SlotPriority; }; class AWeapon : public AInventory @@ -288,18 +288,18 @@ public: int MinAmmo1, MinAmmo2; // Minimum ammo needed to switch to this weapon int AmmoUse1, AmmoUse2; // How much ammo to use with each shot int Kickback; - fixed_t YAdjust; // For viewing the weapon fullscreen + float YAdjust; // For viewing the weapon fullscreen (visual only so no need to be a double) FSoundIDNoInit UpSound, ReadySound; // Sounds when coming up and idle PClassWeapon *SisterWeaponType; // Another weapon to pick up with this one PClassActor *ProjectileType; // Projectile used by primary attack PClassActor *AltProjectileType; // Projectile used by alternate attack int SelectionOrder; // Lower-numbered weapons get picked first int MinSelAmmo1, MinSelAmmo2; // Ignore in BestWeapon() if inadequate ammo - fixed_t MoveCombatDist; // Used by bots, but do they *really* need it? + double MoveCombatDist; // Used by bots, but do they *really* need it? int ReloadCounter; // For A_CheckForReload - int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) - fixed_t BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs. - fixed_t BobRangeX, BobRangeY; // [XA] Bobbing range. Defines how far a weapon bobs in either direction. + int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) (visual only so no need to be a double) + float BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs. + float BobRangeX, BobRangeY; // [XA] Bobbing range. Defines how far a weapon bobs in either direction. // In-inventory instance variables TObjPtr Ammo1, Ammo2; @@ -395,7 +395,7 @@ public: bool TryPickup(AActor *&toucher); void Serialize(FArchive &arc); - fixed_t DropAmmoFactor; + double DropAmmoFactor; }; @@ -456,7 +456,7 @@ public: virtual void AbsorbDamage (int damage, FName damageType, int &newdamage); int AbsorbCount; - fixed_t SavePercent; + double SavePercent; int MaxAbsorb; int MaxFullAbsorb; int BonusCount; @@ -473,7 +473,7 @@ public: virtual AInventory *CreateCopy (AActor *other); virtual bool Use (bool pickup); - fixed_t SavePercent; + double SavePercent; int MaxAbsorb; int MaxFullAbsorb; int SaveAmount; @@ -488,7 +488,7 @@ public: virtual AInventory *CreateCopy (AActor *other); virtual bool Use (bool pickup); - fixed_t SavePercent; // The default, for when you don't already have armor + double SavePercent; // The default, for when you don't already have armor int MaxSaveAmount; int MaxAbsorb; int MaxFullAbsorb; @@ -510,8 +510,8 @@ public: virtual void AbsorbDamage (int damage, FName damageType, int &newdamage); void DepleteOrDestroy(); - fixed_t Slots[5]; - fixed_t SlotsIncrement[4]; + double Slots[5]; + double SlotsIncrement[4]; protected: bool AddArmorToSlot (AActor *actor, int slot, int amount); diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 1a9211b4c..a970f8969 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -35,26 +35,22 @@ DEarthquake::DEarthquake() // //========================================================================== -DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int intensityZ, int duration, - int damrad, int tremrad, FSoundID quakesound, int flags, - double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint) - : DThinker(STAT_EARTHQUAKE) +DEarthquake::DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration, + int damrad, int tremrad, FSoundID quakesound, int flags, + double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint) + : DThinker(STAT_EARTHQUAKE) { m_QuakeSFX = quakesound; m_Spot = center; // Radii are specified in tile units (64 pixels) - m_DamageRadius = damrad << FRACBITS; - m_TremorRadius = tremrad << FRACBITS; - m_IntensityX = intensityX << FRACBITS; - m_IntensityY = intensityY << FRACBITS; - m_IntensityZ = intensityZ << FRACBITS; + m_DamageRadius = damrad; + m_TremorRadius = tremrad; + m_Intensity = DVector3(intensityX, intensityY, intensityZ); m_CountdownStart = duration; m_Countdown = duration; m_Flags = flags; - m_WaveSpeedX = (float)waveSpeedX; - m_WaveSpeedY = (float)waveSpeedY; - m_WaveSpeedZ = (float)waveSpeedZ; - m_Falloff = falloff << FRACBITS; + m_WaveSpeed = DVector3(waveSpeedX, waveSpeedY, waveSpeedZ); + m_Falloff = falloff; m_Highpoint = highpoint; m_MiniCount = highpoint; } @@ -68,46 +64,11 @@ DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int in void DEarthquake::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << m_Spot << m_IntensityX << m_Countdown + arc << m_Spot << m_Intensity << m_Countdown << m_TremorRadius << m_DamageRadius - << m_QuakeSFX; - if (SaveVersion < 4519) - { - m_IntensityY = m_IntensityX; - m_IntensityZ = 0; - m_Flags = 0; - } - else - { - arc << m_IntensityY << m_IntensityZ << m_Flags; - } - if (SaveVersion < 4520) - { - m_CountdownStart = 0; - } - else - { - arc << m_CountdownStart; - } - if (SaveVersion < 4521) - { - m_WaveSpeedX = m_WaveSpeedY = m_WaveSpeedZ = 0; - m_IntensityX <<= FRACBITS; - m_IntensityY <<= FRACBITS; - m_IntensityZ <<= FRACBITS; - } - else - { - arc << m_WaveSpeedX << m_WaveSpeedY << m_WaveSpeedZ; - } - if (SaveVersion < 4534) - { - m_Falloff = m_Highpoint = m_MiniCount = 0; - } - else - { - arc << m_Falloff << m_Highpoint << m_MiniCount; - } + << m_QuakeSFX << m_Flags << m_CountdownStart + << m_WaveSpeed + << m_Falloff << m_Highpoint << m_MiniCount; } //========================================================================== @@ -141,9 +102,9 @@ void DEarthquake::Tick () if (playeringame[i] && !(players[i].cheats & CF_NOCLIP)) { AActor *victim = players[i].mo; - fixed_t dist; + double dist; - dist = m_Spot->AproxDistance (victim, true); + dist = m_Spot->Distance2D(victim, true); // Check if in damage radius if (dist < m_DamageRadius && victim->Z() <= victim->floorz) { @@ -152,19 +113,9 @@ void DEarthquake::Tick () P_DamageMobj (victim, NULL, NULL, pr_quake.HitDice (1), NAME_None); } // Thrust player around - angle_t an = victim->angle + ANGLE_1*pr_quake(); - if (m_IntensityX == m_IntensityY) - { // Thrust in a circle - P_ThrustMobj (victim, an, m_IntensityX/2); - } - else - { // Thrust in an ellipse - an >>= ANGLETOFINESHIFT; - // So this is actually completely wrong, but it ought to be good - // enough. Otherwise, I'd have to use tangents and square roots. - victim->vel.x += FixedMul(m_IntensityX/2, finecosine[an]); - victim->vel.y += FixedMul(m_IntensityY/2, finesine[an]); - } + DAngle an = victim->Angles.Yaw + pr_quake(); + victim->Vel.X += m_Intensity.X * an.Cos() * 0.5; + victim->Vel.Y += m_Intensity.Y * an.Sin() * 0.5; } } } @@ -192,10 +143,10 @@ void DEarthquake::Tick () // //========================================================================== -fixed_t DEarthquake::GetModWave(double waveMultiplier) const +double DEarthquake::GetModWave(double waveMultiplier) const { - double time = m_Countdown - FIXED2DBL(r_TicFrac); - return FLOAT2FIXED(sin(waveMultiplier * time * (M_PI * 2 / TICRATE))); + double time = m_Countdown - r_TicFracF; + return g_sin(waveMultiplier * time * (M_PI * 2 / TICRATE)); } //========================================================================== @@ -206,7 +157,7 @@ fixed_t DEarthquake::GetModWave(double waveMultiplier) const // //========================================================================== -fixed_t DEarthquake::GetModIntensity(fixed_t intensity) const +double DEarthquake::GetModIntensity(double intensity) const { assert(m_CountdownStart >= m_Countdown); @@ -265,7 +216,7 @@ fixed_t DEarthquake::GetModIntensity(fixed_t intensity) const scalar = (scalar > divider) ? divider : scalar; } assert(divider > 0); - intensity = Scale(intensity, scalar, divider); + intensity = intensity * scalar / divider; } return intensity; } @@ -275,26 +226,24 @@ fixed_t DEarthquake::GetModIntensity(fixed_t intensity) const // DEarthquake :: GetFalloff // // Given the distance of the player from the quake, find the multiplier. -// Process everything as doubles, and output again as fixed_t (mainly -// because fixed_t was misbehaving here...) // //========================================================================== -fixed_t DEarthquake::GetFalloff(fixed_t dist) const +double DEarthquake::GetFalloff(double dist) const { if ((dist < m_Falloff) || (m_Falloff >= m_TremorRadius) || (m_Falloff <= 0) || (m_TremorRadius - m_Falloff <= 0)) { //Player inside the minimum falloff range, or safety check kicked in. - return FRACUNIT; + return 1.; } else if ((dist > m_Falloff) && (dist < m_TremorRadius)) { //Player inside the radius, and outside the min distance for falloff. - fixed_t tremorsize = m_TremorRadius - m_Falloff; + double tremorsize = m_TremorRadius - m_Falloff; assert(tremorsize > 0); - return (FRACUNIT - FixedDiv((dist - m_Falloff), tremorsize)); + return (1. - ((dist - m_Falloff) / tremorsize)); } else { //Shouldn't happen. - return FRACUNIT; + return 1.; } } @@ -324,14 +273,14 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger { if (quake->m_Spot != NULL) { - fixed_t dist = quake->m_Spot->AproxDistance (victim, true); + double dist = quake->m_Spot->Distance2D (victim, true); if (dist < quake->m_TremorRadius) { - fixed_t falloff = quake->GetFalloff(dist); + double falloff = quake->GetFalloff(dist); ++count; - fixed_t x = quake->GetModIntensity(quake->m_IntensityX); - fixed_t y = quake->GetModIntensity(quake->m_IntensityY); - fixed_t z = quake->GetModIntensity(quake->m_IntensityZ); + double x = quake->GetModIntensity(quake->m_Intensity.X); + double y = quake->GetModIntensity(quake->m_Intensity.Y); + double z = quake->GetModIntensity(quake->m_Intensity.Z); if (!(quake->m_Flags & QF_WAVE)) @@ -339,23 +288,23 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger jiggers.Falloff = MAX(falloff, jiggers.Falloff); if (quake->m_Flags & QF_RELATIVE) { - jiggers.RelIntensityX = MAX(x, jiggers.RelIntensityX); - jiggers.RelIntensityY = MAX(y, jiggers.RelIntensityY); - jiggers.RelIntensityZ = MAX(z, jiggers.RelIntensityZ); + jiggers.RelIntensity.X = MAX(x, jiggers.RelIntensity.X); + jiggers.RelIntensity.Y = MAX(y, jiggers.RelIntensity.Y); + jiggers.RelIntensity.Z = MAX(z, jiggers.RelIntensity.Z); } else { - jiggers.IntensityX = MAX(x, jiggers.IntensityX); - jiggers.IntensityY = MAX(y, jiggers.IntensityY); - jiggers.IntensityZ = MAX(z, jiggers.IntensityZ); + jiggers.Intensity.X = MAX(x, jiggers.Intensity.X); + jiggers.Intensity.Y = MAX(y, jiggers.Intensity.Y); + jiggers.Intensity.Z = MAX(z, jiggers.Intensity.Z); } } else { jiggers.WFalloff = MAX(falloff, jiggers.WFalloff); - fixed_t mx = FixedMul(x, quake->GetModWave(quake->m_WaveSpeedX)); - fixed_t my = FixedMul(y, quake->GetModWave(quake->m_WaveSpeedY)); - fixed_t mz = FixedMul(z, quake->GetModWave(quake->m_WaveSpeedZ)); + double mx = x * quake->GetModWave(quake->m_WaveSpeed.X); + double my = y * quake->GetModWave(quake->m_WaveSpeed.Y); + double mz = z * quake->GetModWave(quake->m_WaveSpeed.Z); // [RH] This only gives effect to the last sine quake. I would // prefer if some way was found to make multiples coexist @@ -364,15 +313,15 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger // relative phases. if (quake->m_Flags & QF_RELATIVE) { - jiggers.RelOffsetX = mx; - jiggers.RelOffsetY = my; - jiggers.RelOffsetZ = mz; + jiggers.RelOffset.X = mx; + jiggers.RelOffset.Y = my; + jiggers.RelOffset.Z = mz; } else { - jiggers.OffsetX = mx; - jiggers.OffsetY = my; - jiggers.OffsetZ = mz; + jiggers.Offset.X = mx; + jiggers.Offset.Y = my; + jiggers.Offset.Z = mz; } } } diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp index 5784197a2..ac162a241 100644 --- a/src/g_shared/a_randomspawner.cpp +++ b/src/g_shared/a_randomspawner.cpp @@ -114,7 +114,7 @@ class ARandomSpawner : public AActor { Species = cls->TypeName; AActor *defmobj = GetDefaultByType(cls); - this->Speed = defmobj->Speed; + this->Speed = defmobj->Speed; this->flags |= (defmobj->flags & MF_MISSILE); this->flags2 |= (defmobj->flags2 & MF2_SEEKERMISSILE); this->flags4 |= (defmobj->flags4 & MF4_SPECTRAL); @@ -160,8 +160,9 @@ class ARandomSpawner : public AActor if (newmobj != NULL) { // copy everything relevant - newmobj->SpawnAngle = newmobj->angle = angle; - newmobj->SpawnPoint[2] = SpawnPoint[2]; + newmobj->SpawnAngle = SpawnAngle; + newmobj->Angles = Angles; + newmobj->SpawnPoint = SpawnPoint; newmobj->special = special; newmobj->args[0] = args[0]; newmobj->args[1] = args[1]; @@ -175,9 +176,7 @@ class ARandomSpawner : public AActor newmobj->SpawnFlags = SpawnFlags; newmobj->tid = tid; newmobj->AddToHash(); - newmobj->vel.x = vel.x; - newmobj->vel.y = vel.y; - newmobj->vel.z = vel.z; + newmobj->Vel = Vel; newmobj->master = master; // For things such as DamageMaster/DamageChildren, transfer mastery. newmobj->target = target; newmobj->tracer = tracer; @@ -189,17 +188,17 @@ class ARandomSpawner : public AActor // Handle special altitude flags if (newmobj->flags & MF_SPAWNCEILING) { - newmobj->SetZ(newmobj->ceilingz - newmobj->height - SpawnPoint[2]); + newmobj->SetZ(newmobj->ceilingz - newmobj->Height - SpawnPoint.Z); } else if (newmobj->flags2 & MF2_SPAWNFLOAT) { - fixed_t space = newmobj->ceilingz - newmobj->height - newmobj->floorz; - if (space > 48*FRACUNIT) + double space = newmobj->ceilingz - newmobj->Height - newmobj->floorz; + if (space > 48) { - space -= 40*FRACUNIT; - newmobj->SetZ(MulScale8 (space, pr_randomspawn()) + newmobj->floorz + 40*FRACUNIT); + space -= 40; + newmobj->SetZ((space * pr_randomspawn()) / 256. + newmobj->floorz + 40); } - newmobj->AddZ(SpawnPoint[2]); + newmobj->AddZ(SpawnPoint.Z); } if (newmobj->flags & MF_MISSILE) P_CheckMissileSpawn(newmobj, 0); diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 1d5fd4ba5..6776fa814 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -8,9 +8,10 @@ class FDecalTemplate; struct vertex_t; struct side_t; struct F3DFloor; +class DBaseDecal; -void P_SpawnDirt (AActor *actor, fixed_t radius); -class DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, fixed_t x, fixed_t y, fixed_t z, angle_t angle, fixed_t tracedist, bool permanent); +void P_SpawnDirt (AActor *actor, double radius); +class DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent); class DBaseDecal : public DThinker { @@ -18,28 +19,28 @@ class DBaseDecal : public DThinker HAS_OBJECT_POINTERS public: DBaseDecal (); - DBaseDecal (fixed_t z); - DBaseDecal (int statnum, fixed_t z); + DBaseDecal(double z); + DBaseDecal(int statnum, double z); DBaseDecal (const AActor *actor); DBaseDecal (const DBaseDecal *basis); void Serialize (FArchive &arc); void Destroy (); - FTextureID StickToWall (side_t *wall, fixed_t x, fixed_t y, F3DFloor * ffloor); - fixed_t GetRealZ (const side_t *wall) const; + FTextureID StickToWall(side_t *wall, double x, double y, F3DFloor * ffloor); + double GetRealZ (const side_t *wall) const; void SetShade (DWORD rgb); void SetShade (int r, int g, int b); - void Spread (const FDecalTemplate *tpl, side_t *wall, fixed_t x, fixed_t y, fixed_t z, F3DFloor * ffloor); - void GetXY (side_t *side, fixed_t &x, fixed_t &y) const; + void Spread (const FDecalTemplate *tpl, side_t *wall, double x, double y, double z, F3DFloor * ffloor); + void GetXY (side_t *side, double &x, double &y) const; static void SerializeChain (FArchive &arc, DBaseDecal **firstptr); DBaseDecal *WallNext, **WallPrev; - fixed_t LeftDistance; - fixed_t Z; - fixed_t ScaleX, ScaleY; - fixed_t Alpha; + double LeftDistance; + double Z; + double ScaleX, ScaleY; + double Alpha; DWORD AlphaColor; int Translation; FTextureID PicNum; @@ -48,23 +49,23 @@ public: sector_t * Sector; // required for 3D floors protected: - virtual DBaseDecal *CloneSelf (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor) const; - void CalcFracPos (side_t *wall, fixed_t x, fixed_t y); + virtual DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const; + void CalcFracPos(side_t *wall, double x, double y); void Remove (); - static void SpreadLeft (fixed_t r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor); - static void SpreadRight (fixed_t r, side_t *feelwall, fixed_t wallsize, F3DFloor *ffloor); + static void SpreadLeft (double r, vertex_t *v1, side_t *feelwall, F3DFloor *ffloor); + static void SpreadRight (double r, side_t *feelwall, double wallsize, F3DFloor *ffloor); }; class DImpactDecal : public DBaseDecal { DECLARE_CLASS (DImpactDecal, DBaseDecal) public: - DImpactDecal (fixed_t z); + DImpactDecal(double z); DImpactDecal (side_t *wall, const FDecalTemplate *templ); - static DImpactDecal *StaticCreate (const char *name, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color=0); - static DImpactDecal *StaticCreate (const FDecalTemplate *tpl, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color=0); + static DImpactDecal *StaticCreate(const char *name, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0); + static DImpactDecal *StaticCreate(const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0); void BeginPlay (); void Destroy (); @@ -73,7 +74,7 @@ public: static void SerializeTime (FArchive &arc); protected: - DBaseDecal *CloneSelf (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor) const; + DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const; static void CheckMax (); private: @@ -153,11 +154,12 @@ enum struct FQuakeJiggers { - int IntensityX, IntensityY, IntensityZ; - int RelIntensityX, RelIntensityY, RelIntensityZ; - int OffsetX, OffsetY, OffsetZ; - int RelOffsetX, RelOffsetY, RelOffsetZ; - int Falloff, WFalloff; + DVector3 Intensity; + DVector3 RelIntensity; + DVector3 Offset; + DVector3 RelOffset; + double Falloff; + double WFalloff; }; class DEarthquake : public DThinker @@ -172,19 +174,19 @@ public: void Serialize (FArchive &arc); void Tick (); TObjPtr m_Spot; - fixed_t m_TremorRadius, m_DamageRadius; + double m_TremorRadius, m_DamageRadius; int m_Countdown; int m_CountdownStart; FSoundID m_QuakeSFX; int m_Flags; - fixed_t m_IntensityX, m_IntensityY, m_IntensityZ; - float m_WaveSpeedX, m_WaveSpeedY, m_WaveSpeedZ; - fixed_t m_Falloff; + DVector3 m_Intensity; + DVector3 m_WaveSpeed; + double m_Falloff; int m_Highpoint, m_MiniCount; - fixed_t GetModIntensity(int intensity) const; - fixed_t GetModWave(double waveMultiplier) const; - fixed_t GetFalloff(fixed_t dist) const; + double GetModIntensity(double intensity) const; + double GetModWave(double waveMultiplier) const; + double GetFalloff(double dist) const; static int StaticGetQuakeIntensities(AActor *viewer, FQuakeJiggers &jiggers); diff --git a/src/g_shared/a_soundsequence.cpp b/src/g_shared/a_soundsequence.cpp index 50dce9871..b7ef2d25b 100644 --- a/src/g_shared/a_soundsequence.cpp +++ b/src/g_shared/a_soundsequence.cpp @@ -146,7 +146,7 @@ void ASoundSequence::PostBeginPlay () } if (master == NULL) { - master = Spawn (0, 0, 0, NO_REPLACE); + master = Spawn (); master->Sequence = SN_StartSequence (master, slot, 0); GC::WriteBarrier(master, master->Sequence); } diff --git a/src/g_shared/a_spark.cpp b/src/g_shared/a_spark.cpp index 7e7aa1f8e..4bc9dc4c4 100644 --- a/src/g_shared/a_spark.cpp +++ b/src/g_shared/a_spark.cpp @@ -50,6 +50,6 @@ IMPLEMENT_CLASS (ASpark) void ASpark::Activate (AActor *activator) { Super::Activate (activator); - P_DrawSplash (args[0] ? args[0] : 32, X(), Y(), Z(), angle, 1); + P_DrawSplash (args[0] ? args[0] : 32, Pos(), Angles.Yaw, 1); S_Sound (this, CHAN_AUTO, "world/spark", 1, ATTN_STATIC); } diff --git a/src/g_shared/a_specialspot.cpp b/src/g_shared/a_specialspot.cpp index 8dfefb311..a0469fb40 100644 --- a/src/g_shared/a_specialspot.cpp +++ b/src/g_shared/a_specialspot.cpp @@ -149,17 +149,17 @@ struct FSpotList // //---------------------------------------------------------------------------- - ASpecialSpot *GetSpotWithMinMaxDistance(fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist) + ASpecialSpot *GetSpotWithMinMaxDistance(double x, double y, double mindist, double maxdist) { if (Spots.Size() == 0) return NULL; int i = pr_spot() % Spots.Size(); int initial = i; - fixed_t distance; + double distance; while (true) { - distance = Spots[i]->AproxDistance(x, y); + distance = Spots[i]->Distance2D(x, y); if ((distance >= mindist) && ((maxdist == 0) || (distance <= maxdist))) break; @@ -337,7 +337,7 @@ ASpecialSpot *DSpotState::GetNextInList(const PClass *type, int skipcounter) // //---------------------------------------------------------------------------- -ASpecialSpot *DSpotState::GetSpotWithMinMaxDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist) +ASpecialSpot *DSpotState::GetSpotWithMinMaxDistance(const PClass *type, double x, double y, double mindist, double maxdist) { FSpotList *list = FindSpotList(type); if (list != NULL) return list->GetSpotWithMinMaxDistance(x, y, mindist, maxdist); diff --git a/src/g_shared/a_specialspot.h b/src/g_shared/a_specialspot.h index 937814280..db148b19d 100644 --- a/src/g_shared/a_specialspot.h +++ b/src/g_shared/a_specialspot.h @@ -36,7 +36,7 @@ public: bool RemoveSpot(ASpecialSpot *spot); void Serialize(FArchive &arc); ASpecialSpot *GetNextInList(const PClass *type, int skipcounter); - ASpecialSpot *GetSpotWithMinMaxDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist); + ASpecialSpot *GetSpotWithMinMaxDistance(const PClass *type, double x, double y, double mindist, double maxdist); ASpecialSpot *GetRandomSpot(const PClass *type, bool onlyonce = false); }; diff --git a/src/g_shared/a_weaponpiece.cpp b/src/g_shared/a_weaponpiece.cpp index 9612b1716..2d7549db7 100644 --- a/src/g_shared/a_weaponpiece.cpp +++ b/src/g_shared/a_weaponpiece.cpp @@ -89,7 +89,7 @@ bool AWeaponPiece::TryPickup (AActor *&toucher) } if (!hold) { - hold=static_cast(Spawn(RUNTIME_CLASS(AWeaponHolder), 0, 0, 0, NO_REPLACE)); + hold=static_cast(Spawn(RUNTIME_CLASS(AWeaponHolder))); hold->BecomeItem(); hold->AttachToOwner(toucher); hold->PieceMask=0; @@ -129,7 +129,7 @@ bool AWeaponPiece::TryPickup (AActor *&toucher) { if (!toucher->FindInventory (WeaponClass)) { - FullWeapon= static_cast(Spawn(WeaponClass, 0, 0, 0, NO_REPLACE)); + FullWeapon= static_cast(Spawn(WeaponClass)); // The weapon itself should not give more ammo to the player! FullWeapon->AmmoGive1=0; diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 93036b031..971d974de 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -41,7 +41,7 @@ IMPLEMENT_CLASS(PClassWeapon) PClassWeapon::PClassWeapon() { SlotNumber = -1; - SlotPriority = FIXED_MAX; + SlotPriority = INT_MAX; } void PClassWeapon::DeriveData(PClass *newclass) @@ -90,16 +90,11 @@ void AWeapon::Serialize (FArchive &arc) << MoveCombatDist << Ammo1 << Ammo2 << SisterWeapon << GivenAsMorphWeapon << bAltFire - << ReloadCounter; - if (SaveVersion >= 3615) { - arc << BobStyle << BobSpeed << BobRangeX << BobRangeY; - } - arc << FOVScale - << Crosshair; - if (SaveVersion >= 4203) - { - arc << MinSelAmmo1 << MinSelAmmo2; - } + << ReloadCounter + << BobStyle << BobSpeed << BobRangeX << BobRangeY + << FOVScale + << Crosshair + << MinSelAmmo1 << MinSelAmmo2; } //=========================================================================== @@ -382,12 +377,12 @@ AAmmo *AWeapon::AddAmmo (AActor *other, PClassActor *ammotype, int amount) // extra ammo in baby mode and nightmare mode if (!(this->ItemFlags&IF_IGNORESKILL)) { - amount = FixedMul(amount, G_SkillProperty(SKILLP_AmmoFactor)); + amount = int(amount * G_SkillProperty(SKILLP_AmmoFactor)); } ammo = static_cast(other->FindInventory (ammotype)); if (ammo == NULL) { - ammo = static_cast(Spawn (ammotype, 0, 0, 0, NO_REPLACE)); + ammo = static_cast(Spawn (ammotype)); ammo->Amount = MIN (amount, ammo->MaxAmount); ammo->AttachToOwner (other); } @@ -418,7 +413,7 @@ bool AWeapon::AddExistingAmmo (AAmmo *ammo, int amount) // extra ammo in baby mode and nightmare mode if (!(ItemFlags&IF_IGNORESKILL)) { - amount = FixedMul(amount, G_SkillProperty(SKILLP_AmmoFactor)); + amount = int(amount * G_SkillProperty(SKILLP_AmmoFactor)); } ammo->Amount += amount; if (ammo->Amount > ammo->MaxAmount && !sv_unlimited_pickup) @@ -449,7 +444,7 @@ AWeapon *AWeapon::AddWeapon (PClassWeapon *weapontype) weap = static_cast(Owner->FindInventory (weapontype)); if (weap == NULL) { - weap = static_cast(Spawn (weapontype, 0, 0, 0, NO_REPLACE)); + weap = static_cast(Spawn (weapontype)); weap->AttachToOwner (Owner); } return weap; @@ -731,10 +726,7 @@ IMPLEMENT_CLASS(AWeaponGiver) void AWeaponGiver::Serialize(FArchive &arc) { Super::Serialize(arc); - if (SaveVersion >= 4246) - { - arc << DropAmmoFactor; - } + arc << DropAmmoFactor; } bool AWeaponGiver::TryPickup(AActor *&toucher) @@ -749,7 +741,7 @@ bool AWeaponGiver::TryPickup(AActor *&toucher) { if (master == NULL) { - master = weap = static_cast(Spawn(di->Name, 0, 0, 0, NO_REPLACE)); + master = weap = static_cast(Spawn(di->Name)); if (weap != NULL) { weap->ItemFlags &= ~IF_ALWAYSPICKUP; // use the flag of this item only. @@ -762,8 +754,8 @@ bool AWeaponGiver::TryPickup(AActor *&toucher) // If DropAmmoFactor is non-negative, modify the given ammo amounts. if (DropAmmoFactor > 0) { - weap->AmmoGive1 = FixedMul(weap->AmmoGive1, DropAmmoFactor); - weap->AmmoGive2 = FixedMul(weap->AmmoGive2, DropAmmoFactor); + weap->AmmoGive1 = int(weap->AmmoGive1 * DropAmmoFactor); + weap->AmmoGive2 = int(weap->AmmoGive2 * DropAmmoFactor); } weap->BecomeItem(); } @@ -984,7 +976,7 @@ void FWeaponSlot::Sort() for (i = 1; i < (int)Weapons.Size(); ++i) { - fixed_t pos = Weapons[i].Position; + int pos = Weapons[i].Position; PClassWeapon *type = Weapons[i].Type; for (j = i - 1; j >= 0 && Weapons[j].Position > pos; --j) { diff --git a/src/g_shared/hudmessages.cpp b/src/g_shared/hudmessages.cpp index 3fea0f4c7..0ee61f942 100644 --- a/src/g_shared/hudmessages.cpp +++ b/src/g_shared/hudmessages.cpp @@ -146,7 +146,7 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h Font = font; VisibilityFlags = 0; Style = STYLE_Translucent; - Alpha = FRACUNIT; + Alpha = 1.; ResetText (SourceText); } @@ -179,53 +179,23 @@ DHUDMessage::~DHUDMessage () // //============================================================================ -void DHUDMessage::Serialize (FArchive &arc) +void DHUDMessage::Serialize(FArchive &arc) { - Super::Serialize (arc); + Super::Serialize(arc); arc << Left << Top << CenterX << HoldTics << Tics << State << TextColor << SBarID << SourceText << Font << Next - << HUDWidth << HUDHeight; - if (SaveVersion >= 3960) - { - arc << NoWrap; - arc << ClipX << ClipY << ClipWidth << ClipHeight; - arc << WrapWidth; - } - else - { - NoWrap = false; - ClipX = ClipY = ClipWidth = ClipHeight = WrapWidth = 0; - } - if (SaveVersion >= 4525) - { - arc << HandleAspect; - } - else - { - HandleAspect = true; - } - if (arc.IsLoading ()) + << HUDWidth << HUDHeight + << NoWrap + << ClipX << ClipY << ClipWidth << ClipHeight + << WrapWidth + << HandleAspect + << VisibilityFlags + << Style << Alpha; + if (arc.IsLoading()) { Lines = NULL; - ResetText (SourceText); - } - if (SaveVersion < 3821) - { - VisibilityFlags = 0; - } - else - { - arc << VisibilityFlags; - } - if (SaveVersion < 3824) - { - Style = STYLE_Translucent; - Alpha = FRACUNIT; - } - else - { - arc << Style << Alpha; + ResetText(SourceText); } } @@ -474,7 +444,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) { screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, - DTA_Alpha, Alpha, + DTA_AlphaF, Alpha, DTA_RenderStyle, Style, TAG_DONE); } @@ -483,7 +453,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, SCREENWIDTH/2, DTA_VirtualHeight, SCREENHEIGHT/2, - DTA_Alpha, Alpha, + DTA_AlphaF, Alpha, DTA_RenderStyle, Style, DTA_KeepRatio, true, TAG_DONE); @@ -498,7 +468,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) DTA_ClipRight, ClipRight, DTA_ClipTop, ClipTop, DTA_ClipBottom, ClipBot, - DTA_Alpha, Alpha, + DTA_AlphaF, Alpha, DTA_RenderStyle, Style, TAG_DONE); } @@ -570,15 +540,14 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh } else { - fixed_t trans = -(Tics - FadeOutTics) * FRACUNIT / FadeOutTics; - trans = FixedMul(trans, Alpha); + float trans = float(Alpha * -(Tics - FadeOutTics) / FadeOutTics); if (hudheight == 0) { if (con_scaletext <= 1) { screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, - DTA_Alpha, trans, + DTA_AlphaF, trans, DTA_RenderStyle, Style, TAG_DONE); } @@ -587,7 +556,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, SCREENWIDTH/2, DTA_VirtualHeight, SCREENHEIGHT/2, - DTA_Alpha, trans, + DTA_AlphaF, trans, DTA_RenderStyle, Style, DTA_KeepRatio, true, TAG_DONE); @@ -602,7 +571,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh DTA_ClipRight, ClipRight, DTA_ClipTop, ClipTop, DTA_ClipBottom, ClipBot, - DTA_Alpha, trans, + DTA_AlphaF, trans, DTA_RenderStyle, Style, TAG_DONE); } @@ -671,15 +640,14 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu { if (State == 0) { - fixed_t trans = Tics * FRACUNIT / FadeInTics; - trans = FixedMul(trans, Alpha); + float trans = float(Alpha * Tics / FadeInTics); if (hudheight == 0) { if (con_scaletext <= 1) { screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, - DTA_Alpha, trans, + DTA_AlphaF, trans, DTA_RenderStyle, Style, TAG_DONE); } @@ -688,7 +656,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, SCREENWIDTH/2, DTA_VirtualHeight, SCREENHEIGHT/2, - DTA_Alpha, trans, + DTA_AlphaF, trans, DTA_RenderStyle, Style, DTA_KeepRatio, true, TAG_DONE); @@ -703,7 +671,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu DTA_ClipRight, ClipRight, DTA_ClipTop, ClipTop, DTA_ClipBottom, ClipBot, - DTA_Alpha, trans, + DTA_AlphaF, trans, DTA_RenderStyle, Style, TAG_DONE); } @@ -858,7 +826,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, DTA_TextLen, LineVisible, - DTA_Alpha, Alpha, + DTA_AlphaF, Alpha, DTA_RenderStyle, Style, TAG_DONE); } @@ -869,7 +837,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in DTA_VirtualHeight, SCREENHEIGHT/2, DTA_KeepRatio, true, DTA_TextLen, LineVisible, - DTA_Alpha, Alpha, + DTA_AlphaF, Alpha, DTA_RenderStyle, Style, TAG_DONE); } @@ -883,7 +851,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in DTA_ClipRight, ClipRight, DTA_ClipTop, ClipTop, DTA_ClipBottom, ClipBot, - DTA_Alpha, Alpha, + DTA_AlphaF, Alpha, DTA_TextLen, LineVisible, DTA_RenderStyle, Style, TAG_DONE); diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 3f91c2ee3..560a7500a 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -88,7 +88,7 @@ public: { Style = style; } - void SetAlpha(fixed_t alpha) + void SetAlpha(float alpha) { Alpha = alpha; } @@ -127,7 +127,7 @@ protected: EColorRange TextColor; FFont *Font; FRenderStyle Style; - fixed_t Alpha; + double Alpha; void CalcClipCoords(int hudheight); DHUDMessage () : SourceText(NULL) {} @@ -349,7 +349,7 @@ public: DHUDMessage *DetachMessage (uint32 id); void DetachAllMessages (); void ShowPlayerName (); - fixed_t GetDisplacement () { return Displacement; } + double GetDisplacement() { return Displacement; } int GetPlayer (); static void AddBlend (float r, float g, float b, float a, float v_blend[4]); @@ -380,7 +380,6 @@ protected: void UpdateRect (int x, int y, int width, int height) const; void DrawImage (FTexture *image, int x, int y, FRemapTable *translation=NULL) const; void DrawDimImage (FTexture *image, int x, int y, bool dimmed) const; - void DrawFadedImage (FTexture *image, int x, int y, fixed_t shade) const; void DrawPartialImage (FTexture *image, int wx, int ww) const; void DrINumber (signed int val, int x, int y, int imgBase=imgINumbers) const; @@ -407,8 +406,8 @@ public: bool Centering; bool FixedOrigin; bool CompleteBorder; - fixed_t CrosshairSize; - fixed_t Displacement; + double CrosshairSize; + double Displacement; enum { diff --git a/src/g_shared/sbar_mugshot.cpp b/src/g_shared/sbar_mugshot.cpp index 2eaabc7f7..b26541c99 100644 --- a/src/g_shared/sbar_mugshot.cpp +++ b/src/g_shared/sbar_mugshot.cpp @@ -338,9 +338,6 @@ bool FMugShot::SetState(const char *state_name, bool wait_till_done, bool reset) CVAR(Bool,st_oldouch,false,CVAR_ARCHIVE) int FMugShot::UpdateState(player_t *player, StateFlags stateflags) { - int i; - angle_t badguyangle; - angle_t diffang; FString full_state_name; if (player->health > 0) @@ -366,25 +363,14 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) if (player->mo != NULL) { // The next 12 lines are from the Doom statusbar code. - badguyangle = player->mo->AngleTo(player->attacker); - if (badguyangle > player->mo->angle) - { - // whether right or left - diffang = badguyangle - player->mo->angle; - i = diffang > ANG180; - } - else - { - // whether left or right - diffang = player->mo->angle - badguyangle; - i = diffang <= ANG180; - } // confusing, aint it? - if (i && diffang >= ANG45) - { + DAngle badguyangle = player->mo->AngleTo(player->attacker); + DAngle diffang = deltaangle(player->mo->Angles.Yaw, badguyangle); + if (diffang > 45.) + { // turn face right damage_angle = 0; } - else if (!i && diffang >= ANG45) - { + else if (diffang < -45.) + { // turn face left damage_angle = 2; } } diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index 2fcc29b05..0136b4f25 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -76,6 +76,7 @@ EXTERN_CVAR(Bool, vid_fps) EXTERN_CVAR(Bool, hud_scale) class DSBarInfo; +static double nulclip[] = { 0,0,0,0 }; //////////////////////////////////////////////////////////////////////////////// @@ -312,22 +313,22 @@ class SBarInfoMainBlock : public SBarInfoCommandFlowControl { public: SBarInfoMainBlock(SBarInfo *script) : SBarInfoCommandFlowControl(script), - alpha(FRACUNIT), currentAlpha(FRACUNIT), forceScaled(false), + alpha(1.), currentAlpha(1.), forceScaled(false), fullScreenOffsets(false) { SetTruth(true, NULL, NULL); } - int Alpha() const { return currentAlpha; } + double Alpha() const { return currentAlpha; } // Same as Draw but takes into account ForceScaled and temporarily sets the scaling if needed. - void DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statusBar, int xOffset, int yOffset, int alpha); + void DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statusBar, int xOffset, int yOffset, double alpha); // Silence hidden overload warning since this is a special use class. using SBarInfoCommandFlowControl::Draw; - void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, int xOffset, int yOffset, int alpha) + void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, int xOffset, int yOffset, double alpha) { this->xOffset = xOffset; this->yOffset = yOffset; - this->currentAlpha = fixed_t((((double) this->alpha / (double) FRACUNIT) * ((double) alpha / (double) FRACUNIT)) * FRACUNIT); + this->currentAlpha = this->alpha * alpha; SBarInfoCommandFlowControl::Draw(this, statusBar); } bool ForceScaled() const { return forceScaled; } @@ -352,7 +353,7 @@ class SBarInfoMainBlock : public SBarInfoCommandFlowControl } } sc.MustGetToken(TK_FloatConst); - alpha = fixed_t(FRACUNIT * sc.Float); + alpha = sc.Float; } SBarInfoCommandFlowControl::Parse(sc, this->fullScreenOffsets); } @@ -361,8 +362,8 @@ class SBarInfoMainBlock : public SBarInfoCommandFlowControl int YOffset() const { return yOffset; } protected: - int alpha; - int currentAlpha; + double alpha; + double currentAlpha; bool forceScaled; bool fullScreenOffsets; int xOffset; @@ -716,24 +717,24 @@ void SBarInfo::ParseSBarInfo(int lump) popup.transition = Popup::TRANSITION_SLIDEINBOTTOM; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); - popup.speed = sc.Number; + popup.ispeed = sc.Number; } else if(sc.Compare("pushup")) { popup.transition = Popup::TRANSITION_PUSHUP; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); - popup.speed = sc.Number; + popup.ispeed = sc.Number; } else if(sc.Compare("fade")) { popup.transition = Popup::TRANSITION_FADE; sc.MustGetToken(','); sc.MustGetToken(TK_FloatConst); - popup.speed = fixed_t(FRACUNIT * (1.0 / (35.0 * sc.Float))); + popup.speed = 1.0 / (35.0 * sc.Float); sc.MustGetToken(','); sc.MustGetToken(TK_FloatConst); - popup.speed2 = fixed_t(FRACUNIT * (1.0 / (35.0 * sc.Float))); + popup.speed2 = 1.0 / (35.0 * sc.Float); } else sc.ScriptError("Unkown transition type: '%s'", sc.String); @@ -838,7 +839,7 @@ SBarInfo::~SBarInfo() //Popup Popup::Popup() : transition(TRANSITION_NONE), opened(false), moving(false), - height(320), width(200), speed(0), speed2(0), alpha(FRACUNIT), x(320), + height(320), width(200), ispeed(0), speed(0), speed2(0), alpha(1.), x(320), y(200), displacementX(0), displacementY(0) { } @@ -873,9 +874,9 @@ void Popup::tick() { int oldY = y; if(opened) - y -= clamp(height + (y - height), 1, speed); + y -= clamp(height + (y - height), 1, ispeed); else - y += clamp(height - y, 1, speed); + y += clamp(height - y, 1, ispeed); if(transition == TRANSITION_PUSHUP) displacementY += y - oldY; } @@ -888,11 +889,11 @@ void Popup::tick() if(moving) { if(opened) - alpha = clamp(alpha + speed, 0, FRACUNIT); + alpha = clamp(alpha + speed, 0., 1.); else - alpha = clamp(alpha - speed2, 0, FRACUNIT); + alpha = clamp(alpha - speed2, 0., 1.); } - if(alpha == 0 || alpha == FRACUNIT) + if(alpha == 0 || alpha == 1.) moving = false; else moving = true; @@ -928,11 +929,9 @@ int Popup::getYOffset() return y; } -int Popup::getAlpha(int maxAlpha) +double Popup::getAlpha(double maxAlpha) { - double a = (double) alpha / (double) FRACUNIT; - double b = (double) maxAlpha / (double) FRACUNIT; - return fixed_t((a * b) * FRACUNIT); + return alpha * maxAlpha; } int Popup::getXDisplacement() @@ -1077,9 +1076,9 @@ public: } if(currentPopup != POP_None && !script->huds[hud]->FullScreenOffsets()) - script->huds[hud]->Draw(NULL, this, script->popups[currentPopup-1].getXDisplacement(), script->popups[currentPopup-1].getYDisplacement(), FRACUNIT); + script->huds[hud]->Draw(NULL, this, script->popups[currentPopup-1].getXDisplacement(), script->popups[currentPopup-1].getYDisplacement(), 1.); else - script->huds[hud]->Draw(NULL, this, 0, 0, FRACUNIT); + script->huds[hud]->Draw(NULL, this, 0, 0, 1.); lastHud = hud; // Handle inventory bar drawing @@ -1093,7 +1092,7 @@ public: if(inventoryBar->NumCommands() == 0) CPlayer->inventorytics = 0; else - inventoryBar->DrawAux(NULL, this, 0, 0, FRACUNIT); + inventoryBar->DrawAux(NULL, this, 0, 0, 1.); } } @@ -1197,7 +1196,7 @@ public: } //draws an image with the specified flags - void DrawGraphic(FTexture* texture, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool translate=false, bool dim=false, int offsetflags=0, bool alphaMap=false, int forceWidth=-1, int forceHeight=-1, fixed_t cx=0, fixed_t cy=0, fixed_t cr=0, fixed_t cb=0, bool clearDontDraw=false) const + void DrawGraphic(FTexture* texture, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, double Alpha, bool fullScreenOffsets, bool translate=false, bool dim=false, int offsetflags=0, bool alphaMap=false, int forceWidth=-1, int forceHeight=-1, const double *clip = nulclip, bool clearDontDraw=false) const { if (texture == NULL) return; @@ -1225,20 +1224,20 @@ public: dy += ST_Y - (Scaled ? script->resH : 200) + script->height; w = forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth; h = forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight; - double dcx = cx == 0 ? 0 : dx + ((double) cx / FRACUNIT) - texture->GetScaledLeftOffsetDouble(); - double dcy = cy == 0 ? 0 : dy + ((double) cy / FRACUNIT) - texture->GetScaledTopOffsetDouble(); - double dcr = cr == 0 ? INT_MAX : dx + w - ((double) cr / FRACUNIT) - texture->GetScaledLeftOffsetDouble(); - double dcb = cb == 0 ? INT_MAX : dy + h - ((double) cb / FRACUNIT) - texture->GetScaledTopOffsetDouble(); + double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble(); + double dcy = clip[1] == 0 ? 0 : dy + clip[1] - texture->GetScaledTopOffsetDouble(); + double dcr = clip[2] == 0 ? INT_MAX : dx + w - clip[2] - texture->GetScaledLeftOffsetDouble(); + double dcb = clip[3] == 0 ? INT_MAX : dy + h - clip[3] - texture->GetScaledTopOffsetDouble(); if(Scaled) { - if(cx != 0 || cy != 0) + if(clip[0] != 0 || clip[1] != 0) { screen->VirtualToRealCoords(dcx, dcy, tmp, tmp, script->resW, script->resH, true); - if (cx == 0) dcx = 0; - if (cy == 0) dcy = 0; + if (clip[0] == 0) dcx = 0; + if (clip[1] == 0) dcy = 0; } - if(cr != 0 || cb != 0 || clearDontDraw) + if(clip[2] != 0 || clip[3] != 0 || clearDontDraw) screen->VirtualToRealCoords(dcr, dcb, tmp, tmp, script->resW, script->resH, true); screen->VirtualToRealCoords(dx, dy, w, h, script->resW, script->resH, true); } @@ -1265,7 +1264,7 @@ public: DTA_Translation, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, - DTA_Alpha, alpha, + DTA_AlphaF, Alpha, DTA_AlphaChannel, alphaMap, DTA_FillColor, 0, TAG_DONE); @@ -1282,7 +1281,7 @@ public: DTA_Translation, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, - DTA_Alpha, alpha, + DTA_AlphaF, Alpha, TAG_DONE); } } @@ -1318,12 +1317,12 @@ public: ry = SCREENHEIGHT + ry; // Check for clipping - if(cx != 0 || cy != 0 || cr != 0 || cb != 0) + if(clip[0] != 0 || clip[1] != 0 || clip[2] != 0 || clip[3] != 0) { - rcx = cx == 0 ? 0 : rx+((((double) cx/FRACUNIT) - texture->GetScaledLeftOffsetDouble())*xScale); - rcy = cy == 0 ? 0 : ry+((((double) cy/FRACUNIT) - texture->GetScaledTopOffsetDouble())*yScale); - rcr = cr == 0 ? INT_MAX : rx+w-((((double) cr/FRACUNIT) + texture->GetScaledLeftOffsetDouble())*xScale); - rcb = cb == 0 ? INT_MAX : ry+h-((((double) cb/FRACUNIT) + texture->GetScaledTopOffsetDouble())*yScale); + rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*xScale); + rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*yScale); + rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*xScale); + rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*yScale); } if(clearDontDraw) @@ -1342,7 +1341,7 @@ public: DTA_Translation, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, - DTA_Alpha, alpha, + DTA_AlphaF, Alpha, DTA_AlphaChannel, alphaMap, DTA_FillColor, 0, TAG_DONE); @@ -1359,14 +1358,14 @@ public: DTA_Translation, translate ? GetTranslation() : 0, DTA_ColorOverlay, dim ? DIM_OVERLAY : 0, DTA_CenterBottomOffset, (offsetflags & SBarInfoCommand::CENTER_BOTTOM) == SBarInfoCommand::CENTER_BOTTOM, - DTA_Alpha, alpha, + DTA_AlphaF, Alpha, TAG_DONE); } } } } - void DrawString(FFont *font, const char* cstring, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool drawshadow=false, int shadowX=2, int shadowY=2) const + void DrawString(FFont *font, const char* cstring, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, double Alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool drawshadow=false, int shadowX=2, int shadowY=2) const { x += spacing; double ax = *x; @@ -1476,13 +1475,13 @@ public: } if(drawshadow) { - int salpha = fixed_t(((double) alpha / (double) FRACUNIT) * ((double) HR_SHADOW / (double) FRACUNIT) * FRACUNIT); + double salpha = (Alpha *HR_SHADOW); double srx = rx + (shadowX*xScale); double sry = ry + (shadowY*yScale); screen->DrawTexture(character, srx, sry, DTA_DestWidthF, rw, DTA_DestHeightF, rh, - DTA_Alpha, salpha, + DTA_AlphaF, salpha, DTA_FillColor, 0, TAG_DONE); } @@ -1490,7 +1489,7 @@ public: DTA_DestWidthF, rw, DTA_DestHeightF, rh, DTA_Translation, remap, - DTA_Alpha, alpha, + DTA_AlphaF, Alpha, TAG_DONE); if(script->spacingCharacter == '\0') ax += width + spacing - (character->LeftOffset+1); @@ -1536,7 +1535,7 @@ DBaseStatusBar *CreateCustomStatusBar (int script) return new DSBarInfo(SBarInfoScript[script]); } -void SBarInfoMainBlock::DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statusBar, int xOffset, int yOffset, int alpha) +void SBarInfoMainBlock::DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statusBar, int xOffset, int yOffset, double alpha) { // Popups can also be forced to scale bool rescale = false; diff --git a/src/g_shared/sbarinfo.h b/src/g_shared/sbarinfo.h index 4e6591e65..f5dcb4abd 100644 --- a/src/g_shared/sbarinfo.h +++ b/src/g_shared/sbarinfo.h @@ -61,9 +61,10 @@ struct Popup bool moving; int height; int width; - int speed; - int speed2; - int alpha; + int ispeed; + double speed; + double speed2; + double alpha; int x; int y; int displacementX; @@ -77,7 +78,7 @@ struct Popup bool isDoneMoving(); int getXOffset(); int getYOffset(); - int getAlpha(int maxAlpha=FRACUNIT); + double getAlpha(double maxAlpha=1.); int getXDisplacement(); int getYDisplacement(); }; diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index a471ff8b2..26b4c9510 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -48,7 +48,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl translatable(false), type(NORMAL_IMAGE), image(-1), maxwidth(-1), maxheight(-1), spawnScaleX(1.0f), spawnScaleY(1.0f), flags(0), applyscale(false), offset(static_cast (TOP|LEFT)), - texture(NULL), alpha(FRACUNIT) + texture(NULL), alpha(1.) { } @@ -63,9 +63,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl int w = maxwidth, h = maxheight; // We must calculate this per frame in order to prevent glitches with cl_capfps true. - fixed_t frameAlpha = block->Alpha(); - if(alpha != FRACUNIT) - frameAlpha = fixed_t(((double) block->Alpha() / (double) FRACUNIT) * ((double) alpha / (double) OPAQUE) * FRACUNIT); + double frameAlpha = block->Alpha() * alpha; if(flags & DI_DRAWINBOX) { @@ -236,7 +234,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); texture = NULL; - alpha = FRACUNIT; + alpha = 1.; if (applyscale) { spawnScaleX = spawnScaleY = 1.0f; @@ -284,7 +282,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl if (harmor->Slots[armorType] > 0 && harmor->SlotsIncrement[armorType] > 0) { //combine the alpha values - alpha = fixed_t(((double) alpha / (double) FRACUNIT) * ((double) MIN (OPAQUE, Scale(harmor->Slots[armorType], OPAQUE, harmor->SlotsIncrement[armorType])) / (double) OPAQUE) * FRACUNIT); + alpha *= MIN(1., harmor->Slots[armorType] / harmor->SlotsIncrement[armorType]); texture = statusBar->Images[image]; } else @@ -310,8 +308,8 @@ class CommandDrawImage : public SBarInfoCommandFlowControl if (applyscale) { - spawnScaleX = FIXED2DBL(item->scaleX); - spawnScaleY = FIXED2DBL(item->scaleY); + spawnScaleX = item->Scale.X; + spawnScaleY = item->Scale.Y; } texture = TexMan[icon]; @@ -352,7 +350,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl Offset offset; FTexture *texture; - int alpha; + double alpha; }; //////////////////////////////////////////////////////////////////////////////// @@ -643,7 +641,7 @@ class CommandDrawSwitchableImage : public CommandDrawImage // Since we're not going to call our parent's tick() method, // be sure to set the alpha value properly. - alpha = FRACUNIT; + alpha = 1.; return; } CommandDrawImage::Tick(block, statusBar, hudChanged); @@ -1379,21 +1377,21 @@ class CommandDrawNumber : public CommandDrawString case ARMORCLASS: case SAVEPERCENT: { + double add = 0; AHexenArmor *harmor = statusBar->CPlayer->mo->FindInventory(); if(harmor != NULL) { - num = harmor->Slots[0] + harmor->Slots[1] + + add = harmor->Slots[0] + harmor->Slots[1] + harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4]; } //Hexen counts basic armor also so we should too. if(statusBar->armor != NULL) { - num += FixedMul(statusBar->armor->SavePercent, 100*FRACUNIT); + add += statusBar->armor->SavePercent * 100; } if(value == ARMORCLASS) - num /= (5*FRACUNIT); - else - num >>= FRACBITS; + add /= 5; + num = int(add); break; } case GLOBALVAR: @@ -1643,9 +1641,9 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra } else { - if(itemflash && itemflashFade) + if(itemflash && itemflashFade != 0) { - fixed_t flashAlpha = fixed_t(((double) block->Alpha() / (double) FRACUNIT) * ((double) itemflashFade / (double) OPAQUE) * FRACUNIT); + double flashAlpha = block->Alpha() * itemflashFade; statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgCURSOR], imgx-4, imgy+2, block->XOffset(), block->YOffset(), flashAlpha, block->FullScreenOffsets(), translatable, false, offset); } @@ -1738,7 +1736,7 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra artiflashTick--; if(itemflashFade > 0) { - itemflashFade -= FRACUNIT/14; + itemflashFade -= 1./14; if(itemflashFade < 0) itemflashFade = 0; } @@ -1749,7 +1747,7 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra CommandDrawNumber::Tick(block, statusBar, hudChanged); } - static void Flash() { artiflashTick = 4; itemflashFade = FRACUNIT*3/4; } + static void Flash() { artiflashTick = 4; itemflashFade = 0.75; } protected: bool alternateOnEmpty; bool artiflash; @@ -1757,10 +1755,10 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra bool itemflash; static int artiflashTick; - static fixed_t itemflashFade; + static double itemflashFade; }; int CommandDrawSelectedInventory::artiflashTick = 0; -int CommandDrawSelectedInventory::itemflashFade = FRACUNIT*3/4; +double CommandDrawSelectedInventory::itemflashFade = 0.75; void DSBarInfo::FlashItem(const PClass *itemtype) { @@ -2096,9 +2094,9 @@ class CommandDrawInventoryBar : public SBarInfoCommand { int spacing = GetCounterSpacing(statusBar); - int bgalpha = block->Alpha(); + double bgalpha = block->Alpha(); if(translucent) - bgalpha = fixed_t((((double) block->Alpha() / (double) FRACUNIT) * ((double) HX_SHADOW / (double) FRACUNIT)) * FRACUNIT); + bgalpha *= HX_SHADOW; AInventory *item; unsigned int i = 0; @@ -2478,10 +2476,10 @@ class CommandDrawBar : public SBarInfoCommand FTexture *fg = statusBar->Images[foreground]; FTexture *bg = (background != -1) ? statusBar->Images[background] : NULL; - fixed_t value = drawValue; + double value = drawValue; if(border != 0) { - value = FRACUNIT - value; //invert since the new drawing method requires drawing the bg on the fg. + value = 1. - value; //invert since the new drawing method requires drawing the bg on the fg. //Draw the whole foreground statusBar->DrawGraphic(fg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); @@ -2492,27 +2490,27 @@ class CommandDrawBar : public SBarInfoCommand if (bg != NULL && bg->GetScaledWidth() == fg->GetScaledWidth() && bg->GetScaledHeight() == fg->GetScaledHeight()) statusBar->DrawGraphic(bg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); else - statusBar->DrawGraphic(fg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, 0, 0, 0, 0, true); + statusBar->DrawGraphic(fg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, nulclip, true); } // {cx, cy, cr, cb} - fixed_t clip[4] = {0, 0, 0, 0}; + double Clip[4] = {0, 0, 0, 0}; - fixed_t sizeOfImage = (horizontal ? fg->GetScaledWidth()-border*2 : fg->GetScaledHeight()-border*2)<GetScaledWidth()-border*2 : fg->GetScaledHeight()-border*2); + Clip[(!horizontal)|((horizontal ? !reverse : reverse)<<1)] = sizeOfImage - sizeOfImage *value; // Draw background if(border != 0) { for(unsigned int i = 0;i < 4;i++) - clip[i] += border<GetScaledWidth() == fg->GetScaledWidth() && bg->GetScaledHeight() == fg->GetScaledHeight()) - statusBar->DrawGraphic(bg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, clip[0], clip[1], clip[2], clip[3]); + statusBar->DrawGraphic(bg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, Clip); else - statusBar->DrawGraphic(fg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, clip[0], clip[1], clip[2], clip[3], true); + statusBar->DrawGraphic(fg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, Clip, true); } else - statusBar->DrawGraphic(fg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, clip[0], clip[1], clip[2], clip[3]); + statusBar->DrawGraphic(fg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, Clip); } void Parse(FScanner &sc, bool fullScreenOffsets) { @@ -2637,7 +2635,7 @@ class CommandDrawBar : public SBarInfoCommand } void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) { - fixed_t value = 0; + double value = 0; int max = 0; switch(type) { @@ -2756,18 +2754,19 @@ class CommandDrawBar : public SBarInfoCommand } case SAVEPERCENT: { + double add = 0; AHexenArmor *harmor = statusBar->CPlayer->mo->FindInventory(); if(harmor != NULL) { - value = harmor->Slots[0] + harmor->Slots[1] + + add = harmor->Slots[0] + harmor->Slots[1] + harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4]; } //Hexen counts basic armor also so we should too. if(statusBar->armor != NULL) { - value += FixedMul(statusBar->armor->SavePercent, 100*FRACUNIT); + add += statusBar->armor->SavePercent * 100; } - value >>= FRACBITS; + value = int(add); max = 100; break; } @@ -2776,9 +2775,7 @@ class CommandDrawBar : public SBarInfoCommand if(max != 0 && value > 0) { - value = (value << FRACBITS) / max; - if(value > FRACUNIT) - value = FRACUNIT; + value = MIN(value / max, 1.); } else value = 0; @@ -2787,14 +2784,14 @@ class CommandDrawBar : public SBarInfoCommand // [BL] Since we used a percentage (in order to get the most fluid animation) // we need to establish a cut off point so the last pixel won't hang as the animation slows if(pixel == -1 && statusBar->Images[foreground]) - pixel = MAX(1, FRACUNIT/statusBar->Images[foreground]->GetWidth()); + pixel = MAX(1., 1./statusBar->Images[foreground]->GetWidth()); - if(abs(drawValue - value) < pixel) + if(fabs(drawValue - value) < pixel) drawValue = value; - else if(value < drawValue) - drawValue -= clamp((drawValue - value) >> 2, 1, FixedDiv(interpolationSpeed<((value - drawValue) >> 2, 1, FixedDiv(interpolationSpeed<((drawValue - value) / 4, 1 / 65536., interpolationSpeed / 100.); + else if (drawValue < value) + drawValue += clamp((value - drawValue) / 4, 1 / 65536., interpolationSpeed / 100.); } else drawValue = value; @@ -2868,8 +2865,8 @@ class CommandDrawBar : public SBarInfoCommand SBarInfoCoordinate y; int interpolationSpeed; - fixed_t drawValue; - fixed_t pixel; + double drawValue; + double pixel; }; //////////////////////////////////////////////////////////////////////////////// @@ -3385,7 +3382,7 @@ class CommandAlpha : public SBarInfoMainBlock void Parse(FScanner &sc, bool fullScreenOffsets) { sc.MustGetToken(TK_FloatConst); - alpha = fixed_t(FRACUNIT * sc.Float); + alpha = sc.Float; // We don't want to allow all the options of a regular main block // so skip to the SBarInfoCommandFlowControl. diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 821008456..7169cb7db 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -116,7 +116,7 @@ static FTexture * invgems[4]; // Inventory arrows static int hudwidth, hudheight; // current width/height for HUD display static int statspace; -void AM_GetPosition(fixed_t & x, fixed_t & y); +DVector2 AM_GetPosition(); FTextureID GetHUDIcon(PClassInventory *cls) @@ -313,9 +313,8 @@ static void DrawArmor(ABasicArmor * barmor, AHexenArmor * harmor, int x, int y) if (harmor) { - int ac = (harmor->Slots[0] + harmor->Slots[1] + harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4]); - ac >>= FRACBITS; - ap += ac; + auto ac = (harmor->Slots[0] + harmor->Slots[1] + harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4]); + ap += int(ac); if (ac) { @@ -767,7 +766,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y) if (AltIcon.Exists() && (rover->Icon.isValid() || AltIcon.isValid()) ) { - int trans = rover==CPlayer->mo->InvSel ? FRACUNIT : 0x6666; + int trans = rover==CPlayer->mo->InvSel ? 0x10000 : 0x6666; DrawImageToBox(TexMan[AltIcon.isValid()? AltIcon : rover->Icon], x, y, 19, 25, trans); if (rover->Amount>1) @@ -819,23 +818,20 @@ static void DrawFrags(player_t * CPlayer, int x, int y) static void DrawCoordinates(player_t * CPlayer) { - fixed_t x; - fixed_t y; - fixed_t z; + DVector3 pos; char coordstr[18]; int h = SmallFont->GetHeight()+1; if (!map_point_coordinates || !automapactive) { - x=CPlayer->mo->X(); - y=CPlayer->mo->Y(); - z=CPlayer->mo->Z(); + pos = CPlayer->mo->Pos(); } else { - AM_GetPosition(x,y); - z = P_PointInSector(x, y)->floorplane.ZatPoint(x, y); + DVector2 apos = AM_GetPosition(); + double z = P_PointInSector(apos)->floorplane.ZatPoint(apos); + pos = DVector3(apos, z); } int vwidth = con_scaletext==0? SCREENWIDTH : SCREENWIDTH/2; @@ -843,17 +839,17 @@ static void DrawCoordinates(player_t * CPlayer) int xpos = vwidth - SmallFont->StringWidth("X: -00000")-6; int ypos = 18; - mysnprintf(coordstr, countof(coordstr), "X: %d", x>>FRACBITS); + mysnprintf(coordstr, countof(coordstr), "X: %d", int(pos.X)); screen->DrawText(SmallFont, hudcolor_xyco, xpos, ypos, coordstr, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); - mysnprintf(coordstr, countof(coordstr), "Y: %d", y>>FRACBITS); + mysnprintf(coordstr, countof(coordstr), "Y: %d", int(pos.Y)); screen->DrawText(SmallFont, hudcolor_xyco, xpos, ypos+h, coordstr, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); - mysnprintf(coordstr, countof(coordstr), "Z: %d", z>>FRACBITS); + mysnprintf(coordstr, countof(coordstr), "Z: %d", int(pos.Z)); screen->DrawText(SmallFont, hudcolor_xyco, xpos, ypos+2*h, coordstr, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); @@ -934,7 +930,7 @@ static void DrawTime() const int width = SmallFont->GetCharWidth('0') * characterCount + 2; // small offset from screen's border const int height = SmallFont->GetHeight(); - DrawHudText(SmallFont, hud_timecolor, timeString, hudwidth - width, height, FRACUNIT); + DrawHudText(SmallFont, hud_timecolor, timeString, hudwidth - width, height, 0x10000); } static bool IsAltHUDTextVisible() @@ -992,7 +988,7 @@ static void DrawLatency() const int width = SmallFont->GetCharWidth('0') * characterCount + 2; // small offset from screen's border const int height = SmallFont->GetHeight() * (ST_IsTimeVisible() ? 2 : 1); - DrawHudText(SmallFont, color, tempstr, hudwidth - width, height, FRACUNIT); + DrawHudText(SmallFont, color, tempstr, hudwidth - width, height, 0x10000); } bool ST_IsLatencyVisible() @@ -1083,7 +1079,7 @@ void DrawHUD() { seconds = Tics2Seconds(level.totaltime); mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); - DrawHudText(SmallFont, hudcolor_ttim, printstr, hudwidth-length, bottom, FRACUNIT); + DrawHudText(SmallFont, hudcolor_ttim, printstr, hudwidth-length, bottom, 0x10000); bottom -= fonth; } @@ -1093,14 +1089,14 @@ void DrawHUD() { seconds = Tics2Seconds(level.time); mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); - DrawHudText(SmallFont, hudcolor_time, printstr, hudwidth-length, bottom, FRACUNIT); + DrawHudText(SmallFont, hudcolor_time, printstr, hudwidth-length, bottom, 0x10000); bottom -= fonth; } // Single level time for hubs seconds= Tics2Seconds(level.maptime); mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); - DrawHudText(SmallFont, hudcolor_ltim, printstr, hudwidth-length, bottom, FRACUNIT); + DrawHudText(SmallFont, hudcolor_ltim, printstr, hudwidth-length, bottom, 0x10000); } ST_FormatMapName(mapname); diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 16f6d7319..b48c04893 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -56,8 +56,8 @@ #include "../version.h" -#define XHAIRSHRINKSIZE (FRACUNIT/18) -#define XHAIRPICKUPSIZE (FRACUNIT*2+XHAIRSHRINKSIZE) +#define XHAIRSHRINKSIZE (1./18) +#define XHAIRPICKUPSIZE (2+XHAIRSHRINKSIZE) #define POWERUPICONSIZE 32 IMPLEMENT_POINTY_CLASS(DBaseStatusBar) @@ -232,7 +232,7 @@ DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres) CompleteBorder = false; Centering = false; FixedOrigin = false; - CrosshairSize = FRACUNIT; + CrosshairSize = 1.; RelTop = reltop; memset(Messages, 0, sizeof(Messages)); Displacement = 0; @@ -286,7 +286,7 @@ void DBaseStatusBar::SetScaled (bool scale, bool force) ::ST_Y = ST_Y; if (RelTop > 0) { - Displacement = ((ST_Y * VirticalResolution / SCREENHEIGHT) - (VirticalResolution - RelTop))*FRACUNIT/RelTop; + Displacement = double((ST_Y * VirticalResolution / SCREENHEIGHT) - (VirticalResolution - RelTop))/RelTop; } else { @@ -376,12 +376,12 @@ void DBaseStatusBar::Tick () } // If the crosshair has been enlarged, shrink it. - if (CrosshairSize > FRACUNIT) + if (CrosshairSize > 1.) { CrosshairSize -= XHAIRSHRINKSIZE; - if (CrosshairSize < FRACUNIT) + if (CrosshairSize < 1.) { - CrosshairSize = FRACUNIT; + CrosshairSize = 1.; } } } @@ -566,27 +566,6 @@ void DBaseStatusBar::DrawDimImage (FTexture *img, } } -//--------------------------------------------------------------------------- -// -// PROC DrawImage -// -// Draws a translucent image with the status bar's upper-left corner as the -// origin. -// -//--------------------------------------------------------------------------- - -void DBaseStatusBar::DrawFadedImage (FTexture *img, - int x, int y, fixed_t shade) const -{ - if (img != NULL) - { - screen->DrawTexture (img, x + ST_X, y + ST_Y, - DTA_Alpha, shade, - DTA_Bottom320x200, Scaled, - TAG_DONE); - } -} - //--------------------------------------------------------------------------- // // PROC DrawPartialImage @@ -761,7 +740,7 @@ void DBaseStatusBar::DrINumberOuter (signed int val, int x, int y, bool center, else if (val == 0) { screen->DrawTexture (Images[imgINumbers], x + 1, y + 1, - DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, + DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); screen->DrawTexture (Images[imgINumbers], x, y, DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); @@ -775,7 +754,7 @@ void DBaseStatusBar::DrINumberOuter (signed int val, int x, int y, bool center, while (val != 0) { screen->DrawTexture (Images[imgINumbers + val % 10], x + 1, y + 1, - DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, + DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); x -= w; val /= 10; @@ -783,7 +762,7 @@ void DBaseStatusBar::DrINumberOuter (signed int val, int x, int y, bool center, if (negative) { screen->DrawTexture (Images[imgNEGATIVE], x + 1, y + 1, - DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, + DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal, TAG_DONE); } @@ -838,7 +817,7 @@ void DBaseStatusBar::DrBNumberOuter (signed int val, int x, int y, int size) con { screen->DrawTexture (pic, xpos - pic->GetWidth()/2 + 2, y + 2, DTA_HUDRules, HUD_Normal, - DTA_Alpha, HR_SHADOW, + DTA_AlphaF, HR_SHADOW, DTA_FillColor, 0, TAG_DONE); screen->DrawTexture (pic, xpos - pic->GetWidth()/2, y, @@ -864,7 +843,7 @@ void DBaseStatusBar::DrBNumberOuter (signed int val, int x, int y, int size) con { screen->DrawTexture (pic, xpos - pic->GetWidth()/2 + 2, y + 2, DTA_HUDRules, HUD_Normal, - DTA_Alpha, HR_SHADOW, + DTA_AlphaF, HR_SHADOW, DTA_FillColor, 0, TAG_DONE); } @@ -878,7 +857,7 @@ void DBaseStatusBar::DrBNumberOuter (signed int val, int x, int y, int size) con { screen->DrawTexture (pic, xpos - pic->GetWidth()/2 + 2, y + 2, DTA_HUDRules, HUD_Normal, - DTA_Alpha, HR_SHADOW, + DTA_AlphaF, HR_SHADOW, DTA_FillColor, 0, TAG_DONE); } @@ -940,7 +919,7 @@ void DBaseStatusBar::DrBNumberOuterFont (signed int val, int x, int y, int size) pic = BigFont->GetChar ('0', &v); screen->DrawTexture (pic, xpos - v/2 + 2, y + 2, DTA_HUDRules, HUD_Normal, - DTA_Alpha, HR_SHADOW, + DTA_AlphaF, HR_SHADOW, DTA_FillColor, 0, DTA_Translation, BigFont->GetColorTranslation (CR_UNTRANSLATED), TAG_DONE); @@ -965,7 +944,7 @@ void DBaseStatusBar::DrBNumberOuterFont (signed int val, int x, int y, int size) pic = BigFont->GetChar ('0' + val % 10, &v); screen->DrawTexture (pic, xpos - v/2 + 2, y + 2, DTA_HUDRules, HUD_Normal, - DTA_Alpha, HR_SHADOW, + DTA_AlphaF, HR_SHADOW, DTA_FillColor, 0, DTA_Translation, BigFont->GetColorTranslation (CR_UNTRANSLATED), TAG_DONE); @@ -979,7 +958,7 @@ void DBaseStatusBar::DrBNumberOuterFont (signed int val, int x, int y, int size) { screen->DrawTexture (pic, xpos - v/2 + 2, y + 2, DTA_HUDRules, HUD_Normal, - DTA_Alpha, HR_SHADOW, + DTA_AlphaF, HR_SHADOW, DTA_FillColor, 0, DTA_Translation, BigFont->GetColorTranslation (CR_UNTRANSLATED), TAG_DONE); @@ -1112,7 +1091,7 @@ void DBaseStatusBar::DrawCrosshair () static int palettecolor = 0; DWORD color; - fixed_t size; + double size; int w, h; // Don't draw the crosshair in chasecam mode @@ -1129,19 +1108,19 @@ void DBaseStatusBar::DrawCrosshair () if (crosshairscale) { - size = SCREENHEIGHT * FRACUNIT / 200; + size = SCREENHEIGHT / 200.; } else { - size = FRACUNIT; + size = 1.; } if (crosshairgrow) { - size = FixedMul (size, CrosshairSize); + size *= CrosshairSize; } - w = (CrosshairImage->GetWidth() * size) >> FRACBITS; - h = (CrosshairImage->GetHeight() * size) >> FRACBITS; + w = int(CrosshairImage->GetWidth() * size); + h = int(CrosshairImage->GetHeight() * size); if (crosshairhealth) { @@ -1254,7 +1233,6 @@ void DBaseStatusBar::Draw (EHudState state) { // Draw current coordinates int height = SmallFont->GetHeight(); char labels[3] = { 'X', 'Y', 'Z' }; - fixed_t *value; int i; int vwidth; @@ -1285,10 +1263,10 @@ void DBaseStatusBar::Draw (EHudState state) y -= height * 2; } - fixedvec3 pos = CPlayer->mo->Pos(); - for (i = 2, value = &pos.z; i >= 0; y -= height, --value, --i) + DVector3 pos = CPlayer->mo->Pos(); + for (i = 2; i >= 0; y -= height, --i) { - mysnprintf (line, countof(line), "%c: %d", labels[i], *value >> FRACBITS); + mysnprintf (line, countof(line), "%c: %d", labels[i], int(pos[i])); screen->DrawText (SmallFont, CR_GREEN, xpos, y, line, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, @@ -1673,17 +1651,9 @@ void DBaseStatusBar::ReceivedWeapon (AWeapon *weapon) void DBaseStatusBar::Serialize (FArchive &arc) { - if (SaveVersion < 3821) + for (size_t i = 0; i < countof(Messages); ++i) { - memset(Messages, 0, sizeof(Messages)); - arc << Messages[HUDMSGLayer_Default]; - } - else - { - for (size_t i = 0; i < countof(Messages); ++i) - { - arc << Messages[i]; - } + arc << Messages[i]; } } diff --git a/src/g_skill.cpp b/src/g_skill.cpp index a4956477c..44c2cef8c 100644 --- a/src/g_skill.cpp +++ b/src/g_skill.cpp @@ -59,10 +59,12 @@ void FMapInfoParser::ParseSkill () bool thisisdefault = false; bool acsreturnisset = false; - skill.AmmoFactor = FRACUNIT; - skill.DoubleAmmoFactor = 2*FRACUNIT; - skill.DropAmmoFactor = -1; - skill.DamageFactor = FRACUNIT; + skill.AmmoFactor = 1.; + skill.DoubleAmmoFactor = 2.; + skill.DropAmmoFactor = -1.; + skill.DamageFactor = 1.; + skill.ArmorFactor = 1.; + skill.HealthFactor = 1.; skill.FastMonsters = false; skill.SlowMonsters = false; skill.DisableCheats = false; @@ -71,7 +73,7 @@ void FMapInfoParser::ParseSkill () skill.AutoUseHealth = false; skill.RespawnCounter = 0; skill.RespawnLimit = 0; - skill.Aggressiveness = FRACUNIT; + skill.Aggressiveness = 1.; skill.SpawnFilter = 0; skill.ACSReturn = 0; skill.MustConfirm = false; @@ -79,12 +81,10 @@ void FMapInfoParser::ParseSkill () skill.TextColor = ""; skill.Replace.Clear(); skill.Replaced.Clear(); - skill.MonsterHealth = FRACUNIT; - skill.FriendlyHealth = FRACUNIT; + skill.MonsterHealth = 1.; + skill.FriendlyHealth = 1.; skill.NoPain = false; - skill.ArmorFactor = FRACUNIT; skill.Infighting = 0; - skill.HealthFactor = FRACUNIT; sc.MustGetString(); skill.Name = sc.String; @@ -97,25 +97,25 @@ void FMapInfoParser::ParseSkill () { ParseAssign(); sc.MustGetFloat (); - skill.AmmoFactor = FLOAT2FIXED(sc.Float); + skill.AmmoFactor = sc.Float; } else if (sc.Compare ("doubleammofactor")) { ParseAssign(); sc.MustGetFloat (); - skill.DoubleAmmoFactor = FLOAT2FIXED(sc.Float); + skill.DoubleAmmoFactor = sc.Float; } else if (sc.Compare ("dropammofactor")) { ParseAssign(); sc.MustGetFloat (); - skill.DropAmmoFactor = FLOAT2FIXED(sc.Float); + skill.DropAmmoFactor = sc.Float; } else if (sc.Compare ("damagefactor")) { ParseAssign(); sc.MustGetFloat (); - skill.DamageFactor = FLOAT2FIXED(sc.Float); + skill.DamageFactor = sc.Float; } else if (sc.Compare ("fastmonsters")) { @@ -157,7 +157,7 @@ void FMapInfoParser::ParseSkill () { ParseAssign(); sc.MustGetFloat (); - skill.Aggressiveness = FRACUNIT - FLOAT2FIXED(clamp(sc.Float, 0.,1.)); + skill.Aggressiveness = 1. - clamp(sc.Float, 0.,1.); } else if (sc.Compare("SpawnFilter")) { @@ -250,13 +250,13 @@ void FMapInfoParser::ParseSkill () { ParseAssign(); sc.MustGetFloat(); - skill.MonsterHealth = FLOAT2FIXED(sc.Float); + skill.MonsterHealth = sc.Float; } else if (sc.Compare("FriendlyHealth")) { ParseAssign(); sc.MustGetFloat(); - skill.FriendlyHealth = FLOAT2FIXED(sc.Float); + skill.FriendlyHealth = sc.Float; } else if (sc.Compare("NoPain")) { @@ -266,13 +266,13 @@ void FMapInfoParser::ParseSkill () { ParseAssign(); sc.MustGetFloat(); - skill.ArmorFactor = FLOAT2FIXED(sc.Float); + skill.ArmorFactor = sc.Float; } else if (sc.Compare("HealthFactor")) { ParseAssign(); sc.MustGetFloat(); - skill.HealthFactor = FLOAT2FIXED(sc.Float); + skill.HealthFactor = sc.Float; } else if (sc.Compare("NoInfighting")) { @@ -341,19 +341,6 @@ int G_SkillProperty(ESkillProperty prop) { switch(prop) { - case SKILLP_AmmoFactor: - if (dmflags2 & DF2_YES_DOUBLEAMMO) - { - return AllSkills[gameskill].DoubleAmmoFactor; - } - return AllSkills[gameskill].AmmoFactor; - - case SKILLP_DropAmmoFactor: - return AllSkills[gameskill].DropAmmoFactor; - - case SKILLP_DamageFactor: - return AllSkills[gameskill].DamageFactor; - case SKILLP_FastMonsters: return AllSkills[gameskill].FastMonsters || (dmflags & DF_FAST_MONSTERS); @@ -368,9 +355,6 @@ int G_SkillProperty(ESkillProperty prop) case SKILLP_RespawnLimit: return AllSkills[gameskill].RespawnLimit; - case SKILLP_Aggressiveness: - return AllSkills[gameskill].Aggressiveness; - case SKILLP_DisableCheats: return AllSkills[gameskill].DisableCheats; @@ -389,21 +373,9 @@ int G_SkillProperty(ESkillProperty prop) case SKILLP_ACSReturn: return AllSkills[gameskill].ACSReturn; - case SKILLP_MonsterHealth: - return AllSkills[gameskill].MonsterHealth; - - case SKILLP_FriendlyHealth: - return AllSkills[gameskill].FriendlyHealth; - case SKILLP_NoPain: return AllSkills[gameskill].NoPain; - case SKILLP_ArmorFactor: - return AllSkills[gameskill].ArmorFactor; - - case SKILLP_HealthFactor: - return AllSkills[gameskill].HealthFactor; - case SKILLP_Infight: // This property also needs to consider the level flags for the same info. if (level.flags2 & LEVEL2_TOTALINFIGHTING) return 1; @@ -416,6 +388,53 @@ int G_SkillProperty(ESkillProperty prop) return 0; } +//========================================================================== +// +// +// +//========================================================================== + +double G_SkillProperty(EFSkillProperty prop) +{ + if (AllSkills.Size() > 0) + { + switch (prop) + { + case SKILLP_AmmoFactor: + if (dmflags2 & DF2_YES_DOUBLEAMMO) + { + return AllSkills[gameskill].DoubleAmmoFactor; + } + return AllSkills[gameskill].AmmoFactor; + + case SKILLP_DropAmmoFactor: + return AllSkills[gameskill].DropAmmoFactor; + + case SKILLP_ArmorFactor: + return AllSkills[gameskill].ArmorFactor; + + case SKILLP_HealthFactor: + return AllSkills[gameskill].HealthFactor; + + case SKILLP_DamageFactor: + return AllSkills[gameskill].DamageFactor; + + case SKILLP_Aggressiveness: + return AllSkills[gameskill].Aggressiveness; + + case SKILLP_MonsterHealth: + return AllSkills[gameskill].MonsterHealth; + + case SKILLP_FriendlyHealth: + return AllSkills[gameskill].FriendlyHealth; + + } + } + return 0; +} + + + //========================================================================== // // diff --git a/src/g_strife/a_acolyte.cpp b/src/g_strife/a_acolyte.cpp index f0824a98b..e8049da1b 100644 --- a/src/g_strife/a_acolyte.cpp +++ b/src/g_strife/a_acolyte.cpp @@ -29,7 +29,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_HideDecepticon) { PARAM_ACTION_PROLOGUE; - EV_DoDoor (DDoor::doorClose, NULL, self, 999, 8*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorClose, NULL, self, 999, 8., 0, 0, 0); if (self->target != NULL && self->target->player != NULL) { P_NoiseAlert (self->target, self); @@ -95,7 +95,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeShadowyFoe) PARAM_ACTION_PROLOGUE; self->RenderStyle = STYLE_Translucent; - self->alpha = HR_SHADOW; + self->Alpha = HR_SHADOW; self->flags &= ~MF_FRIENDLY; return 0; } diff --git a/src/g_strife/a_alienspectres.cpp b/src/g_strife/a_alienspectres.cpp index 53ab1b42a..a7624785b 100644 --- a/src/g_strife/a_alienspectres.cpp +++ b/src/g_strife/a_alienspectres.cpp @@ -22,19 +22,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkSmall) { PARAM_ACTION_PROLOGUE; - AActor *foo = Spawn("AlienChunkSmall", self->PosPlusZ(10*FRACUNIT), ALLOW_REPLACE); + AActor *foo = Spawn("AlienChunkSmall", self->PosPlusZ(10.), ALLOW_REPLACE); if (foo != NULL) { int t; t = pr_spectrechunk() & 15; - foo->vel.x = (t - (pr_spectrechunk() & 7)) << FRACBITS; + foo->Vel.X = (t - (pr_spectrechunk() & 7)); t = pr_spectrechunk() & 15; - foo->vel.y = (t - (pr_spectrechunk() & 7)) << FRACBITS; + foo->Vel.Y = (t - (pr_spectrechunk() & 7)); - foo->vel.z = (pr_spectrechunk() & 15) << FRACBITS; + foo->Vel.Z = (pr_spectrechunk() & 15); } return 0; } @@ -43,19 +43,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkLarge) { PARAM_ACTION_PROLOGUE; - AActor *foo = Spawn("AlienChunkLarge", self->PosPlusZ(10*FRACUNIT), ALLOW_REPLACE); + AActor *foo = Spawn("AlienChunkLarge", self->PosPlusZ(10.), ALLOW_REPLACE); if (foo != NULL) { int t; t = pr_spectrechunk() & 7; - foo->vel.x = (t - (pr_spectrechunk() & 15)) << FRACBITS; + foo->Vel.X = (t - (pr_spectrechunk() & 15)); t = pr_spectrechunk() & 7; - foo->vel.y = (t - (pr_spectrechunk() & 15)) << FRACBITS; + foo->Vel.Y = (t - (pr_spectrechunk() & 15)); - foo->vel.z = (pr_spectrechunk() & 7) << FRACBITS; + foo->Vel.Z = (pr_spectrechunk() & 7); } return 0; } @@ -67,20 +67,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_Spectre3Attack) if (self->target == NULL) return 0; - AActor *foo = Spawn("SpectralLightningV2", self->PosPlusZ(32*FRACUNIT), ALLOW_REPLACE); + AActor *foo = Spawn("SpectralLightningV2", self->PosPlusZ(32.), ALLOW_REPLACE); - foo->vel.z = -12*FRACUNIT; + foo->Vel.Z = -12; foo->target = self; foo->FriendPlayer = 0; foo->tracer = self->target; - self->angle -= ANGLE_180 / 20 * 10; + self->Angles.Yaw -= 90.; for (int i = 0; i < 20; ++i) { - self->angle += ANGLE_180 / 20; + self->Angles.Yaw += 9.; P_SpawnSubMissile (self, PClass::FindActor("SpectralLightningBall2"), self); } - self->angle -= ANGLE_180 / 20 * 10; + self->Angles.Yaw -= 90.; return 0; } @@ -114,7 +114,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AlienSpectreDeath) switch (self->GetClass()->TypeName) { case NAME_AlienSpectre1: - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 999, FRACUNIT, 0, -1, 0, false); + EV_DoFloor (DFloor::floorLowerToLowest, NULL, 999, 1., 0., -1, 0, false); log = 95; break; @@ -152,7 +152,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AlienSpectreDeath) { // You wield the power of the complete Sigil. log = 85; } - EV_DoDoor (DDoor::doorOpen, NULL, NULL, 222, 8*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorOpen, NULL, NULL, 222, 8., 0, 0, 0); break; } @@ -188,7 +188,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AlienSpectreDeath) { // Another Sigil piece. Woohoo! log = 83; } - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, FRACUNIT, 0, -1, 0, false); + EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, 1., 0., -1, 0, false); break; default: diff --git a/src/g_strife/a_coin.cpp b/src/g_strife/a_coin.cpp index 0796abc54..5848164bd 100644 --- a/src/g_strife/a_coin.cpp +++ b/src/g_strife/a_coin.cpp @@ -54,7 +54,7 @@ AInventory *ACoin::CreateCopy (AActor *other) { return Super::CreateCopy (other); } - AInventory *copy = Spawn (0,0,0, NO_REPLACE); + AInventory *copy = Spawn (); copy->Amount = Amount; copy->BecomeItem (); GoAwayAndDie (); diff --git a/src/g_strife/a_crusader.cpp b/src/g_strife/a_crusader.cpp index a7b2ac23c..b54fdd427 100644 --- a/src/g_strife/a_crusader.cpp +++ b/src/g_strife/a_crusader.cpp @@ -13,7 +13,7 @@ static bool CrusaderCheckRange (AActor *self) { if (self->reactiontime == 0 && P_CheckSight (self, self->target)) { - return self->AproxDistance (self->target) < 264*FRACUNIT; + return self->Distance2D (self->target) < 264.; } return false; } @@ -28,20 +28,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderChoose) if (CrusaderCheckRange (self)) { A_FaceTarget (self); - self->angle -= ANGLE_180/16; - P_SpawnMissileZAimed (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); + self->Angles.Yaw -= 180./16; + P_SpawnMissileZAimed (self, self->Z() + 40, self->target, PClass::FindActor("FastFlameMissile")); } else { if (P_CheckMissileRange (self)) { A_FaceTarget (self); - P_SpawnMissileZAimed (self, self->Z() + 56*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); - self->angle -= ANGLE_45/32; - P_SpawnMissileZAimed (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); - self->angle += ANGLE_45/16; - P_SpawnMissileZAimed (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); - self->angle -= ANGLE_45/16; + P_SpawnMissileZAimed (self, self->Z() + 56, self->target, PClass::FindActor("CrusaderMissile")); + self->Angles.Yaw -= 45./32; + P_SpawnMissileZAimed (self, self->Z() + 40, self->target, PClass::FindActor("CrusaderMissile")); + self->Angles.Yaw += 45./16; + P_SpawnMissileZAimed (self, self->Z() + 40, self->target, PClass::FindActor("CrusaderMissile")); + self->Angles.Yaw -= 45./16; self->reactiontime += 15; } self->SetState (self->SeeState); @@ -53,11 +53,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepLeft) { PARAM_ACTION_PROLOGUE; - self->angle += ANGLE_90/16; - AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); + self->Angles.Yaw += 90./16; + AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48, self->target, PClass::FindActor("FastFlameMissile")); if (misl != NULL) { - misl->vel.z += FRACUNIT; + misl->Vel.Z += 1; } return 0; } @@ -66,11 +66,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepRight) { PARAM_ACTION_PROLOGUE; - self->angle -= ANGLE_90/16; - AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); + self->Angles.Yaw -= 90./16; + AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48, self->target, PClass::FindActor("FastFlameMissile")); if (misl != NULL) { - misl->vel.z += FRACUNIT; + misl->Vel.Z += 1; } return 0; } @@ -94,7 +94,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderDeath) if (CheckBossDeath (self)) { - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 667, FRACUNIT, 0, -1, 0, false); + EV_DoFloor (DFloor::floorLowerToLowest, NULL, 667, 1., 0., -1, 0, false); } return 0; } diff --git a/src/g_strife/a_entityboss.cpp b/src/g_strife/a_entityboss.cpp index 3195d3813..72eeaac3a 100644 --- a/src/g_strife/a_entityboss.cpp +++ b/src/g_strife/a_entityboss.cpp @@ -27,8 +27,7 @@ void A_SpectralMissile (AActor *self, const char *missilename) { if (self->target != NULL) { - AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32*FRACUNIT), - self, self->target, PClass::FindActor(missilename), false); + AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32.), self, self->target, PClass::FindActor(missilename), false); if (missile != NULL) { missile->tracer = self->target; @@ -78,12 +77,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnEntity) { PARAM_ACTION_PROLOGUE; - AActor *entity = Spawn("EntityBoss", self->PosPlusZ(70*FRACUNIT), ALLOW_REPLACE); + AActor *entity = Spawn("EntityBoss", self->PosPlusZ(70.), ALLOW_REPLACE); if (entity != NULL) { - entity->angle = self->angle; + entity->Angles.Yaw = self->Angles.Yaw; entity->CopyFriendliness(self, true); - entity->vel.z = 5*FRACUNIT; + entity->Vel.Z = 5; entity->tracer = self; } return 0; @@ -94,39 +93,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_EntityDeath) PARAM_ACTION_PROLOGUE; AActor *second; - fixed_t secondRadius = GetDefaultByName("EntitySecond")->radius * 2; - angle_t an; + double secondRadius = GetDefaultByName("EntitySecond")->radius * 2; + + static const double turns[3] = { 0, 90, -90 }; + const double velmul[3] = { 4.8828125f, secondRadius*4, secondRadius*4 }; AActor *spot = self->tracer; if (spot == NULL) spot = self; - fixedvec3 pos = spot->Vec3Angle(secondRadius, self->angle, self->tracer? 70*FRACUNIT : 0); - - an = self->angle >> ANGLETOFINESHIFT; - second = Spawn("EntitySecond", pos, ALLOW_REPLACE); - second->CopyFriendliness(self, true); - //second->target = self->target; - A_FaceTarget (second); - an = second->angle >> ANGLETOFINESHIFT; - second->vel.x += FixedMul (finecosine[an], 320000); - second->vel.y += FixedMul (finesine[an], 320000); + for (int i = 0; i < 3; i++) + { + DAngle an = self->Angles.Yaw + turns[i]; + DVector3 pos = spot->Vec3Angle(secondRadius, an, self->tracer ? 70. : 0.); - pos = spot->Vec3Angle(secondRadius, self->angle + ANGLE_90, self->tracer? 70*FRACUNIT : 0); - an = (self->angle + ANGLE_90) >> ANGLETOFINESHIFT; - second = Spawn("EntitySecond", pos, ALLOW_REPLACE); - second->CopyFriendliness(self, true); - //second->target = self->target; - second->vel.x = FixedMul (secondRadius, finecosine[an]) << 2; - second->vel.y = FixedMul (secondRadius, finesine[an]) << 2; - A_FaceTarget (second); - - pos = spot->Vec3Angle(secondRadius, self->angle - ANGLE_90, self->tracer? 70*FRACUNIT : 0); - an = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; - second = Spawn("EntitySecond", pos, ALLOW_REPLACE); - second->CopyFriendliness(self, true); - //second->target = self->target; - second->vel.x = FixedMul (secondRadius, finecosine[an]) << 2; - second->vel.y = FixedMul (secondRadius, finesine[an]) << 2; - A_FaceTarget (second); + second = Spawn("EntitySecond", pos, ALLOW_REPLACE); + second->CopyFriendliness(self, true); + A_FaceTarget(second); + second->VelFromAngle(an, velmul[i]); + } return 0; } diff --git a/src/g_strife/a_inquisitor.cpp b/src/g_strife/a_inquisitor.cpp index 8a44add95..e372d8de1 100644 --- a/src/g_strife/a_inquisitor.cpp +++ b/src/g_strife/a_inquisitor.cpp @@ -23,7 +23,7 @@ bool InquisitorCheckDistance (AActor *self) { if (self->reactiontime == 0 && P_CheckSight (self, self->target)) { - return self->AproxDistance (self->target) < 264*FRACUNIT; + return self->Distance2D (self->target) < 264.; } return false; } @@ -42,7 +42,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorDecide) } if (self->target->Z() != self->Z()) { - if (self->Top() + 54*FRACUNIT < self->ceilingz) + if (self->Top() + 54 < self->ceilingz) { self->SetState (self->FindState("Jump")); } @@ -61,20 +61,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorAttack) A_FaceTarget (self); - self->AddZ(32*FRACUNIT); - self->angle -= ANGLE_45/32; + self->AddZ(32); + self->Angles.Yaw -= 45./32; proj = P_SpawnMissileZAimed (self, self->Z(), self->target, PClass::FindActor("InquisitorShot")); if (proj != NULL) { - proj->vel.z += 9*FRACUNIT; + proj->Vel.Z += 9; } - self->angle += ANGLE_45/16; + self->Angles.Yaw += 45./16; proj = P_SpawnMissileZAimed (self, self->Z(), self->target, PClass::FindActor("InquisitorShot")); if (proj != NULL) { - proj->vel.z += 16*FRACUNIT; + proj->Vel.Z += 16; } - self->AddZ(-32*FRACUNIT); + self->AddZ(-32); return 0; } @@ -82,27 +82,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorJump) { PARAM_ACTION_PROLOGUE; - fixed_t dist; - fixed_t speed; - angle_t an; + double dist; + double speed; if (self->target == NULL) return 0; S_Sound (self, CHAN_ITEM|CHAN_LOOP, "inquisitor/jump", 1, ATTN_NORM); - self->AddZ(64*FRACUNIT); + self->AddZ(64); A_FaceTarget (self); - an = self->angle >> ANGLETOFINESHIFT; - speed = self->Speed * 2/3; - self->vel.x += FixedMul (speed, finecosine[an]); - self->vel.y += FixedMul (speed, finesine[an]); - dist = self->AproxDistance (self->target); - dist /= speed; - if (dist < 1) - { - dist = 1; - } - self->vel.z = (self->target->Z() - self->Z()) / dist; + speed = self->Speed * (2./3); + self->VelFromAngle(speed); + dist = self->DistanceBySpeed(self->target, speed); + self->Vel.Z = (self->target->Z() - self->Z()) / dist; self->reactiontime = 60; self->flags |= MF_NOGRAVITY; return 0; @@ -114,8 +106,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorCheckLand) self->reactiontime--; if (self->reactiontime < 0 || - self->vel.x == 0 || - self->vel.y == 0 || + self->Vel.X == 0 || + self->Vel.Y == 0 || self->Z() <= self->floorz) { self->SetState (self->SeeState); @@ -135,11 +127,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_TossArm) { PARAM_ACTION_PROLOGUE; - AActor *foo = Spawn("InquisitorArm", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE); - foo->angle = self->angle - ANGLE_90 + (pr_inq.Random2() << 22); - foo->vel.x = FixedMul (foo->Speed, finecosine[foo->angle >> ANGLETOFINESHIFT]) >> 3; - foo->vel.y = FixedMul (foo->Speed, finesine[foo->angle >> ANGLETOFINESHIFT]) >> 3; - foo->vel.z = pr_inq() << 10; + AActor *foo = Spawn("InquisitorArm", self->PosPlusZ(24.), ALLOW_REPLACE); + foo->Angles.Yaw = self->Angles.Yaw - 90. + pr_inq.Random2() * (360./1024.); + foo->VelFromAngle(foo->Speed / 8); + foo->Vel.Z = pr_inq() / 64.; return 0; } diff --git a/src/g_strife/a_loremaster.cpp b/src/g_strife/a_loremaster.cpp index 5b2f7fd90..ead116c63 100644 --- a/src/g_strife/a_loremaster.cpp +++ b/src/g_strife/a_loremaster.cpp @@ -24,15 +24,9 @@ int ALoreShot::DoSpecialDamage (AActor *victim, int damage, FName damagetype) if (victim != NULL && target != NULL && !(victim->flags7 & MF7_DONTTHRUST)) { - fixedvec3 fixthrust = victim->Vec3To(target); - DVector3 thrust(fixthrust.x, fixthrust.y, fixthrust.z); - - thrust.MakeUnit(); - thrust *= double((255*50*FRACUNIT) / (victim->Mass ? victim->Mass : 1)); - - victim->vel.x += fixed_t(thrust.X); - victim->vel.y += fixed_t(thrust.Y); - victim->vel.z += fixed_t(thrust.Z); + DVector3 thrust = victim->Vec3To(target); + thrust.MakeResize(255. * 50 / MAX(victim->Mass, 1)); + victim->Vel += thrust; } return damage; } @@ -43,7 +37,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LoremasterChain) S_Sound (self, CHAN_BODY, "loremaster/active", 1, ATTN_NORM); Spawn("LoreShot2", self->Pos(), ALLOW_REPLACE); - Spawn("LoreShot2", self->Vec3Offset(-(self->vel.x >> 1), -(self->vel.y >> 1), -(self->vel.z >> 1)), ALLOW_REPLACE); - Spawn("LoreShot2", self->Vec3Offset(-self->vel.x, -self->vel.y, -self->vel.z), ALLOW_REPLACE); + Spawn("LoreShot2", self->Vec3Offset(-self->Vel/2.), ALLOW_REPLACE); + Spawn("LoreShot2", self->Vec3Offset(-self->Vel), ALLOW_REPLACE); return 0; } diff --git a/src/g_strife/a_programmer.cpp b/src/g_strife/a_programmer.cpp index 214641e03..bed5f838b 100644 --- a/src/g_strife/a_programmer.cpp +++ b/src/g_strife/a_programmer.cpp @@ -109,7 +109,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpotLightning) if (self->target == NULL) return 0; - spot = Spawn("SpectralLightningSpot", self->target->X(), self->target->Y(), self->target->floorz, ALLOW_REPLACE); + spot = Spawn("SpectralLightningSpot", self->target->PosAtZ(self->target->floorz), ALLOW_REPLACE); if (spot != NULL) { spot->threshold = 25; @@ -130,13 +130,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnProgrammerBase) { PARAM_ACTION_PROLOGUE; - AActor *foo = Spawn("ProgrammerBase", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE); + AActor *foo = Spawn("ProgrammerBase", self->PosPlusZ(24.), ALLOW_REPLACE); if (foo != NULL) { - foo->angle = self->angle + ANGLE_180 + (pr_prog.Random2() << 22); - foo->vel.x = FixedMul (foo->Speed, finecosine[foo->angle >> ANGLETOFINESHIFT]); - foo->vel.y = FixedMul (foo->Speed, finesine[foo->angle >> ANGLETOFINESHIFT]); - foo->vel.z = pr_prog() << 9; + foo->Angles.Yaw = self->Angles.Yaw + 180. + pr_prog.Random2() * (360. / 1024.); + foo->VelFromAngle(); + foo->Vel.Z = pr_prog() / 128.; } return 0; } diff --git a/src/g_strife/a_reaver.cpp b/src/g_strife/a_reaver.cpp index 393670f06..372aea794 100644 --- a/src/g_strife/a_reaver.cpp +++ b/src/g_strife/a_reaver.cpp @@ -17,17 +17,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_ReaverRanged) if (self->target != NULL) { - angle_t bangle; - int pitch; + DAngle bangle; + DAngle pitch; A_FaceTarget (self); S_Sound (self, CHAN_WEAPON, "reaver/attack", 1, ATTN_NORM); - bangle = self->angle; + bangle = self->Angles.Yaw; pitch = P_AimLineAttack (self, bangle, MISSILERANGE); for (int i = 0; i < 3; ++i) { - angle_t angle = bangle + (pr_reaverattack.Random2() << 20); + DAngle angle = bangle + pr_reaverattack.Random2() * (22.5 / 256); int damage = ((pr_reaverattack() & 7) + 1) * 3; P_LineAttack (self, angle, MISSILERANGE, pitch, damage, NAME_Hitscan, NAME_StrifePuff); } diff --git a/src/g_strife/a_rebels.cpp b/src/g_strife/a_rebels.cpp index 6a93ef91e..dd5267c60 100644 --- a/src/g_strife/a_rebels.cpp +++ b/src/g_strife/a_rebels.cpp @@ -24,15 +24,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShootGun) { PARAM_ACTION_PROLOGUE; - int pitch; + DAngle pitch; if (self->target == NULL) return 0; S_Sound (self, CHAN_WEAPON, "monsters/rifle", 1, ATTN_NORM); A_FaceTarget (self); - pitch = P_AimLineAttack (self, self->angle, MISSILERANGE); - P_LineAttack (self, self->angle + (pr_shootgun.Random2() << 19), + pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); + P_LineAttack (self, self->Angles.Yaw + pr_shootgun.Random2() * (11.25 / 256), MISSILERANGE, pitch, 3*(pr_shootgun() % 5 + 1), NAME_Hitscan, NAME_StrifePuff); return 0; @@ -78,10 +78,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Beacon) AActor *owner = self->target; AActor *rebel; - angle_t an; - rebel = Spawn("Rebel1", self->X(), self->Y(), self->floorz, ALLOW_REPLACE); - if (!P_TryMove (rebel, rebel->X(), rebel->Y(), true)) + rebel = Spawn("Rebel1", self->PosAtZ(self->floorz), ALLOW_REPLACE); + if (!P_TryMove (rebel, rebel->Pos(), true)) { rebel->Destroy (); return 0; @@ -115,9 +114,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Beacon) } rebel->SetState (rebel->SeeState); - rebel->angle = self->angle; - an = self->angle >> ANGLETOFINESHIFT; - Spawn (rebel->Vec3Offset(20*finecosine[an], 20*finesine[an], TELEFOGHEIGHT), ALLOW_REPLACE); + rebel->Angles.Yaw = self->Angles.Yaw; + Spawn (rebel->Vec3Angle(20., self->Angles.Yaw, TELEFOGHEIGHT), ALLOW_REPLACE); if (--self->health < 0) { self->SetState(self->FindState(NAME_Death)); diff --git a/src/g_strife/a_sentinel.cpp b/src/g_strife/a_sentinel.cpp index 21eaa9993..fa99c827f 100644 --- a/src/g_strife/a_sentinel.cpp +++ b/src/g_strife/a_sentinel.cpp @@ -13,29 +13,29 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelBob) { PARAM_ACTION_PROLOGUE; - fixed_t minz, maxz; + double minz, maxz; if (self->flags & MF_INFLOAT) { - self->vel.z = 0; + self->Vel.Z = 0; return 0; } if (self->threshold != 0) return 0; - maxz = self->ceilingz - self->height - 16*FRACUNIT; - minz = self->floorz + 96*FRACUNIT; + maxz = self->ceilingz - self->Height - 16; + minz = self->floorz + 96; if (minz > maxz) { minz = maxz; } if (minz < self->Z()) { - self->vel.z -= FRACUNIT; + self->Vel.Z -= 1; } else { - self->vel.z += FRACUNIT; + self->Vel.Z += 1; } self->reactiontime = (minz >= self->Z()) ? 4 : 0; return 0; @@ -53,24 +53,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelAttack) return 0; } - missile = P_SpawnMissileZAimed (self, self->Z() + 32*FRACUNIT, self->target, PClass::FindActor("SentinelFX2")); + missile = P_SpawnMissileZAimed (self, self->Z() + 32, self->target, PClass::FindActor("SentinelFX2")); - if (missile != NULL && (missile->vel.x | missile->vel.y) != 0) + if (missile != NULL && (missile->Vel.X != 0 || missile->Vel.Y != 0)) { for (int i = 8; i > 1; --i) { trail = Spawn("SentinelFX1", - self->Vec3Angle(missile->radius*i, missile->angle, (missile->vel.z / 4 * i)), ALLOW_REPLACE); + self->Vec3Angle(missile->radius*i, missile->Angles.Yaw, missile->Vel.Z / 4 * i), ALLOW_REPLACE); if (trail != NULL) { trail->target = self; - trail->vel.x = missile->vel.x; - trail->vel.y = missile->vel.y; - trail->vel.z = missile->vel.z; + trail->Vel = missile->Vel; P_CheckMissileSpawn (trail, self->radius); } } - missile->AddZ(missile->vel.z >> 2); + missile->AddZ(missile->Vel.Z / 4); } return 0; } diff --git a/src/g_strife/a_spectral.cpp b/src/g_strife/a_spectral.cpp index b5003105c..00b19055c 100644 --- a/src/g_strife/a_spectral.cpp +++ b/src/g_strife/a_spectral.cpp @@ -28,9 +28,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectralLightningTail) { PARAM_ACTION_PROLOGUE; - AActor *foo = Spawn("SpectralLightningHTail", self->Vec3Offset(-self->vel.x, -self->vel.y, 0), ALLOW_REPLACE); + AActor *foo = Spawn("SpectralLightningHTail", self->Vec3Offset(-self->Vel.X, -self->Vel.Y, 0.), ALLOW_REPLACE); - foo->angle = self->angle; + foo->Angles.Yaw = self->Angles.Yaw; foo->FriendPlayer = self->FriendPlayer; return 0; } @@ -42,11 +42,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectralBigBallLightning) PClassActor *cls = PClass::FindActor("SpectralLightningH3"); if (cls) { - self->angle += ANGLE_90; + self->Angles.Yaw += 90.; P_SpawnSubMissile (self, cls, self->target); - self->angle += ANGLE_180; + self->Angles.Yaw += 180.; P_SpawnSubMissile (self, cls, self->target); - self->angle += ANGLE_90; + self->Angles.Yaw -= 270.; P_SpawnSubMissile (self, cls, self->target); } return 0; @@ -63,93 +63,81 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectralLightning) if (self->threshold != 0) --self->threshold; - self->vel.x += pr_zap5.Random2(3) << FRACBITS; - self->vel.y += pr_zap5.Random2(3) << FRACBITS; + self->Vel.X += pr_zap5.Random2(3); + self->Vel.Y += pr_zap5.Random2(3); - fixedvec2 pos = self->Vec2Offset( - pr_zap5.Random2(3) * FRACUNIT * 50, - pr_zap5.Random2(3) * FRACUNIT * 50); + double xo = pr_zap5.Random2(3) * 50.; + double yo = pr_zap5.Random2(3) * 50.; flash = Spawn (self->threshold > 25 ? PClass::FindActor(NAME_SpectralLightningV2) : - PClass::FindActor(NAME_SpectralLightningV1), pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE); + PClass::FindActor(NAME_SpectralLightningV1), self->Vec2OffsetZ(xo, yo, ONCEILINGZ), ALLOW_REPLACE); flash->target = self->target; - flash->vel.z = -18*FRACUNIT; + flash->Vel.Z = -18; flash->FriendPlayer = self->FriendPlayer; - flash = Spawn(NAME_SpectralLightningV2, self->X(), self->Y(), ONCEILINGZ, ALLOW_REPLACE); + flash = Spawn(NAME_SpectralLightningV2, self->PosAtZ(ONCEILINGZ), ALLOW_REPLACE); flash->target = self->target; - flash->vel.z = -18*FRACUNIT; + flash->Vel.Z = -18; flash->FriendPlayer = self->FriendPlayer; return 0; } // In Strife, this number is stored in the data segment, but it doesn't seem to be // altered anywhere. -#define TRACEANGLE (0xe000000) +#define TRACEANGLE (19.6875) DEFINE_ACTION_FUNCTION(AActor, A_Tracer2) { PARAM_ACTION_PROLOGUE; AActor *dest; - angle_t exact; - fixed_t dist; - fixed_t slope; + double dist; + double slope; dest = self->tracer; if (!dest || dest->health <= 0 || self->Speed == 0 || !self->CanSeek(dest)) return 0; - // change angle - exact = self->AngleTo(dest); + DAngle exact = self->AngleTo(dest); + DAngle diff = deltaangle(self->Angles.Yaw, exact); - if (exact != self->angle) + if (diff < 0) { - if (exact - self->angle > 0x80000000) - { - self->angle -= TRACEANGLE; - if (exact - self->angle < 0x80000000) - self->angle = exact; - } - else - { - self->angle += TRACEANGLE; - if (exact - self->angle > 0x80000000) - self->angle = exact; - } + self->Angles.Yaw -= TRACEANGLE; + if (deltaangle(self->Angles.Yaw, exact) > 0) + self->Angles.Yaw = exact; + } + else if (diff > 0) + { + self->Angles.Yaw += TRACEANGLE; + if (deltaangle(self->Angles.Yaw, exact) < 0.) + self->Angles.Yaw = exact; } - exact = self->angle >> ANGLETOFINESHIFT; - self->vel.x = FixedMul (self->Speed, finecosine[exact]); - self->vel.y = FixedMul (self->Speed, finesine[exact]); + self->VelFromAngle(); if (!(self->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { // change slope - dist = self->AproxDistance (dest) / self->Speed; - - if (dist < 1) + dist = self->DistanceBySpeed (dest, self->Speed); + if (dest->Height >= 56) { - dist = 1; - } - if (dest->height >= 56*FRACUNIT) - { - slope = (dest->Z()+40*FRACUNIT - self->Z()) / dist; + slope = (dest->Z()+40 - self->Z()) / dist; } else { - slope = (dest->Z() + self->height*2/3 - self->Z()) / dist; + slope = (dest->Z() + self->Height*(2./3) - self->Z()) / dist; } - if (slope < self->vel.z) + if (slope < self->Vel.Z) { - self->vel.z -= FRACUNIT/8; + self->Vel.Z -= 1 / 8.; } else { - self->vel.z += FRACUNIT/8; + self->Vel.Z += 1 / 8.; } } return 0; diff --git a/src/g_strife/a_strifeitems.cpp b/src/g_strife/a_strifeitems.cpp index 896357c8d..45e8218e1 100644 --- a/src/g_strife/a_strifeitems.cpp +++ b/src/g_strife/a_strifeitems.cpp @@ -82,7 +82,7 @@ bool AHealthTraining::TryPickup (AActor *&toucher) if (Super::TryPickup (toucher)) { toucher->GiveInventoryType (PClass::FindActor("GunTraining")); - AInventory *coin = Spawn (0,0,0, NO_REPLACE); + AInventory *coin = Spawn (); if (coin != NULL) { coin->Amount = toucher->player->mo->accuracy*5 + 300; @@ -135,7 +135,7 @@ IMPLEMENT_CLASS (APrisonPass) bool APrisonPass::TryPickup (AActor *&toucher) { Super::TryPickup (toucher); - EV_DoDoor (DDoor::doorOpen, NULL, toucher, 223, 2*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorOpen, NULL, toucher, 223, 2., 0, 0, 0); toucher->GiveInventoryType (QuestItemClasses[9]); return true; } @@ -152,7 +152,7 @@ bool APrisonPass::TryPickup (AActor *&toucher) bool APrisonPass::SpecialDropAction (AActor *dropper) { - EV_DoDoor (DDoor::doorOpen, NULL, dropper, 223, 2*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorOpen, NULL, dropper, 223, 2., 0, 0, 0); Destroy (); return true; } @@ -210,7 +210,7 @@ IMPLEMENT_CLASS (AOpenDoor222) bool AOpenDoor222::TryPickup (AActor *&toucher) { - EV_DoDoor (DDoor::doorOpen, NULL, toucher, 222, 2*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorOpen, NULL, toucher, 222, 2., 0, 0, 0); GoAwayAndDie (); return true; } @@ -229,14 +229,14 @@ IMPLEMENT_CLASS (ACloseDoor222) bool ACloseDoor222::TryPickup (AActor *&toucher) { - EV_DoDoor (DDoor::doorClose, NULL, toucher, 222, 2*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorClose, NULL, toucher, 222, 2., 0, 0, 0); GoAwayAndDie (); return true; } bool ACloseDoor222::SpecialDropAction (AActor *dropper) { - EV_DoDoor (DDoor::doorClose, NULL, dropper, 222, 2*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorClose, NULL, dropper, 222, 2., 0, 0, 0); if (dropper->target->CheckLocalView (consoleplayer)) { Printf ("You're dead! You set off the alarm.\n"); @@ -260,14 +260,14 @@ IMPLEMENT_CLASS (AOpenDoor224) bool AOpenDoor224::TryPickup (AActor *&toucher) { - EV_DoDoor (DDoor::doorOpen, NULL, toucher, 224, 2*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorOpen, NULL, toucher, 224, 2., 0, 0, 0); GoAwayAndDie (); return true; } bool AOpenDoor224::SpecialDropAction (AActor *dropper) { - EV_DoDoor (DDoor::doorOpen, NULL, dropper, 224, 2*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorOpen, NULL, dropper, 224, 2., 0, 0, 0); Destroy (); return true; } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index abbfc2300..097965e34 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -58,354 +58,6 @@ // angle += pr_spawnmissile.Random2() << 22 // Note that these numbers are different from those used by all the other Doom engine games. -/* These mobjinfos have been converted: - - 0 ForceFieldGuard - 1 StrifePlayer - 2 WeaponSmith - 3 BarKeep - 4 Armorer - 5 Medic - 6 Peasant1 - 7 Peasant2 - 8 Peasant3 - 9 Peasant4 - 10 Peasant5 - 11 Peasant6 - 12 Peasant7 - 13 Peasant8 - 14 Peasant9 - 15 Peasant10 - 16 Peasant11 - 17 Peasant12 - 18 Peasant13 - 19 Peasant14 - 20 Peasant15 - 21 Peasant16 - 22 Peasant17 - 23 Peasant18 - 24 Peasant19 - 25 Peasant20 - 26 Peasant21 - 27 Peasant22 - 28 Zombie - 29 AcolyteToBe - 30 ZombieSpawner - 31 Tank1 - 32 Tank2 - 33 Tank3 - 34 Tank4 - 35 Tank5 - 36 Tank6 - 37 KneelingGuy - 38 Beggar1 - 39 Beggar2 - 40 Beggar3 - 41 Beggar4 - 42 Beggar5 - 43 Rebel1 - 44 Rebel2 - 45 Rebel3 - 46 Rebel4 - 47 Rebel5 - 48 Rebel6 - 49 Macil1 - 50 Macil2 - 51 RocketTrail - 52 Reaver - 53 AcolyteTan - 54 AcolyteRed - 55 AcolyteRust - 56 AcolyteGray - 57 AcolyteDGreen - 58 AcolyteGold - 59 AcolyteLGreen - 60 AcolyteBlue - 61 AcolyteShadow - 62 Templar - 63 Crusader - 64 StrifeBishop - 65 Oracle - 66 Loremaster (aka Priest) - 67 AlienSpectre1 - 68 AlienChunkSmall - 69 AlienChunkLarge - 70 AlienSpectre2 - 71 AlienSpectre3 - 72 AlienSpectre4 - 73 AlienSpectre5 - 74 EntityBoss - 75 EntitySecond - 76 EntityNest - 77 EntityPod - 78 SpectralLightningH1 - 79 SpectralLightningH2 - 80 SpectralLightningBall1 - 81 SpectralLightningBall2 - 82 SpectralLightningH3 - 83 SpectralLightningHTail - 84 SpectralLightningBigBall1 - 85 SpectralLightningBigBall2 - 86 SpectralLightningV1 - 87 SpectralLightningV2 - 88 SpectralLightningSpot - 89 SpectralLightningBigV1 - 90 SpectralLightningBigV2 - 91 Sentinel - 92 Stalker - 93 Inquisitor - 94 InquisitorArm - 95 Programmer - 96 ProgrammerBase - 97 LoreShot - 98 LoreShot2 - 99 MiniMissile - 100 CrusaderMissile - 101 BishopMissile - 102 ElectricBolt - 103 PoisonBolt - 104 SentinelFX1 - 105 SentinelFX2 - 106 HEGrenade - 107 PhosphorousGrenade - 108 InquisitorShot - 109 PhosphorousFire - 110 MaulerTorpedo - 111 MaulerTorpedoWave - 112 FlameMissile - 113 FastFlameMissile - 114 MaulerPuff - 115 StrifePuff - 116 StrifeSpark - 117 Blood - 118 TeleportFog - 119 ItemFog - 120 teleport destination - 121 KlaxonWarningLight - 122 CeilingTurret - 123 Piston - 124 Computer - 125 MedPatch - 126 MedicalKit - 127 SurgeryKit - 128 DegninOre - 129 MetalArmor - 130 LeatherArmor - 131 WaterBottle - 132 Mug - 133 BaseKey - 134 GovsKey - 135 Passcard - 136 IDBadge - 137 PrisonKey - 138 SeveredHand - 139 Power1Key - 140 Power2Key - 141 Power3Key - 142 GoldKey - 143 IDCard - 144 SilverKey - 145 OracleKey - 146 MilitaryID - 147 OrderKey - 148 WarehouseKey - 149 BrassKey - 150 RedCrystalKey - 151 BlueCrystalKey - 152 ChapelKey - 153 CatacombKey - 154 SecurityKey - 155 CoreKey - 156 MaulerKey - 157 FactoryKey - 158 MineKey - 159 NewKey5 - 160 ShadowArmor - 161 EnvironmentalSuit - 162 GuardUniform - 163 OfficersUniform - 164 StrifeMap - 165 Scanner - 166 - 167 Targeter - 168 Coin - 169 Gold10 - 170 Gold25 - 171 Gold50 - 172 Gold300 - 173 BeldinsRing - 174 OfferingChalice - 175 Ear - 176 Communicator - 177 HEGrenadeRounds - 178 PhosphorusGrenadeRounds - 179 ClipOfBullets - 180 BoxOfBullets - 181 MiniMissiles - 182 CrateOfMissiles - 183 EnergyPod - 184 EnergyPack - 185 PoisonBolts - 186 ElectricBolts - 187 AmmoSatchel - 188 AssaultGun - 189 AssaultGunStanding - 190 FlameThrower - 191 FlameThrowerParts - 192 MiniMissileLauncher - 193 Mauler - 194 StrifeCrossbow - 195 StrifeGrenadeLauncher - 196 Sigil1 - 197 Sigil2 - 198 Sigil3 - 199 Sigil4 - 200 Sigil5 - 201 PowerCrystal - 202 RatBuddy - 203 WoodenBarrel - 204 ExplosiveBarrel2 - 205 TargetPractice - 206 LightSilverFluorescent - 207 LightBrownFluorescent - 208 LightGoldFluorescent - 209 LightGlobe - 210 PillarTechno - 211 PillarAztec - 212 PillarAztecDamaged - 213 PillarAztecRuined - 214 PillarHugeTech - 215 PillarAlienPower - 216 SStalactiteBig - 217 SStalactiteSmall - 218 SStalagmiteBig - 219 CavePillarTop - 220 CavePillarBottom - 221 SStalagmiteSmall - 222 Candle - 223 StrifeCandelabra - 224 WaterDropOnFloor - 225 WaterfallSplash - 226 WaterDrip - 227 WaterFountain - 228 HeartsInTank - 229 TeleportSwirl - 230 DeadCrusader - 231 DeadStrifePlayer - 232 DeadPeasant - 233 DeadAcolyte - 234 DeadReaver - 235 DeadRebel - 236 SacrificedGuy - 237 PileOfGuts - 238 StrifeBurningBarrel - 239 BurningBowl - 240 BurningBrazier - 241 SmallTorchLit - 242 SmallTorchUnlit - 243 CeilingChain - 244 CageLight - 245 Statue - 246 StatueRuined - 247 MediumTorch - 248 OutsideLamp - 249 PoleLantern - 250 SRock1 - 251 SRock2 - 252 SRock3 - 253 SRock4 - 254 StickInWater - 255 Rubble1 - 256 Rubble2 - 257 Rubble3 - 258 Rubble4 - 259 Rubble5 - 260 Rubble6 - 261 Rubble7 - 262 Rubble8 - 263 SurgeryCrab - 264 LargeTorch - 265 HugeTorch - 266 PalmTree - 267 BigTree2 - 268 PottedTree - 269 TreeStub - 270 ShortBush - 271 TallBush - 272 ChimneyStack - 273 BarricadeColumn - 274 Pot - 275 Pitcher - 276 Stool - 277 MetalPot - 278 Tub - 279 Anvil - 280 TechLampSilver - 281 TechLampBrass - 282 Tray - 283 AmmoFiller - 284 SigilBanner - 285 RebelBoots - 286 RebelHelmet - 287 RebelShirt - 288 PowerCoupling - 289 BrokenPowerCoupling - 290 AlienBubbleColumn - 291 AlienFloorBubble - 292 AlienCeilingBubble - 293 AlienAspClimber - 294 AlienSpiderLight - 295 Meat - 296 Junk - 297 FireDroplet - 298 AmmoFillup - 299 HealthFillup - 300 Info - 301 RaiseAlarm - 302 OpenDoor222 - 303 CloseDoor222 - 304 PrisonPass - 305 OpenDoor224 - 306 UpgradeStamina - 307 UpgradeAccuracy - 308 InterrogatorReport (seems to be unused) - 309 HealthTraining - 310 GunTraining - 311 OraclePass - 312 QuestItem1 - 313 QuestItem2 - 314 QuestItem3 - 315 QuestItem4 - 316 QuestItem5 - 317 QuestItem6 - 318 QuestItem7 - 319 QuestItem8 - 320 QuestItem9 - 321 QuestItem10 - 322 QuestItem11 - 323 QuestItem12 - 324 QuestItem13 - 325 QuestItem14 - 326 QuestItem15 - 327 QuestItem16 - 328 QuestItem17 - 329 QuestItem18 - 330 QuestItem19 - 331 QuestItem20 - 332 QuestItem21 - 333 QuestItem22 - 334 QuestItem23 - 335 QuestItem24 - 336 QuestItem25 - 337 QuestItem26 - 338 QuestItem27 - 339 QuestItem28 - 340 QuestItem29 - 341 QuestItem30 - 342 QuestItem31 - 343 SlideshowStarter -*/ - static FRandom pr_gibtosser ("GibTosser"); // Force Field Guard -------------------------------------------------------- @@ -438,7 +90,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetShadow) self->flags |= MF_STRIFEx8000000|MF_SHADOW; self->RenderStyle = STYLE_Translucent; - self->alpha = HR_SHADOW; + self->Alpha = HR_SHADOW; return 0; } @@ -448,7 +100,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearShadow) self->flags &= ~(MF_STRIFEx8000000|MF_SHADOW); self->RenderStyle = STYLE_Normal; - self->alpha = OPAQUE; + self->Alpha = 1.; return 0; } @@ -564,8 +216,8 @@ void APowerCoupling::Die (AActor *source, AActor *inflictor, int dmgflags) { P_NoiseAlert (source, this); } - EV_DoDoor (DDoor::doorClose, NULL, players[i].mo, 225, 2*FRACUNIT, 0, 0, 0); - EV_DoFloor (DFloor::floorLowerToHighest, NULL, 44, FRACUNIT, 0, -1, 0, false); + EV_DoDoor (DDoor::doorClose, NULL, players[i].mo, 225, 2., 0, 0, 0); + EV_DoFloor (DFloor::floorLowerToHighest, NULL, 44, 1., 0., -1, 0, false); players[i].mo->GiveInventoryType (QuestItemClasses[5]); S_Sound (CHAN_VOICE, "svox/voc13", 1, ATTN_NORM); players[i].SetLogNumber (13); @@ -599,21 +251,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_TossGib) PARAM_ACTION_PROLOGUE; const char *gibtype = (self->flags & MF_NOBLOOD) ? "Junk" : "Meat"; - AActor *gib = Spawn (gibtype, self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE); - angle_t an; - int speed; + AActor *gib = Spawn (gibtype, self->PosPlusZ(24.), ALLOW_REPLACE); if (gib == NULL) { return 0; } - an = pr_gibtosser() << 24; - gib->angle = an; - speed = pr_gibtosser() & 15; - gib->vel.x = speed * finecosine[an >> ANGLETOFINESHIFT]; - gib->vel.y = speed * finesine[an >> ANGLETOFINESHIFT]; - gib->vel.z = (pr_gibtosser() & 15) << FRACBITS; + gib->Angles.Yaw = pr_gibtosser() * (360 / 256.f); + gib->VelFromAngle(pr_gibtosser() & 15); + gib->Vel.Z = pr_gibtosser() & 15; return 0; } @@ -668,11 +315,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain) else if (sec->special == Scroll_StrifeCurrent) { int anglespeed = tagManager.GetFirstSectorTag(sec) - 100; - fixed_t speed = (anglespeed % 10) << (FRACBITS - 4); - angle_t finean = (anglespeed / 10) << (32-3); - finean >>= ANGLETOFINESHIFT; - self->vel.x += FixedMul (speed, finecosine[finean]); - self->vel.y += FixedMul (speed, finesine[finean]); + double speed = (anglespeed % 10) / 16.; + DAngle an = (anglespeed / 10) * (360 / 8.); + self->VelFromAngle(an, speed); } } return 0; @@ -721,8 +366,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DropFire) { PARAM_ACTION_PROLOGUE; - AActor *drop = Spawn("FireDroplet", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE); - drop->vel.z = -FRACUNIT; + AActor *drop = Spawn("FireDroplet", self->PosPlusZ(24.), ALLOW_REPLACE); + drop->Vel.Z = -1.; P_RadiusAttack (self, self, 64, 64, NAME_Fire, 0); return 0; } @@ -748,7 +393,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_HandLower) if (self->player != NULL) { pspdef_t *psp = &self->player->psprites[ps_weapon]; - psp->sy += FRACUNIT*9; + psp->sy += 9; if (psp->sy > WEAPONBOTTOM*2) { P_SetPsprite (self->player, ps_weapon, NULL); diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 90a934b82..96d53d431 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -96,9 +96,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int pitch; + DAngle pitch; int power; FTranslatedLineTarget t; @@ -110,9 +110,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger) damage *= 10; } - angle = self->angle + (pr_jabdagger.Random2() << 18); - pitch = P_AimLineAttack (self, angle, 80*FRACUNIT); - P_LineAttack (self, angle, 80*FRACUNIT, pitch, damage, NAME_Melee, "StrifeSpark", true, &t); + angle = self->Angles.Yaw + pr_jabdagger.Random2() * (5.625 / 256); + pitch = P_AimLineAttack (self, angle, 80.); + P_LineAttack (self, angle, 80., pitch, damage, NAME_Melee, "StrifeSpark", true, &t); // turn to face target if (t.linetarget) @@ -120,7 +120,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger) S_Sound (self, CHAN_WEAPON, t.linetarget->flags & MF_NOBLOOD ? "misc/metalhit" : "misc/meathit", 1, ATTN_NORM); - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; self->flags |= MF_JUSTATTACKED; P_DaggerAlert (self, t.linetarget); } @@ -147,7 +147,7 @@ enum DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_AlertMonsters) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED_OPT(maxdist) { maxdist = 0; } + PARAM_FLOAT_OPT(maxdist) { maxdist = 0; } PARAM_INT_OPT(Flags) { Flags = 0; } AActor * target = NULL; @@ -251,7 +251,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow) PARAM_ACTION_PROLOGUE; PARAM_CLASS(ti, AActor); - angle_t savedangle; + DAngle savedangle; if (self->player == NULL) return 0; @@ -265,11 +265,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow) if (ti) { - savedangle = self->angle; - self->angle += pr_electric.Random2 () << (18 - self->player->mo->accuracy * 5 / 100); + savedangle = self->Angles.Yaw; + self->Angles.Yaw += pr_electric.Random2() * (5.625/256) * self->player->mo->AccuracyFactor(); self->player->mo->PlayAttacking2 (); P_SpawnPlayerMissile (self, ti); - self->angle = savedangle; + self->Angles.Yaw = savedangle; S_Sound (self, CHAN_WEAPON, "weapons/xbowshoot", 1, ATTN_NORM); } return 0; @@ -283,17 +283,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow) // //============================================================================ -void P_StrifeGunShot (AActor *mo, bool accurate, angle_t pitch) +void P_StrifeGunShot (AActor *mo, bool accurate, DAngle pitch) { - angle_t angle; + DAngle angle; int damage; damage = 4*(pr_sgunshot()%3+1); - angle = mo->angle; + angle = mo->Angles.Yaw; if (mo->player != NULL && !accurate) { - angle += pr_sgunshot.Random2() << (20 - mo->player->mo->accuracy * 5 / 100); + angle += pr_sgunshot.Random2() * (22.5 / 256) * mo->player->mo->AccuracyFactor(); } P_LineAttack (mo, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, NAME_StrifePuff); @@ -346,7 +346,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMiniMissile) PARAM_ACTION_PROLOGUE; player_t *player = self->player; - angle_t savedangle; + DAngle savedangle; if (self->player == NULL) return 0; @@ -358,11 +358,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMiniMissile) return 0; } - savedangle = self->angle; - self->angle += pr_minimissile.Random2() << (19 - player->mo->accuracy * 5 / 100); + savedangle = self->Angles.Yaw; + self->Angles.Yaw += pr_minimissile.Random2() * (11.25 / 256) * player->mo->AccuracyFactor(); player->mo->PlayAttacking2 (); P_SpawnPlayerMissile (self, PClass::FindActor("MiniMissile")); - self->angle = savedangle; + self->Angles.Yaw = savedangle; return 0; } @@ -379,11 +379,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_RocketInFlight) AActor *trail; S_Sound (self, CHAN_VOICE, "misc/missileinflight", 1, ATTN_NORM); - P_SpawnPuff (self, PClass::FindActor("MiniMissilePuff"), self->Pos(), self->angle - ANGLE_180, 2, PF_HITTHING); - trail = Spawn("RocketTrail", self->Vec3Offset(-self->vel.x, -self->vel.y, 0), ALLOW_REPLACE); + P_SpawnPuff (self, PClass::FindActor("MiniMissilePuff"), self->Pos(), self->Angles.Yaw - 180, self->Angles.Yaw - 180, 2, PF_HITTHING); + trail = Spawn("RocketTrail", self->Vec3Offset(-self->Vel.X, -self->Vel.Y, 0.), ALLOW_REPLACE); if (trail != NULL) { - trail->vel.z = FRACUNIT; + trail->Vel.Z = 1; } return 0; } @@ -401,7 +401,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlameDie) PARAM_ACTION_PROLOGUE; self->flags |= MF_NOGRAVITY; - self->vel.z = (pr_flamedie() & 3) << FRACBITS; + self->Vel.Z = pr_flamedie() & 3; return 0; } @@ -428,11 +428,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireFlamer) player->mo->PlayAttacking2 (); } - self->angle += pr_flamethrower.Random2() << 18; + self->Angles.Yaw += pr_flamethrower.Random2() * (5.625/256.); self = P_SpawnPlayerMissile (self, PClass::FindActor("FlameMissile")); if (self != NULL) { - self->vel.z += 5*FRACUNIT; + self->Vel.Z += 5; } return 0; } @@ -467,13 +467,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler1) S_Sound (self, CHAN_WEAPON, "weapons/mauler1", 1, ATTN_NORM); - int bpitch = P_BulletSlope (self); + DAngle bpitch = P_BulletSlope (self); for (int i = 0; i < 20; ++i) { int damage = 5 * (pr_mauler1() % 3 + 1); - angle_t angle = self->angle + (pr_mauler1.Random2() << 19); - int pitch = bpitch + (pr_mauler1.Random2() * 332063); + DAngle angle = self->Angles.Yaw + pr_mauler1.Random2() * (11.25 / 256); + DAngle pitch = bpitch + pr_mauler1.Random2() * (7.097 / 256); // Strife used a range of 2112 units for the mauler to signal that // it should use a different puff. ZDoom's default range is longer @@ -500,8 +500,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler2Pre) if (self->player != NULL) { - self->player->psprites[ps_weapon].sx += pr_mauler2.Random2() << 10; - self->player->psprites[ps_weapon].sy += pr_mauler2.Random2() << 10; + self->player->psprites[ps_weapon].sx += pr_mauler2.Random2() / 64.; + self->player->psprites[ps_weapon].sy += pr_mauler2.Random2() / 64.; } return 0; } @@ -530,7 +530,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler2) } P_SpawnPlayerMissile (self, PClass::FindActor("MaulerTorpedo")); P_DamageMobj (self, self, NULL, 20, self->DamageType); - P_ThrustMobj (self, self->angle + ANGLE_180, 0x7D000); + self->Thrust(self->Angles.Yaw+180., 7.8125); return 0; } @@ -547,19 +547,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaulerTorpedoWave) PARAM_ACTION_PROLOGUE; AActor *wavedef = GetDefaultByName("MaulerTorpedoWave"); - fixed_t savedz; - self->angle += ANGLE_180; + double savedz; + self->Angles.Yaw += 180.; // If the torpedo hit the ceiling, it should still spawn the wave savedz = self->Z(); - if (wavedef && self->ceilingz - self->Z() < wavedef->height) + if (wavedef && self->ceilingz < wavedef->Top()) { - self->SetZ(self->ceilingz - wavedef->height); + self->SetZ(self->ceilingz - wavedef->Height); } for (int i = 0; i < 80; ++i) { - self->angle += ANGLE_45/10; + self->Angles.Yaw += 4.5; P_SpawnSubMissile (self, PClass::FindActor("MaulerTorpedoWave"), self->target); } self->SetZ(savedz); @@ -576,10 +576,8 @@ AActor *P_SpawnSubMissile (AActor *source, PClassActor *type, AActor *target) } other->target = target; - other->angle = source->angle; - - other->vel.x = FixedMul (other->Speed, finecosine[source->angle >> ANGLETOFINESHIFT]); - other->vel.y = FixedMul (other->Speed, finesine[source->angle >> ANGLETOFINESHIFT]); + other->Angles.Yaw = source->Angles.Yaw; + other->VelFromAngle(); if (other->flags4 & MF4_SPECTRAL) { @@ -595,8 +593,8 @@ AActor *P_SpawnSubMissile (AActor *source, PClassActor *type, AActor *target) if (P_CheckMissileSpawn (other, source->radius)) { - angle_t pitch = P_AimLineAttack (source, source->angle, 1024*FRACUNIT); - other->vel.z = FixedMul (-finesine[pitch>>ANGLETOFINESHIFT], other->Speed); + DAngle pitch = P_AimLineAttack (source, source->Angles.Yaw, 1024.); + other->Vel.Z = -other->Speed * pitch.Sin(); return other; } return NULL; @@ -632,16 +630,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_Burnination) { PARAM_ACTION_PROLOGUE; - self->vel.z -= 8*FRACUNIT; - self->vel.x += (pr_phburn.Random2 (3)) << FRACBITS; - self->vel.y += (pr_phburn.Random2 (3)) << FRACBITS; + self->Vel.Z -= 8; + self->Vel.X += (pr_phburn.Random2 (3)); + self->Vel.Y += (pr_phburn.Random2 (3)); S_Sound (self, CHAN_VOICE, "world/largefire", 1, ATTN_NORM); // Only the main fire spawns more. if (!(self->flags & MF_DROPPED)) { // Original x and y offsets seemed to be like this: - // x + (((pr_phburn() + 12) & 31) << FRACBITS); + // x + (((pr_phburn() + 12) & 31) << F.RACBITS); // // But that creates a lop-sided burn because it won't use negative offsets. int xofs, xrand = pr_phburn(); @@ -660,24 +658,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_Burnination) yofs = -yofs; } - fixedvec2 pos = self->Vec2Offset(xofs << FRACBITS, yofs << FRACBITS); - sector_t * sector = P_PointInSector(pos.x, pos.y); + DVector2 pos = self->Vec2Offset((double)xofs, (double)yofs); + sector_t * sector = P_PointInSector(pos); // The sector's floor is too high so spawn the flame elsewhere. - if (sector->floorplane.ZatPoint(pos.x, pos.y) > self->Z() + self->MaxStepHeight) + if (sector->floorplane.ZatPoint(pos) > self->Z() + self->MaxStepHeight) { - pos.x = self->X(); - pos.y = self->Y(); + pos = self->Pos(); } - AActor *drop = Spawn ( - pos.x, pos.y, - self->Z() + 4*FRACUNIT, ALLOW_REPLACE); + AActor *drop = Spawn (DVector3(pos, self->Z() + 4.), ALLOW_REPLACE); if (drop != NULL) { - drop->vel.x = self->vel.x + ((pr_phburn.Random2 (7)) << FRACBITS); - drop->vel.y = self->vel.y + ((pr_phburn.Random2 (7)) << FRACBITS); - drop->vel.z = self->vel.z - FRACUNIT; + drop->Vel.X = self->Vel.X + pr_phburn.Random2 (7); + drop->Vel.Y = self->Vel.Y + pr_phburn.Random2 (7); + drop->Vel.Z = self->Vel.Z - 1; drop->reactiontime = (pr_phburn() & 3) + 2; drop->flags |= MF_DROPPED; } @@ -700,8 +695,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) player_t *player = self->player; AActor *grenade; - angle_t an; - fixed_t tworadii; + DAngle an; AWeapon *weapon; if (player == NULL || grenadetype == NULL) @@ -718,9 +712,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) if (grenadetype != NULL) { - self->AddZ(32*FRACUNIT); + self->AddZ(32); grenade = P_SpawnSubMissile (self, grenadetype, self); - self->AddZ(-32*FRACUNIT); + self->AddZ(-32); if (grenade == NULL) return 0; @@ -729,22 +723,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) S_Sound (grenade, CHAN_VOICE, grenade->SeeSound, 1, ATTN_NORM); } - grenade->vel.z = FixedMul (finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)], grenade->Speed) + 8*FRACUNIT; + grenade->Vel.Z = (-self->Angles.Pitch.TanClamped()) * grenade->Speed + 8; - fixedvec2 offset; - - an = self->angle >> ANGLETOFINESHIFT; - tworadii = self->radius + grenade->radius; - offset.x = FixedMul (finecosine[an], tworadii); - offset.y = FixedMul (finesine[an], tworadii); - - an = self->angle + angleofs; - an >>= ANGLETOFINESHIFT; - offset.x += FixedMul (finecosine[an], 15*FRACUNIT); - offset.y += FixedMul (finesine[an], 15*FRACUNIT); - - fixedvec2 newpos = grenade->Vec2Offset(offset.x, offset.y); - grenade->SetOrigin(newpos.x, newpos.y, grenade->Z(), false); + DVector2 offset = self->Angles.Yaw.ToVector(self->radius + grenade->radius); + DAngle an = self->Angles.Yaw + angleofs; + offset += an.ToVector(15); + grenade->SetOrigin(grenade->Vec3Offset(offset.X, offset.Y, 0.), false); } return 0; } @@ -817,7 +801,7 @@ bool ASigil::HandlePickup (AInventory *item) AInventory *ASigil::CreateCopy (AActor *other) { - ASigil *copy = Spawn (0,0,0, NO_REPLACE); + ASigil *copy = Spawn (); copy->Amount = Amount; copy->MaxAmount = MaxAmount; copy->NumPieces = NumPieces; @@ -990,7 +974,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil1) P_BulletSlope (self, &t, ALF_PORTALRESTRICT); if (t.linetarget != NULL) { - spot = Spawn("SpectralLightningSpot", t.linetarget->X(), t.linetarget->Y(), t.linetarget->floorz, ALLOW_REPLACE); + spot = Spawn("SpectralLightningSpot", t.linetarget->PosAtZ(t.linetarget->floorz), ALLOW_REPLACE); if (spot != NULL) { spot->tracer = t.linetarget; @@ -1001,8 +985,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil1) spot = Spawn("SpectralLightningSpot", self->Pos(), ALLOW_REPLACE); if (spot != NULL) { - spot->vel.x += 28 * finecosine[self->angle >> ANGLETOFINESHIFT]; - spot->vel.y += 28 * finesine[self->angle >> ANGLETOFINESHIFT]; + spot->VelFromAngle(self->Angles.Yaw, 28.); } } if (spot != NULL) @@ -1055,17 +1038,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil3) P_DamageMobj (self, self, NULL, 3*4, 0, DMG_NO_ARMOR); S_Sound (self, CHAN_WEAPON, "weapons/sigilcharge", 1, ATTN_NORM); - self->angle -= ANGLE_90; + self->Angles.Yaw -= 90.; for (i = 0; i < 20; ++i) { - self->angle += ANGLE_180/20; + self->Angles.Yaw += 9.; spot = P_SpawnSubMissile (self, PClass::FindActor("SpectralLightningBall1"), self); if (spot != NULL) { - spot->SetZ(self->Z() + 32*FRACUNIT); + spot->SetZ(self->Z() + 32); } } - self->angle -= (ANGLE_180/20)*10; + self->Angles.Yaw -= 90.; return 0; } @@ -1092,7 +1075,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil4) P_BulletSlope (self, &t, ALF_PORTALRESTRICT); if (t.linetarget != NULL) { - spot = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("SpectralLightningBigV1"), self->angle, &t, NULL, false, false, ALF_PORTALRESTRICT); + spot = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("SpectralLightningBigV1"), self->Angles.Yaw, &t, NULL, false, false, ALF_PORTALRESTRICT); if (spot != NULL) { spot->tracer = t.linetarget; @@ -1103,8 +1086,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil4) spot = P_SpawnPlayerMissile (self, PClass::FindActor("SpectralLightningBigV1")); if (spot != NULL) { - spot->vel.x += FixedMul (spot->Speed, finecosine[self->angle >> ANGLETOFINESHIFT]); - spot->vel.y += FixedMul (spot->Speed, finesine[self->angle >> ANGLETOFINESHIFT]); + spot->VelFromAngle(self->Angles.Yaw, spot->Speed); } } return 0; @@ -1172,7 +1154,7 @@ int ASigil::GiveSigilPiece (AActor *receiver) sigil = receiver->FindInventory (); if (sigil == NULL) { - sigil = static_cast(Spawn("Sigil1", 0,0,0, NO_REPLACE)); + sigil = static_cast(Spawn("Sigil1")); if (!sigil->CallTryPickup (receiver)) { sigil->Destroy (); diff --git a/src/g_strife/a_templar.cpp b/src/g_strife/a_templar.cpp index 554ca141d..547d4d73e 100644 --- a/src/g_strife/a_templar.cpp +++ b/src/g_strife/a_templar.cpp @@ -16,23 +16,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_TemplarAttack) PARAM_ACTION_PROLOGUE; int damage; - angle_t angle; - int pitch; - int pitchdiff; + DAngle angle; + DAngle pitch; if (self->target == NULL) return 0; S_Sound (self, CHAN_WEAPON, "templar/shoot", 1, ATTN_NORM); A_FaceTarget (self); - pitch = P_AimLineAttack (self, self->angle, MISSILERANGE); + pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); for (int i = 0; i < 10; ++i) { damage = (pr_templar() & 4) * 2; - angle = self->angle + (pr_templar.Random2() << 19); - pitchdiff = pr_templar.Random2() * 332063; - P_LineAttack (self, angle, MISSILERANGE+64*FRACUNIT, pitch+pitchdiff, damage, NAME_Hitscan, NAME_MaulerPuff); + angle = self->Angles.Yaw + pr_templar.Random2() * (11.25 / 256); + P_LineAttack (self, angle, MISSILERANGE+64., pitch + pr_templar.Random2() * (7.097 / 256), damage, NAME_Hitscan, NAME_MaulerPuff); } return 0; } diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp index 55b00e6b9..3644bb54c 100644 --- a/src/g_strife/a_thingstoblowup.cpp +++ b/src/g_strife/a_thingstoblowup.cpp @@ -18,9 +18,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Bang4Cloud) { PARAM_ACTION_PROLOGUE; - fixed_t xo = (pr_bang4cloud.Random2() & 3) * 10240; - fixed_t yo = (pr_bang4cloud.Random2() & 3) * 10240; - Spawn("Bang4Cloud", self->Vec3Offset(xo, yo, 0), ALLOW_REPLACE); + double xo = (pr_bang4cloud.Random2() & 3) * (10. / 64); + double yo = (pr_bang4cloud.Random2() & 3) * (10. / 64); + Spawn("Bang4Cloud", self->Vec3Offset(xo, yo, 0.), ALLOW_REPLACE); return 0; } @@ -38,7 +38,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveQuestItem) { if (playeringame[i]) { - AInventory *item = static_cast(Spawn (QuestItemClasses[questitem - 1], 0,0,0, NO_REPLACE)); + AInventory *item = static_cast(Spawn (QuestItemClasses[questitem - 1])); if (!item->CallTryPickup (players[i].mo)) { item->Destroy (); @@ -81,7 +81,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Explode512) { self->target->player->extralight = 5; } - P_CheckSplash(self, 512<RenderStyle = STYLE_Add; @@ -95,14 +95,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightGoesOut) AActor *foo; sector_t *sec = self->Sector; vertex_t *spot; - fixed_t newheight; + double newheight; sec->SetLightLevel(0); - fixed_t oldtheight = sec->floorplane.Zat0(); + double oldtheight = sec->floorplane.fD(); newheight = sec->FindLowestFloorSurrounding(&spot); - sec->floorplane.d = sec->floorplane.PointToDist (spot, newheight); - fixed_t newtheight = sec->floorplane.Zat0(); + sec->floorplane.setD(sec->floorplane.PointToDist (spot, newheight)); + double newtheight = sec->floorplane.fD(); sec->ChangePlaneTexZ(sector_t::floor, newtheight - oldtheight); sec->CheckPortalPlane(sector_t::floor); @@ -112,9 +112,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightGoesOut) if (foo != NULL) { int t = pr_lightout() & 15; - foo->vel.x = (t - (pr_lightout() & 7)) << FRACBITS; - foo->vel.y = (pr_lightout.Random2() & 7) << FRACBITS; - foo->vel.z = (7 + (pr_lightout() & 3)) << FRACBITS; + foo->Vel.X = t - (pr_lightout() & 7); + foo->Vel.Y = pr_lightout.Random2() & 7; + foo->Vel.Z = 7 + (pr_lightout() & 3); } } return 0; diff --git a/src/g_strife/strife_sbar.cpp b/src/g_strife/strife_sbar.cpp index 2257ee268..bcdf624d7 100644 --- a/src/g_strife/strife_sbar.cpp +++ b/src/g_strife/strife_sbar.cpp @@ -327,7 +327,7 @@ private: if (ItemFlash > 0) { - ItemFlash -= FRACUNIT/14; + ItemFlash -= 1/14.; if (ItemFlash < 0) { ItemFlash = 0; @@ -379,7 +379,7 @@ private: void FlashItem (const PClass *itemtype) { - ItemFlash = FRACUNIT*3/4; + ItemFlash = 0.75; } void DrawMainBar () @@ -454,7 +454,7 @@ private: screen->DrawTexture (Images[CursorImage], 42 + 35*i + ST_X, 12 + ST_Y, DTA_Bottom320x200, Scaled, - DTA_Alpha, FRACUNIT - ItemFlash, + DTA_AlphaF, 1. - ItemFlash, TAG_DONE); } if (item->Icon.isValid()) @@ -526,7 +526,7 @@ private: DTA_HUDRules, HUD_Normal, DTA_LeftOffset, cursor->GetWidth(), DTA_TopOffset, cursor->GetHeight(), - DTA_Alpha, ItemFlash, + DTA_AlphaF, ItemFlash, TAG_DONE); } DrINumberOuter (CPlayer->mo->InvSel->Amount, -51, -10, false, 7); @@ -576,14 +576,14 @@ private: int bars = (CurrentPop == POP_Status) ? imgINVPOP : imgINVPOP2; int back = (CurrentPop == POP_Status) ? imgINVPBAK : imgINVPBAK2; // Extrapolate the height of the popscreen for smoother movement - int height = clamp (PopHeight + FixedMul (r_TicFrac, PopHeightChange), -POP_HEIGHT, 0); + int height = clamp (PopHeight + int(r_TicFracF * PopHeightChange), -POP_HEIGHT, 0); xscale = CleanXfac; yscale = CleanYfac; left = screen->GetWidth()/2 - 160*CleanXfac; top = bottom + height * yscale; - screen->DrawTexture (Images[back], left, top, DTA_CleanNoMove, true, DTA_Alpha, FRACUNIT*3/4, TAG_DONE); + screen->DrawTexture (Images[back], left, top, DTA_CleanNoMove, true, DTA_AlphaF, 0.75, TAG_DONE); screen->DrawTexture (Images[bars], left, top, DTA_CleanNoMove, true, TAG_DONE); @@ -627,7 +627,7 @@ private: if (KeyPopScroll > 0) { // Extrapolate the scroll position for smoother scrolling - int scroll = MAX (0,KeyPopScroll - FixedMul (r_TicFrac, 280/KEY_TIME)); + int scroll = MAX (0,KeyPopScroll - int(r_TicFracF * (280./KEY_TIME))); pos -= 10; leftcol = leftcol - 280 + scroll; } @@ -847,7 +847,7 @@ private: int CursorImage; int CurrentPop, PendingPop, PopHeight, PopHeightChange; int KeyPopPos, KeyPopScroll; - fixed_t ItemFlash; + double ItemFlash; }; IMPLEMENT_CLASS(DStrifeStatusBar); diff --git a/src/gi.cpp b/src/gi.cpp index 405e42ce7..313df4f0b 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -133,11 +133,11 @@ const char* GameInfoBorders[] = gameinfo.key = static_cast (sc.Float); \ } -#define GAMEINFOKEY_FIXED(key, variable) \ +#define GAMEINFOKEY_DOUBLE(key, variable) \ else if(nextKey.CompareNoCase(variable) == 0) \ { \ sc.MustGetFloat(); \ - gameinfo.key = static_cast (sc.Float*FRACUNIT); \ + gameinfo.key = sc.Float; \ } #define GAMEINFOKEY_COLOR(key, variable) \ @@ -272,7 +272,7 @@ void FMapInfoParser::ParseGameInfo() if (sc.CheckToken(',')) { sc.MustGetToken(TK_FloatConst); - gameinfo.Armor2Percent = FLOAT2FIXED(sc.Float); + gameinfo.Armor2Percent = sc.Float; sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); gameinfo.ArmorIcon2 = sc.String; @@ -310,8 +310,8 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_STRING(PauseSign, "pausesign") GAMEINFOKEY_STRING(quitSound, "quitSound") GAMEINFOKEY_STRING(BorderFlat, "borderFlat") - GAMEINFOKEY_FIXED(telefogheight, "telefogheight") - GAMEINFOKEY_FIXED(gibfactor, "gibfactor") + GAMEINFOKEY_DOUBLE(telefogheight, "telefogheight") + GAMEINFOKEY_DOUBLE(gibfactor, "gibfactor") GAMEINFOKEY_INT(defKickback, "defKickback") GAMEINFOKEY_STRING(SkyFlatName, "SkyFlatName") GAMEINFOKEY_STRING(translator, "translator") diff --git a/src/gi.h b/src/gi.h index 8bdfc7e3e..2786b3425 100644 --- a/src/gi.h +++ b/src/gi.h @@ -135,10 +135,10 @@ struct gameinfo_t FString ArmorIcon2; FString PauseSign; FString Endoom; - fixed_t Armor2Percent; + double Armor2Percent; FString quitSound; gameborder_t Border; - int telefogheight; + double telefogheight; int defKickback; FString translator; DWORD defaultbloodcolor; @@ -163,7 +163,7 @@ struct gameinfo_t FName mFontColorHighlight; FName mFontColorSelection; FString mBackButton; - fixed_t gibfactor; + double gibfactor; int TextScreenX; int TextScreenY; FName DefaultEndSequence; diff --git a/src/info.cpp b/src/info.cpp index 40a600884..e997d9717 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -229,9 +229,9 @@ PClassActor::PClassActor() GibHealth = INT_MIN; WoundHealth = 6; PoisonDamage = 0; - FastSpeed = FIXED_MIN; - RDFactor = FRACUNIT; - CameraHeight = FIXED_MIN; + FastSpeed = -1.; + RDFactor = 1.; + CameraHeight = INT_MIN; DropItems = NULL; @@ -532,7 +532,7 @@ PClassActor *PClassActor::GetReplacee(bool lookskill) // //========================================================================== -void PClassActor::SetDamageFactor(FName type, fixed_t factor) +void PClassActor::SetDamageFactor(FName type, double factor) { if (DamageFactors == NULL) { @@ -593,16 +593,18 @@ void PClassActor::ReplaceClassRef(PClass *oldclass, PClass *newclass) // //========================================================================== -fixed_t *DmgFactors::CheckFactor(FName type) +int DmgFactors::Apply(FName type, int damage) { - fixed_t *pdf = CheckKey(type); + auto pdf = CheckKey(type); if (pdf == NULL && type != NAME_None) { pdf = CheckKey(NAME_None); } - return pdf; + if (!pdf) return damage; + return int(damage * *pdf); } + static void SummonActor (int command, int command2, FCommandLine argv) { if (CheckCheatmode ()) @@ -689,32 +691,33 @@ bool DamageTypeDefinition::IgnoreArmor(FName type) // //========================================================================== -int DamageTypeDefinition::ApplyMobjDamageFactor(int damage, FName type, DmgFactors const * const factors) +double DamageTypeDefinition::GetMobjDamageFactor(FName type, DmgFactors const * const factors) { if (factors) { // If the actor has named damage factors, look for a specific factor - fixed_t const *pdf = factors->CheckKey(type); - if (pdf) return FixedMul(damage, *pdf); // type specific damage type + + auto pdf = factors->CheckKey(type); + if (pdf) return *pdf; // type specific damage type // If this was nonspecific damage, don't fall back to nonspecific search - if (type == NAME_None) return damage; + if (type == NAME_None) return 1.; } // If this was nonspecific damage, don't fall back to nonspecific search else if (type == NAME_None) { - return damage; + return 1.; } else { // Normal is unsupplied / 1.0, so there's no difference between modifying and overriding DamageTypeDefinition *dtd = Get(type); - return dtd ? FixedMul(damage, dtd->DefaultFactor) : damage; + return dtd ? dtd->DefaultFactor : 1.; } { - fixed_t const *pdf = factors->CheckKey(NAME_None); + auto pdf = factors->CheckKey(NAME_None); DamageTypeDefinition *dtd = Get(type); // Here we are looking for modifications to untyped damage // If the calling actor defines untyped damage factor, that is contained in "pdf". @@ -722,15 +725,21 @@ int DamageTypeDefinition::ApplyMobjDamageFactor(int damage, FName type, DmgFacto { if (dtd) { - if (dtd->ReplaceFactor) return FixedMul(damage, dtd->DefaultFactor); // use default instead of untyped factor - return FixedMul(damage, FixedMul(*pdf, dtd->DefaultFactor)); // use default as modification of untyped factor + if (dtd->ReplaceFactor) return dtd->DefaultFactor; // use default instead of untyped factor + return *pdf * dtd->DefaultFactor; // use default as modification of untyped factor } - return FixedMul(damage, *pdf); // there was no default, so actor default is used + return *pdf; // there was no default, so actor default is used } else if (dtd) { - return FixedMul(damage, dtd->DefaultFactor); // implicit untyped factor 1.0 does not need to be applied/replaced explicitly + return dtd->DefaultFactor; // implicit untyped factor 1.0 does not need to be applied/replaced explicitly } } - return damage; + return 1.; +} + +int DamageTypeDefinition::ApplyMobjDamageFactor(int damage, FName type, DmgFactors const * const factors) +{ + double factor = GetMobjDamageFactor(type, factors); + return int(damage * factor); } diff --git a/src/info.h b/src/info.h index 1f2537d47..decfd72df 100644 --- a/src/info.h +++ b/src/info.h @@ -37,7 +37,7 @@ #include #if !defined(_WIN32) #include // for intptr_t -#elif !defined(_MSC_VER) +#else #include // for mingw #endif @@ -158,9 +158,9 @@ FArchive &operator<< (FArchive &arc, FState *&state); #include "gametype.h" -struct DmgFactors : public TMap +struct DmgFactors : public TMap { - fixed_t *CheckFactor(FName type); + int Apply(FName type, int damage); }; typedef TMap PainChanceList; @@ -169,20 +169,21 @@ struct DamageTypeDefinition public: DamageTypeDefinition() { Clear(); } - fixed_t DefaultFactor; + double DefaultFactor; bool ReplaceFactor; bool NoArmor; void Apply(FName type); void Clear() { - DefaultFactor = FRACUNIT; + DefaultFactor = 1.; ReplaceFactor = false; NoArmor = false; } static DamageTypeDefinition *Get(FName type); static bool IgnoreArmor(FName type); + static double GetMobjDamageFactor(FName type, DmgFactors const * const factors); static int ApplyMobjDamageFactor(int damage, FName type, DmgFactors const * const factors); }; @@ -206,7 +207,7 @@ public: void BuildDefaults(); void ApplyDefaults(BYTE *defaults); void RegisterIDs(); - void SetDamageFactor(FName type, fixed_t factor); + void SetDamageFactor(FName type, double factor); void SetPainChance(FName type, int chance); size_t PropagateMark(); void InitializeNativeDefaults(); @@ -242,15 +243,15 @@ public: FString Obituary; // Player was killed by this actor FString HitObituary; // Player was killed by this actor in melee - fixed_t DeathHeight; // Height on normal death - fixed_t BurnHeight; // Height on burning death + double DeathHeight; // Height on normal death + double BurnHeight; // Height on burning death PalEntry BloodColor; // Colorized blood int GibHealth; // Negative health below which this monster dies an extreme death int WoundHealth; // Health needed to enter wound state int PoisonDamage; // Amount of poison damage - fixed_t FastSpeed; // Speed in fast mode - fixed_t RDFactor; // Radius damage factor - fixed_t CameraHeight; // Height of camera when used as such + double FastSpeed; // speed in fast mode + double RDFactor; // Radius damage factor + double CameraHeight; // Height of camera when used as such FSoundID HowlSound; // Sound being played when electrocuted or poisoned FName BloodType; // Blood replacement type FName BloodType2; // Bloopsplatter replacement type @@ -266,7 +267,7 @@ public: int MeleeDamage; FSoundID MeleeSound; FName MissileName; - fixed_t MissileHeight; + double MissileHeight; // For those times when being able to scan every kind of actor is convenient static TArray AllActorClasses; diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index cceb2cb8c..5b78ebc51 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -262,7 +262,7 @@ void DIntermissionScreenFader::Drawer () { double factor = clamp(double(mTicker) / mDuration, 0., 1.); if (mType == FADE_In) factor = 1.0 - factor; - int color = MAKEARGB(xs_RoundToInt(factor*255), 0,0,0); + int color = MAKEARGB(int(factor*255), 0,0,0); if (screen->Begin2D(false)) { @@ -591,8 +591,7 @@ void DIntermissionScreenCast::Drawer () // draw the current frame in the middle of the screen if (caststate != NULL) { - double castscalex = FIXED2DBL(mDefaults->scaleX); - double castscaley = FIXED2DBL(mDefaults->scaleY); + DVector2 castscale = mDefaults->Scale; int castsprite = caststate->sprite; @@ -612,8 +611,7 @@ void DIntermissionScreenCast::Drawer () if (!(mDefaults->flags4 & MF4_NOSKIN)) { - castscaley = FIXED2DBL(skin->ScaleY); - castscalex = FIXED2DBL(skin->ScaleX); + castscale = skin->Scale; } } @@ -626,10 +624,10 @@ void DIntermissionScreenCast::Drawer () screen->DrawTexture (pic, 160, 170, DTA_320x200, true, DTA_FlipX, sprframe->Flip & 1, - DTA_DestHeightF, pic->GetScaledHeightDouble() * castscaley, - DTA_DestWidthF, pic->GetScaledWidthDouble() * castscalex, + DTA_DestHeightF, pic->GetScaledHeightDouble() * castscale.Y, + DTA_DestWidthF, pic->GetScaledWidthDouble() * castscale.X, DTA_RenderStyle, mDefaults->RenderStyle, - DTA_Alpha, mDefaults->alpha, + DTA_AlphaF, mDefaults->Alpha, DTA_Translation, casttranslation, TAG_DONE); } diff --git a/src/intermission/intermission_parse.cpp b/src/intermission/intermission_parse.cpp index e9ebd847e..b15b78e71 100644 --- a/src/intermission/intermission_parse.cpp +++ b/src/intermission/intermission_parse.cpp @@ -113,7 +113,7 @@ bool FIntermissionAction::ParseKey(FScanner &sc) if (!sc.CheckToken('-')) { sc.MustGetFloat(); - mDuration = xs_RoundToInt(sc.Float*TICRATE); + mDuration = int(sc.Float*TICRATE); } else { @@ -329,7 +329,7 @@ bool FIntermissionActionTextscreen::ParseKey(FScanner &sc) if (!sc.CheckToken('-')) { sc.MustGetFloat(); - mTextDelay = xs_RoundToInt(sc.Float*TICRATE); + mTextDelay = int(sc.Float*TICRATE); } else { @@ -438,7 +438,7 @@ bool FIntermissionActionScroller::ParseKey(FScanner &sc) if (!sc.CheckToken('-')) { sc.MustGetFloat(); - mScrollDelay = xs_RoundToInt(sc.Float*TICRATE); + mScrollDelay = int(sc.Float*TICRATE); } else { @@ -453,7 +453,7 @@ bool FIntermissionActionScroller::ParseKey(FScanner &sc) if (!sc.CheckToken('-')) { sc.MustGetFloat(); - mScrollTime = xs_RoundToInt(sc.Float*TICRATE); + mScrollTime = int(sc.Float*TICRATE); } else { diff --git a/src/m_bbox.cpp b/src/m_bbox.cpp index a2d839b6b..143f54d47 100644 --- a/src/m_bbox.cpp +++ b/src/m_bbox.cpp @@ -34,32 +34,17 @@ // //========================================================================== -void FBoundingBox::setBox(fixed_t x, fixed_t y, fixed_t radius) +void FBoundingBox::AddToBox (const DVector2 &pos) { - m_Box[BOXTOP] = (fixed_t)MIN((SQWORD)y + radius, FIXED_MAX); - m_Box[BOXLEFT] = (fixed_t)MAX((SQWORD)x - radius, FIXED_MIN); - m_Box[BOXRIGHT] = (fixed_t)MIN((SQWORD)x + radius, FIXED_MAX); - m_Box[BOXBOTTOM] = (fixed_t)MAX((SQWORD)y - radius, FIXED_MIN); -} + if (pos.X < m_Box[BOXLEFT]) + m_Box[BOXLEFT] = pos.X; + if (pos.X > m_Box[BOXRIGHT]) + m_Box[BOXRIGHT] = pos.X; - -//========================================================================== -// -// -// -//========================================================================== - -void FBoundingBox::AddToBox (fixed_t x, fixed_t y) -{ - if (x < m_Box[BOXLEFT]) - m_Box[BOXLEFT] = x; - if (x > m_Box[BOXRIGHT]) - m_Box[BOXRIGHT] = x; - - if (y < m_Box[BOXBOTTOM]) - m_Box[BOXBOTTOM] = y; - if (y > m_Box[BOXTOP]) - m_Box[BOXTOP] = y; + if (pos.Y < m_Box[BOXBOTTOM]) + m_Box[BOXBOTTOM] = pos.Y; + if (pos.Y > m_Box[BOXTOP]) + m_Box[BOXTOP] = pos.Y; } //========================================================================== @@ -76,27 +61,27 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const int p1; int p2; - if (ld->dx == 0) + if (ld->Delta().X == 0) { // ST_VERTICAL - p1 = m_Box[BOXRIGHT] < ld->v1->x; - p2 = m_Box[BOXLEFT] < ld->v1->x; - if (ld->dy < 0) + p1 = m_Box[BOXRIGHT] < ld->v1->fX(); + p2 = m_Box[BOXLEFT] < ld->v1->fX(); + if (ld->Delta().Y < 0) { p1 ^= 1; p2 ^= 1; } } - else if (ld->dy == 0) + else if (ld->Delta().Y == 0) { // ST_HORIZONTAL: - p1 = m_Box[BOXTOP] > ld->v1->y; - p2 = m_Box[BOXBOTTOM] > ld->v1->y; - if (ld->dx < 0) + p1 = m_Box[BOXTOP] > ld->v1->fY(); + p2 = m_Box[BOXBOTTOM] > ld->v1->fY(); + if (ld->Delta().X < 0) { p1 ^= 1; p2 ^= 1; } } - else if ((ld->dy ^ ld->dx) >= 0) + else if ((ld->Delta().X * ld->Delta().Y) >= 0) { // ST_POSITIVE: p1 = P_PointOnLineSide (m_Box[BOXLEFT], m_Box[BOXTOP], ld); p2 = P_PointOnLineSide (m_Box[BOXRIGHT], m_Box[BOXBOTTOM], ld); diff --git a/src/m_bbox.h b/src/m_bbox.h index a48b6fecb..71728b851 100644 --- a/src/m_bbox.h +++ b/src/m_bbox.h @@ -22,7 +22,9 @@ #ifndef __M_BBOX_H__ #define __M_BBOX_H__ -#include "doomtype.h" +#include +#include "vectors.h" +#include "m_fixed.h" struct line_t; struct node_t; @@ -35,7 +37,7 @@ public: ClearBox(); } - FBoundingBox(fixed_t left, fixed_t bottom, fixed_t right, fixed_t top) + FBoundingBox(double left, double bottom, double right, double top) { m_Box[BOXTOP] = top; m_Box[BOXLEFT] = left; @@ -43,17 +45,24 @@ public: m_Box[BOXBOTTOM] = bottom; } - FBoundingBox(fixed_t x, fixed_t y, fixed_t radius) + FBoundingBox(double x, double y, double radius) { setBox(x, y, radius); } - void setBox(fixed_t x, fixed_t y, fixed_t radius); + + void setBox(double x, double y, double radius) + { + m_Box[BOXTOP] = y + radius; + m_Box[BOXLEFT] = x - radius; + m_Box[BOXRIGHT] = x + radius; + m_Box[BOXBOTTOM] = y - radius; + } void ClearBox () { - m_Box[BOXTOP] = m_Box[BOXRIGHT] = FIXED_MIN; - m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FIXED_MAX; + m_Box[BOXTOP] = m_Box[BOXRIGHT] = -FLT_MAX; + m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FLT_MAX; } // Returns a bounding box that encloses both bounding boxes @@ -65,19 +74,21 @@ public: m_Box[BOXTOP] > box2.m_Box[BOXTOP] ? m_Box[BOXTOP] : box2.m_Box[BOXTOP]); } - void AddToBox (fixed_t x, fixed_t y); + void AddToBox(const DVector2 &pos); - inline fixed_t Top () const { return m_Box[BOXTOP]; } - inline fixed_t Bottom () const { return m_Box[BOXBOTTOM]; } - inline fixed_t Left () const { return m_Box[BOXLEFT]; } - inline fixed_t Right () const { return m_Box[BOXRIGHT]; } + inline double Top () const { return m_Box[BOXTOP]; } + inline double Bottom () const { return m_Box[BOXBOTTOM]; } + inline double Left () const { return m_Box[BOXLEFT]; } + inline double Right () const { return m_Box[BOXRIGHT]; } + + bool inRange(const line_t *ld) const; int BoxOnLineSide (const line_t *ld) const; - void Set(int index, fixed_t value) {m_Box[index] = value;} + void Set(int index, double value) {m_Box[index] = value;} protected: - fixed_t m_Box[4]; + double m_Box[4]; }; diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 25f8cfca2..c9b478161 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -138,7 +138,7 @@ void cht_DoCheat (player_t *player, int cheat) player->cheats &= ~CF_NOCLIP; msg = GStrings("STSTR_NCOFF"); } - if (player->mo->vel.x == 0) player->mo->vel.x = 1; // force some lateral movement so that internal variables are up to date + if (player->mo->Vel.X == 0) player->mo->Vel.X = MinVel; // force some lateral movement so that internal variables are up to date break; case CHT_NOVELOCITY: @@ -333,7 +333,7 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->flags6 = player->mo->GetDefault()->flags6; player->mo->flags7 = player->mo->GetDefault()->flags7; player->mo->renderflags &= ~RF_INVISIBLE; - player->mo->height = player->mo->GetDefault()->height; + player->mo->Height = player->mo->GetDefault()->Height; player->mo->radius = player->mo->GetDefault()->radius; player->mo->special1 = 0; // required for the Hexen fighter's fist attack. // This gets set by AActor::Die as flag for the wimpy death and must be reset here. @@ -469,8 +469,8 @@ void cht_DoCheat (player_t *player, int cheat) { // Don't allow this in deathmatch even with cheats enabled, because it's // a very very cheap kill. - P_LineAttack (player->mo, player->mo->angle, PLAYERMISSILERANGE, - P_AimLineAttack (player->mo, player->mo->angle, PLAYERMISSILERANGE), TELEFRAG_DAMAGE, + P_LineAttack (player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE, + P_AimLineAttack (player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE), TELEFRAG_DAMAGE, NAME_MDK, NAME_BulletPuff); } break; @@ -583,7 +583,7 @@ void GiveSpawner (player_t *player, PClassInventory *type, int amount) } AInventory *item = static_cast - (Spawn (type, player->mo->X(), player->mo->Y(), player->mo->Z(), NO_REPLACE)); + (Spawn (type, player->mo->Pos(), NO_REPLACE)); if (item != NULL) { if (amount > 0) @@ -694,7 +694,7 @@ void cht_Give (player_t *player, const char *name, int amount) AInventory *ammo = player->mo->FindInventory(atype); if (ammo == NULL) { - ammo = static_cast(Spawn (atype, 0, 0, 0, NO_REPLACE)); + ammo = static_cast(Spawn (atype)); ammo->AttachToOwner (player->mo); ammo->Amount = ammo->MaxAmount; } @@ -713,9 +713,9 @@ void cht_Give (player_t *player, const char *name, int amount) { if (gameinfo.gametype != GAME_Hexen) { - ABasicArmorPickup *armor = Spawn (0,0,0, NO_REPLACE); + ABasicArmorPickup *armor = Spawn (); armor->SaveAmount = 100*deh.BlueAC; - armor->SavePercent = gameinfo.Armor2Percent > 0? gameinfo.Armor2Percent : FRACUNIT/2; + armor->SavePercent = gameinfo.Armor2Percent > 0? gameinfo.Armor2Percent : 0.5; if (!armor->CallTryPickup (player->mo)) { armor->Destroy (); @@ -725,7 +725,7 @@ void cht_Give (player_t *player, const char *name, int amount) { for (i = 0; i < 4; ++i) { - AHexenArmor *armor = Spawn (0,0,0, NO_REPLACE); + AHexenArmor *armor = Spawn (); armor->health = i; armor->Amount = 0; if (!armor->CallTryPickup (player->mo)) @@ -748,7 +748,7 @@ void cht_Give (player_t *player, const char *name, int amount) AKey *key = (AKey *)GetDefaultByType (PClassActor::AllActorClasses[i]); if (key->KeyNumber != 0) { - key = static_cast(Spawn(static_cast(PClassActor::AllActorClasses[i]), 0,0,0, NO_REPLACE)); + key = static_cast(Spawn(static_cast(PClassActor::AllActorClasses[i]))); if (!key->CallTryPickup (player->mo)) { key->Destroy (); @@ -1071,8 +1071,8 @@ public: Pawn->flags |= MF_SHOOTABLE; Pawn->flags2 &= ~MF2_INVULNERABLE; // Store the player's current damage factor, to restore it later. - fixed_t plyrdmgfact = Pawn->DamageFactor; - Pawn->DamageFactor = 65536; + double plyrdmgfact = Pawn->DamageFactor; + Pawn->DamageFactor = 1.; P_DamageMobj (Pawn, Pawn, Pawn, TELEFRAG_DAMAGE, NAME_Suicide); Pawn->DamageFactor = plyrdmgfact; if (Pawn->health <= 0) diff --git a/src/m_fixed.h b/src/m_fixed.h index 58d13123a..506b9702c 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -136,17 +136,35 @@ inline SDWORD ModDiv (SDWORD num, SDWORD den, SDWORD *dmval) return num % den; } +inline fixed_t FloatToFixed(double f) +{ + return xs_Fix<16>::ToFix(f); +} -#define FLOAT2FIXED(f) ((fixed_t)xs_Fix<16>::ToFix(f)) -#define FIXED2FLOAT(f) ((f) / float(65536)) -#define FIXED2DBL(f) ((f) / double(65536)) +inline double FixedToFloat(fixed_t f) +{ + return f / 65536.; +} -#define ANGLE2DBL(f) ((f) * (90./ANGLE_90)) -#define ANGLE2FLOAT(f) (float((f) * (90./ANGLE_90))) -#define FLOAT2ANGLE(f) ((angle_t)xs_CRoundToInt((f) * (ANGLE_90/90.))) +inline unsigned FloatToAngle(double f) +{ + return xs_CRoundToInt((f)* (0x40000000 / 90.)); +} -#define ANGLE2RAD(f) ((f) * (M_PI/ANGLE_180)) -#define ANGLE2RADF(f) ((f) * float(M_PI/ANGLE_180)) -#define RAD2ANGLE(f) ((angle_t)xs_CRoundToInt((f) * (ANGLE_180/M_PI))) +inline double AngleToFloat(unsigned f) +{ + return f * (90. / 0x40000000); +} + +inline double AngleToFloat(int f) +{ + return f * (90. / 0x40000000); +} + +#define FLOAT2FIXED(f) FloatToFixed(f) +#define FIXED2FLOAT(f) float(FixedToFloat(f)) +#define FIXED2DBL(f) FixedToFloat(f) + +#define ANGLE2DBL(f) AngleToFloat(f) #endif diff --git a/src/m_joy.cpp b/src/m_joy.cpp index d2a067846..46c0b9006 100644 --- a/src/m_joy.cpp +++ b/src/m_joy.cpp @@ -1,5 +1,6 @@ // HEADER FILES ------------------------------------------------------------ +#include #include "m_joy.h" #include "gameconfigfile.h" #include "d_event.h" diff --git a/src/math/asin.c b/src/math/asin.c new file mode 100644 index 000000000..50419597f --- /dev/null +++ b/src/math/asin.c @@ -0,0 +1,315 @@ +/* asin.c + * + * Inverse circular sine + * + * + * + * SYNOPSIS: + * + * double x, y, asin(); + * + * y = asin( x ); + * + * + * + * DESCRIPTION: + * + * Returns radian angle between -pi/2 and +pi/2 whose sine is x. + * + * A rational function of the form x + x**3 P(x**2)/Q(x**2) + * is used for |x| in the interval [0, 0.5]. If |x| > 0.5 it is + * transformed by the identity + * + * asin(x) = pi/2 - 2 asin( sqrt( (1-x)/2 ) ). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -1, 1 40000 2.6e-17 7.1e-18 + * IEEE -1, 1 10^6 1.9e-16 5.4e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * asin domain |x| > 1 NAN + * + */ + /* acos() + * + * Inverse circular cosine + * + * + * + * SYNOPSIS: + * + * double x, y, acos(); + * + * y = acos( x ); + * + * + * + * DESCRIPTION: + * + * Returns radian angle between 0 and pi whose cosine + * is x. + * + * Analytically, acos(x) = pi/2 - asin(x). However if |x| is + * near 1, there is cancellation error in subtracting asin(x) + * from pi/2. Hence if x < -0.5, + * + * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); + * + * or if x > +0.5, + * + * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -1, 1 50000 3.3e-17 8.2e-18 + * IEEE -1, 1 10^6 2.2e-16 6.5e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * asin domain |x| > 1 NAN + */ + +/* asin.c */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +/* arcsin(x) = x + x^3 P(x^2)/Q(x^2) + 0 <= x <= 0.625 + Peak relative error = 1.2e-18 */ +#if UNK +static double P[6] = { + 4.253011369004428248960E-3, +-6.019598008014123785661E-1, + 5.444622390564711410273E0, +-1.626247967210700244449E1, + 1.956261983317594739197E1, +-8.198089802484824371615E0, +}; +static double Q[5] = { +/* 1.000000000000000000000E0, */ +-1.474091372988853791896E1, + 7.049610280856842141659E1, +-1.471791292232726029859E2, + 1.395105614657485689735E2, +-4.918853881490881290097E1, +}; +#endif +#if DEC +static short P[24] = { +0036213,0056330,0057244,0053234, +0140032,0015011,0114762,0160255, +0040656,0035130,0136121,0067313, +0141202,0014616,0170474,0101731, +0041234,0100076,0151674,0111310, +0141003,0025540,0033165,0077246, +}; +static short Q[20] = { +/* 0040200,0000000,0000000,0000000, */ +0141153,0155310,0055360,0072530, +0041614,0177001,0027764,0101237, +0142023,0026733,0064653,0133266, +0042013,0101264,0023775,0176351, +0141504,0140420,0050660,0036543, +}; +#endif +#if IBMPC +static short P[24] = { +0x8ad3,0x0bd4,0x6b9b,0x3f71, +0x5c16,0x333e,0x4341,0xbfe3, +0x2dd9,0x178a,0xc74b,0x4015, +0x907b,0xde27,0x4331,0xc030, +0x9259,0xda77,0x9007,0x4033, +0xafd5,0x06ce,0x656c,0xc020, +}; +static short Q[20] = { +/* 0x0000,0x0000,0x0000,0x3ff0, */ +0x0eab,0x0b5e,0x7b59,0xc02d, +0x9054,0x25fe,0x9fc0,0x4051, +0x76d7,0x6d35,0x65bb,0xc062, +0xbf9d,0x84ff,0x7056,0x4061, +0x07ac,0x0a36,0x9822,0xc048, +}; +#endif +#if MIEEE +static short P[24] = { +0x3f71,0x6b9b,0x0bd4,0x8ad3, +0xbfe3,0x4341,0x333e,0x5c16, +0x4015,0xc74b,0x178a,0x2dd9, +0xc030,0x4331,0xde27,0x907b, +0x4033,0x9007,0xda77,0x9259, +0xc020,0x656c,0x06ce,0xafd5, +}; +static short Q[20] = { +/* 0x3ff0,0x0000,0x0000,0x0000, */ +0xc02d,0x7b59,0x0b5e,0x0eab, +0x4051,0x9fc0,0x25fe,0x9054, +0xc062,0x65bb,0x6d35,0x76d7, +0x4061,0x7056,0x84ff,0xbf9d, +0xc048,0x9822,0x0a36,0x07ac, +}; +#endif + +/* arcsin(1-x) = pi/2 - sqrt(2x)(1+R(x)) + 0 <= x <= 0.5 + Peak relative error = 4.2e-18 */ +#if UNK +static double R[5] = { + 2.967721961301243206100E-3, +-5.634242780008963776856E-1, + 6.968710824104713396794E0, +-2.556901049652824852289E1, + 2.853665548261061424989E1, +}; +static double S[4] = { +/* 1.000000000000000000000E0, */ +-2.194779531642920639778E1, + 1.470656354026814941758E2, +-3.838770957603691357202E2, + 3.424398657913078477438E2, +}; +#endif +#if DEC +static short R[20] = { +0036102,0077034,0142164,0174103, +0140020,0036222,0147711,0044173, +0040736,0177655,0153631,0171523, +0141314,0106525,0060015,0055474, +0041344,0045422,0003630,0040344, +}; +static short S[16] = { +/* 0040200,0000000,0000000,0000000, */ +0141257,0112425,0132772,0166136, +0042023,0010315,0075523,0175020, +0142277,0170104,0126203,0017563, +0042253,0034115,0102662,0022757, +}; +#endif +#if IBMPC +static short R[20] = { +0x9f08,0x988e,0x4fc3,0x3f68, +0x290f,0x59f9,0x0792,0xbfe2, +0x3e6a,0xbaf3,0xdff5,0x401b, +0xab68,0xac01,0x91aa,0xc039, +0x081d,0x40f3,0x8962,0x403c, +}; +static short S[16] = { +/* 0x0000,0x0000,0x0000,0x3ff0, */ +0x5d8c,0xb6bf,0xf2a2,0xc035, +0x7f42,0xaf6a,0x6219,0x4062, +0x63ee,0x9590,0xfe08,0xc077, +0x44be,0xb0b6,0x6709,0x4075, +}; +#endif +#if MIEEE +static short R[20] = { +0x3f68,0x4fc3,0x988e,0x9f08, +0xbfe2,0x0792,0x59f9,0x290f, +0x401b,0xdff5,0xbaf3,0x3e6a, +0xc039,0x91aa,0xac01,0xab68, +0x403c,0x8962,0x40f3,0x081d, +}; +static short S[16] = { +/* 0x3ff0,0x0000,0x0000,0x0000, */ +0xc035,0xf2a2,0xb6bf,0x5d8c, +0x4062,0x6219,0xaf6a,0x7f42, +0xc077,0xfe08,0x9590,0x63ee, +0x4075,0x6709,0xb0b6,0x44be, +}; +#endif + +/* pi/2 = PIO2 + MOREBITS. */ +#ifdef DEC +#define MOREBITS 5.721188726109831840122E-18 +#else +#define MOREBITS 6.123233995736765886130E-17 +#endif + +#ifdef ANSIPROT +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern double c_sqrt ( double ); +double c_asin ( double ); +#else +double c_sqrt(), polevl(), p1evl(); +double c_asin(); +#endif +extern double PIO2, PIO4, NAN; + +double c_asin(x) +double x; +{ +double a, p, z, zz; +short sign; + +if( x > 0 ) + { + sign = 1; + a = x; + } +else + { + sign = -1; + a = -x; + } + +if( a > 1.0 ) + { + mtherr( "asin", DOMAIN ); + return( NAN ); + } + +if( a > 0.625 ) + { + /* arcsin(1-x) = pi/2 - sqrt(2x)(1+R(x)) */ + zz = 1.0 - a; + p = zz * polevl( zz, R, 4)/p1evl( zz, S, 4); + zz = c_sqrt(zz+zz); + z = PIO4 - zz; + zz = zz * p - MOREBITS; + z = z - zz; + z = z + PIO4; + } +else + { + if( a < 1.0e-8 ) + { + return(x); + } + zz = a * a; + z = zz * polevl( zz, P, 5)/p1evl( zz, Q, 5); + z = a * z + a; + } +if( sign < 0 ) + z = -z; +return(z); +} + + + +double c_acos(x) +double x; +{ +if( (x < -1.0) || (x > 1.0) ) + { + mtherr( "acos", DOMAIN ); + return( NAN ); + } + return PIO2 - c_asin(x) + MOREBITS; +} diff --git a/src/math/atan.c b/src/math/atan.c new file mode 100644 index 000000000..3c5d4394c --- /dev/null +++ b/src/math/atan.c @@ -0,0 +1,393 @@ +/* atan.c + * + * Inverse circular tangent + * (arctangent) + * + * + * + * SYNOPSIS: + * + * double x, y, atan(); + * + * y = atan( x ); + * + * + * + * DESCRIPTION: + * + * Returns radian angle between -pi/2 and +pi/2 whose tangent + * is x. + * + * Range reduction is from three intervals into the interval + * from zero to 0.66. The approximant uses a rational + * function of degree 4/5 of the form x + x**3 P(x)/Q(x). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10, 10 50000 2.4e-17 8.3e-18 + * IEEE -10, 10 10^6 1.8e-16 5.0e-17 + * + */ + /* atan2() + * + * Quadrant correct inverse circular tangent + * + * + * + * SYNOPSIS: + * + * double x, y, z, atan2(); + * + * z = atan2( y, x ); + * + * + * + * DESCRIPTION: + * + * Returns radian angle whose tangent is y/x. + * Define compile time symbol ANSIC = 1 for ANSI standard, + * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range + * 0 to 2PI, args (x,y). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10, 10 10^6 2.5e-16 6.9e-17 + * See atan.c. + * + */ + +/* atan.c */ + + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + + +#include "mconf.h" + +/* arctan(x) = x + x^3 P(x^2)/Q(x^2) + 0 <= x <= 0.66 + Peak relative error = 2.6e-18 */ +#ifdef UNK +static double P[5] = { +-8.750608600031904122785E-1, +-1.615753718733365076637E1, +-7.500855792314704667340E1, +-1.228866684490136173410E2, +-6.485021904942025371773E1, +}; +static double Q[5] = { +/* 1.000000000000000000000E0, */ + 2.485846490142306297962E1, + 1.650270098316988542046E2, + 4.328810604912902668951E2, + 4.853903996359136964868E2, + 1.945506571482613964425E2, +}; + +/* tan( 3*pi/8 ) */ +static double T3P8 = 2.41421356237309504880; +#endif + +#ifdef DEC +static short P[20] = { +0140140,0001775,0007671,0026242, +0141201,0041242,0155534,0001715, +0141626,0002141,0132100,0011625, +0141765,0142771,0064055,0150453, +0141601,0131517,0164507,0062164, +}; +static short Q[20] = { +/* 0040200,0000000,0000000,0000000, */ +0041306,0157042,0154243,0000742, +0042045,0003352,0016707,0150452, +0042330,0070306,0113425,0170730, +0042362,0130770,0116602,0047520, +0042102,0106367,0156753,0013541, +}; + +/* tan( 3*pi/8 ) = 2.41421356237309504880 */ +static unsigned short T3P8A[] = {040432,0101171,0114774,0167462,}; +#define T3P8 *(double *)T3P8A +#endif + +#ifdef IBMPC +static short P[20] = { +0x2594,0xa1f7,0x007f,0xbfec, +0x807a,0x5b6b,0x2854,0xc030, +0x0273,0x3688,0xc08c,0xc052, +0xba25,0x2d05,0xb8bf,0xc05e, +0xec8e,0xfd28,0x3669,0xc050, +}; +static short Q[20] = { +/* 0x0000,0x0000,0x0000,0x3ff0, */ +0x603c,0x5b14,0xdbc4,0x4038, +0xfa25,0x43b8,0xa0dd,0x4064, +0xbe3b,0xd2e2,0x0e18,0x407b, +0x49ea,0x13b0,0x563f,0x407e, +0x62ec,0xfbbd,0x519e,0x4068, +}; + +/* tan( 3*pi/8 ) = 2.41421356237309504880 */ +static unsigned short T3P8A[] = {0x9de6,0x333f,0x504f,0x4003}; +#define T3P8 *(double *)T3P8A +#endif + +#ifdef MIEEE +static short P[20] = { +0xbfec,0x007f,0xa1f7,0x2594, +0xc030,0x2854,0x5b6b,0x807a, +0xc052,0xc08c,0x3688,0x0273, +0xc05e,0xb8bf,0x2d05,0xba25, +0xc050,0x3669,0xfd28,0xec8e, +}; +static short Q[20] = { +/* 0x3ff0,0x0000,0x0000,0x0000, */ +0x4038,0xdbc4,0x5b14,0x603c, +0x4064,0xa0dd,0x43b8,0xfa25, +0x407b,0x0e18,0xd2e2,0xbe3b, +0x407e,0x563f,0x13b0,0x49ea, +0x4068,0x519e,0xfbbd,0x62ec, +}; + +/* tan( 3*pi/8 ) = 2.41421356237309504880 */ +static unsigned short T3P8A[] = { +0x4003,0x504f,0x333f,0x9de6 +}; +#define T3P8 *(double *)T3P8A +#endif + +#ifdef ANSIPROT +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern double atan ( double ); +extern double fabs ( double ); +extern int signbit ( double ); +extern int isnan ( double ); +#else +double polevl(), p1evl(), atan(), fabs(); +int signbit(), isnan(); +#endif +extern double PI, PIO2, PIO4, INFINITY, NEGZERO, MAXNUM; + +/* pi/2 = PIO2 + MOREBITS. */ +#ifdef DEC +#define MOREBITS 5.721188726109831840122E-18 +#else +#define MOREBITS 6.123233995736765886130E-17 +#endif + + +double c_atan(x) +double x; +{ +double y, z; +short sign, flag; + +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +#ifdef INFINITIES +if(x == INFINITY) + return(PIO2); +if(x == -INFINITY) + return(-PIO2); +#endif +/* make argument positive and save the sign */ +sign = 1; +if( x < 0.0 ) + { + sign = -1; + x = -x; + } +/* range reduction */ +flag = 0; +if( x > T3P8 ) + { + y = PIO2; + flag = 1; + x = -( 1.0/x ); + } +else if( x <= 0.66 ) + { + y = 0.0; + } +else + { + y = PIO4; + flag = 2; + x = (x-1.0)/(x+1.0); + } +z = x * x; +z = z * polevl( z, P, 4 ) / p1evl( z, Q, 5 ); +z = x * z + x; +if( flag == 2 ) + z += 0.5 * MOREBITS; +else if( flag == 1 ) + z += MOREBITS; +y = y + z; +if( sign < 0 ) + y = -y; +return(y); +} + +/* atan2 */ + +#ifdef ANSIC +double c_atan2( y, x ) +#else +double c_atan2( x, y ) +#endif +double x, y; +{ +double z, w; +short code; + +code = 0; + +#ifdef NANS +if( isnan(x) ) + return(x); +if( isnan(y) ) + return(y); +#endif +#ifdef MINUSZERO +if( y == 0.0 ) + { + if( signbit(y) ) + { + if( x > 0.0 ) + z = y; + else if( x < 0.0 ) + z = -PI; + else + { + if( signbit(x) ) + z = -PI; + else + z = y; + } + } + else /* y is +0 */ + { + if( x == 0.0 ) + { + if( signbit(x) ) + z = PI; + else + z = 0.0; + } + else if( x > 0.0 ) + z = 0.0; + else + z = PI; + } + return z; + } +if( x == 0.0 ) + { + if( y > 0.0 ) + z = PIO2; + else + z = -PIO2; + return z; + } +#endif /* MINUSZERO */ +#ifdef INFINITIES +if( x == INFINITY ) + { + if( y == INFINITY ) + z = 0.25 * PI; + else if( y == -INFINITY ) + z = -0.25 * PI; + else if( y < 0.0 ) + z = NEGZERO; + else + z = 0.0; + return z; + } +if( x == -INFINITY ) + { + if( y == INFINITY ) + z = 0.75 * PI; + else if( y <= -INFINITY ) + z = -0.75 * PI; + else if( y >= 0.0 ) + z = PI; + else + z = -PI; + return z; + } +if( y == INFINITY ) + return( PIO2 ); +if( y == -INFINITY ) + return( -PIO2 ); +#endif + +if( x < 0.0 ) + code = 2; +if( y < 0.0 ) + code |= 1; + +#ifdef INFINITIES +if( x == 0.0 ) +#else +if( fabs(x) <= (fabs(y) / MAXNUM) ) +#endif + { + if( code & 1 ) + { +#if ANSIC + return( -PIO2 ); +#else + return( 3.0*PIO2 ); +#endif + } + if( y == 0.0 ) + return( 0.0 ); + return( PIO2 ); + } + +if( y == 0.0 ) + { + if( code & 2 ) + return( PI ); + return( 0.0 ); + } + + +switch( code ) + { +#if ANSIC + default: + case 0: + case 1: w = 0.0; break; + case 2: w = PI; break; + case 3: w = -PI; break; +#else + default: + case 0: w = 0.0; break; + case 1: w = 2.0 * PI; break; + case 2: + case 3: w = PI; break; +#endif + } + +z = w + c_atan( y/x ); +#ifdef MINUSZERO +if( z == 0.0 && y < 0 ) + z = NEGZERO; +#endif +return( z ); +} diff --git a/src/math/cmath.h b/src/math/cmath.h new file mode 100644 index 000000000..9fd0b570d --- /dev/null +++ b/src/math/cmath.h @@ -0,0 +1,146 @@ +#ifndef __CMATH_H +#define __CMATH_H + +#include "xs_Float.h" + +#define USE_CUSTOM_MATH // we want repreducably reliable results, even at the cost of performance +#define USE_FAST_MATH // use faster table-based sin and cos variants with limited precision (sufficient for Doom gameplay) + +extern"C" +{ +double c_asin(double); +double c_acos(double); +double c_atan(double); +double c_atan2(double, double); +double c_sin(double); +double c_cos(double); +double c_tan(double); +double c_cot(double); +double c_sqrt(double); +double c_sinh(double); +double c_cosh(double); +double c_tanh(double); +double c_exp(double); +double c_log(double); +double c_log10(double); +} + + +// This uses a sine table with linear interpolation +// For in-game calculations this is precise enough +// and this code is more than 10x faster than the +// Cephes sin and cos function. + +struct FFastTrig +{ + static const int TBLPERIOD = 8192; + static const int BITSHIFT = 19; + static const int REMAINDER = (1 << BITSHIFT) - 1; + float sinetable[2049]; + + double sinq1(unsigned); + +public: + FFastTrig(); + double sin(unsigned); + double cos(unsigned); +}; + +extern FFastTrig fasttrig; + +// This must use xs_Float to guarantee proper integer wraparound. +#define DEG2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x40000000/90.))) +#define RAD2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x80000000/3.14159265358979323846))) + + +inline double fastcosdeg(double v) +{ + return fasttrig.cos(DEG2BAM(v)); +} + +inline double fastsindeg(double v) +{ + return fasttrig.sin(DEG2BAM(v)); +} + +inline double fastcos(double v) +{ + return fasttrig.cos(RAD2BAM(v)); +} + +inline double fastsin(double v) +{ + return fasttrig.sin(RAD2BAM(v)); +} + +// these are supposed to be local to this file. +#undef DEG2BAM +#undef RAD2BAM + +inline double sindeg(double v) +{ +#ifdef USE_CUSTOM_MATH + return c_sin(v * (3.14159265358979323846 / 180.)); +#else + return sin(v * (3.14159265358979323846 / 180.)); +#endif +} + +inline double cosdeg(double v) +{ +#ifdef USE_CUSTOM_MATH + return c_cos(v * (3.14159265358979323846 / 180.)); +#else + return cos(v * (3.14159265358979323846 / 180.)); +#endif +} + + +#ifndef USE_CUSTOM_MATH +#define g_asin asin +#define g_acos acos +#define g_atan atan +#define g_atan2 atan2 +#define g_sin sin +#define g_cos cos +#define g_sindeg sindeg +#define g_cosdeg cosdeg +#define g_tan tan +#define g_cot cot +#define g_sqrt sqrt +#define g_sinh sinh +#define g_cosh cosh +#define g_tanh tanh +#define g_exp exp +#define g_log log +#define g_log10 log10 +#else +#define g_asin c_asin +#define g_acos c_acos +#define g_atan c_atan +#define g_atan2 c_atan2 +#ifndef USE_FAST_MATH +#define g_sindeg sindeg +#define g_cosdeg cosdeg +#define g_sin c_sin +#define g_cos c_cos +#else +#define g_sindeg fastsindeg +#define g_cosdeg fastcosdeg +#define g_sin fastsin +#define g_cos fastcos +#endif +#define g_tan c_tan +#define g_cot c_cot +#define g_sqrt c_sqrt +#define g_sinh c_sinh +#define g_cosh c_cosh +#define g_tanh c_tanh +#define g_exp c_exp +#define g_log c_log +#define g_log10 c_log10 +#endif + + + +#endif \ No newline at end of file diff --git a/src/math/const.c b/src/math/const.c new file mode 100644 index 000000000..2d9ff7b33 --- /dev/null +++ b/src/math/const.c @@ -0,0 +1,252 @@ +/* const.c + * + * Globally declared constants + * + * + * + * SYNOPSIS: + * + * extern double nameofconstant; + * + * + * + * + * DESCRIPTION: + * + * This file contains a number of mathematical constants and + * also some needed size parameters of the computer arithmetic. + * The values are supplied as arrays of hexadecimal integers + * for IEEE arithmetic; arrays of octal constants for DEC + * arithmetic; and in a normal decimal scientific notation for + * other machines. The particular notation used is determined + * by a symbol (DEC, IBMPC, or UNK) defined in the include file + * mconf.h. + * + * The default size parameters are as follows. + * + * For DEC and UNK modes: + * MACHEP = 1.38777878078144567553E-17 2**-56 + * MAXLOG = 8.8029691931113054295988E1 log(2**127) + * MINLOG = -8.872283911167299960540E1 log(2**-128) + * MAXNUM = 1.701411834604692317316873e38 2**127 + * + * For IEEE arithmetic (IBMPC): + * MACHEP = 1.11022302462515654042E-16 2**-53 + * MAXLOG = 7.09782712893383996843E2 log(2**1024) + * MINLOG = -7.08396418532264106224E2 log(2**-1022) + * MAXNUM = 1.7976931348623158E308 2**1024 + * + * The global symbols for mathematical constants are + * PI = 3.14159265358979323846 pi + * PIO2 = 1.57079632679489661923 pi/2 + * PIO4 = 7.85398163397448309616E-1 pi/4 + * SQRT2 = 1.41421356237309504880 sqrt(2) + * SQRTH = 7.07106781186547524401E-1 sqrt(2)/2 + * LOG2E = 1.4426950408889634073599 1/log(2) + * SQ2OPI = 7.9788456080286535587989E-1 sqrt( 2/pi ) + * LOGE2 = 6.93147180559945309417E-1 log(2) + * LOGSQ2 = 3.46573590279972654709E-1 log(2)/2 + * THPIO4 = 2.35619449019234492885 3*pi/4 + * TWOOPI = 6.36619772367581343075535E-1 2/pi + * + * These lists are subject to change. + */ + +/* const.c */ + +/* +Cephes Math Library Release 2.3: March, 1995 +Copyright 1984, 1995 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +#if 1 +double MACHEP = 1.11022302462515654042E-16; /* 2**-53 */ +#else +double MACHEP = 1.38777878078144567553E-17; /* 2**-56 */ +#endif +double UFLOWTHRESH = 2.22507385850720138309E-308; /* 2**-1022 */ +#ifdef DENORMAL +double MAXLOG = 7.09782712893383996732E2; /* log(MAXNUM) */ +/* double MINLOG = -7.44440071921381262314E2; */ /* log(2**-1074) */ +double MINLOG = -7.451332191019412076235E2; /* log(2**-1075) */ +#else +double MAXLOG = 7.08396418532264106224E2; /* log 2**1022 */ +double MINLOG = -7.08396418532264106224E2; /* log 2**-1022 */ +#endif +double MAXNUM = 1.79769313486231570815E308; /* 2**1024*(1-MACHEP) */ +double PI = 3.14159265358979323846; /* pi */ +double PIO2 = 1.57079632679489661923; /* pi/2 */ +double PIO4 = 7.85398163397448309616E-1; /* pi/4 */ +double SQRT2 = 1.41421356237309504880; /* sqrt(2) */ +double SQRTH = 7.07106781186547524401E-1; /* sqrt(2)/2 */ +double LOG2E = 1.4426950408889634073599; /* 1/log(2) */ +double SQ2OPI = 7.9788456080286535587989E-1; /* sqrt( 2/pi ) */ +double LOGE2 = 6.93147180559945309417E-1; /* log(2) */ +double LOGSQ2 = 3.46573590279972654709E-1; /* log(2)/2 */ +double THPIO4 = 2.35619449019234492885; /* 3*pi/4 */ +double TWOOPI = 6.36619772367581343075535E-1; /* 2/pi */ +#ifdef INFINITIES +double INFINITY = 1.0/0.0; /* 99e999; */ +#else +double INFINITY = 1.79769313486231570815E308; /* 2**1024*(1-MACHEP) */ +#endif +#ifdef NANS +double NAN = 1.0/0.0 - 1.0/0.0; +#else +double NAN = 0.0; +#endif +#ifdef MINUSZERO +double NEGZERO = -0.0; +#else +double NEGZERO = 0.0; +#endif +#endif + +#ifdef IBMPC + /* 2**-53 = 1.11022302462515654042E-16 */ +unsigned short MACHEP[4] = {0x0000,0x0000,0x0000,0x3ca0}; +unsigned short UFLOWTHRESH[4] = {0x0000,0x0000,0x0000,0x0010}; +#ifdef DENORMAL + /* log(MAXNUM) = 7.09782712893383996732224E2 */ +unsigned short MAXLOG[4] = {0x39ef,0xfefa,0x2e42,0x4086}; + /* log(2**-1074) = - -7.44440071921381262314E2 */ +/*unsigned short MINLOG[4] = {0x71c3,0x446d,0x4385,0xc087};*/ +unsigned short MINLOG[4] = {0x3052,0xd52d,0x4910,0xc087}; +#else + /* log(2**1022) = 7.08396418532264106224E2 */ +unsigned short MAXLOG[4] = {0xbcd2,0xdd7a,0x232b,0x4086}; + /* log(2**-1022) = - 7.08396418532264106224E2 */ +unsigned short MINLOG[4] = {0xbcd2,0xdd7a,0x232b,0xc086}; +#endif + /* 2**1024*(1-MACHEP) = 1.7976931348623158E308 */ +unsigned short MAXNUM[4] = {0xffff,0xffff,0xffff,0x7fef}; +unsigned short PI[4] = {0x2d18,0x5444,0x21fb,0x4009}; +unsigned short PIO2[4] = {0x2d18,0x5444,0x21fb,0x3ff9}; +unsigned short PIO4[4] = {0x2d18,0x5444,0x21fb,0x3fe9}; +unsigned short SQRT2[4] = {0x3bcd,0x667f,0xa09e,0x3ff6}; +unsigned short SQRTH[4] = {0x3bcd,0x667f,0xa09e,0x3fe6}; +unsigned short LOG2E[4] = {0x82fe,0x652b,0x1547,0x3ff7}; +unsigned short SQ2OPI[4] = {0x3651,0x33d4,0x8845,0x3fe9}; +unsigned short LOGE2[4] = {0x39ef,0xfefa,0x2e42,0x3fe6}; +unsigned short LOGSQ2[4] = {0x39ef,0xfefa,0x2e42,0x3fd6}; +unsigned short THPIO4[4] = {0x21d2,0x7f33,0xd97c,0x4002}; +unsigned short TWOOPI[4] = {0xc883,0x6dc9,0x5f30,0x3fe4}; +#ifdef INFINITIES +unsigned short INFINITY[4] = {0x0000,0x0000,0x0000,0x7ff0}; +#else +unsigned short INFINITY[4] = {0xffff,0xffff,0xffff,0x7fef}; +#endif +#ifdef NANS +unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x7ffc}; +#else +unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#ifdef MINUSZERO +unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x8000}; +#else +unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#endif + +#ifdef MIEEE + /* 2**-53 = 1.11022302462515654042E-16 */ +unsigned short MACHEP[4] = {0x3ca0,0x0000,0x0000,0x0000}; +unsigned short UFLOWTHRESH[4] = {0x0010,0x0000,0x0000,0x0000}; +#ifdef DENORMAL + /* log(2**1024) = 7.09782712893383996843E2 */ +unsigned short MAXLOG[4] = {0x4086,0x2e42,0xfefa,0x39ef}; + /* log(2**-1074) = - -7.44440071921381262314E2 */ +/* unsigned short MINLOG[4] = {0xc087,0x4385,0x446d,0x71c3}; */ +unsigned short MINLOG[4] = {0xc087,0x4910,0xd52d,0x3052}; +#else + /* log(2**1022) = 7.08396418532264106224E2 */ +unsigned short MAXLOG[4] = {0x4086,0x232b,0xdd7a,0xbcd2}; + /* log(2**-1022) = - 7.08396418532264106224E2 */ +unsigned short MINLOG[4] = {0xc086,0x232b,0xdd7a,0xbcd2}; +#endif + /* 2**1024*(1-MACHEP) = 1.7976931348623158E308 */ +unsigned short MAXNUM[4] = {0x7fef,0xffff,0xffff,0xffff}; +unsigned short PI[4] = {0x4009,0x21fb,0x5444,0x2d18}; +unsigned short PIO2[4] = {0x3ff9,0x21fb,0x5444,0x2d18}; +unsigned short PIO4[4] = {0x3fe9,0x21fb,0x5444,0x2d18}; +unsigned short SQRT2[4] = {0x3ff6,0xa09e,0x667f,0x3bcd}; +unsigned short SQRTH[4] = {0x3fe6,0xa09e,0x667f,0x3bcd}; +unsigned short LOG2E[4] = {0x3ff7,0x1547,0x652b,0x82fe}; +unsigned short SQ2OPI[4] = {0x3fe9,0x8845,0x33d4,0x3651}; +unsigned short LOGE2[4] = {0x3fe6,0x2e42,0xfefa,0x39ef}; +unsigned short LOGSQ2[4] = {0x3fd6,0x2e42,0xfefa,0x39ef}; +unsigned short THPIO4[4] = {0x4002,0xd97c,0x7f33,0x21d2}; +unsigned short TWOOPI[4] = {0x3fe4,0x5f30,0x6dc9,0xc883}; +#ifdef INFINITIES +unsigned short INFINITY[4] = {0x7ff0,0x0000,0x0000,0x0000}; +#else +unsigned short INFINITY[4] = {0x7fef,0xffff,0xffff,0xffff}; +#endif +#ifdef NANS +unsigned short NAN[4] = {0x7ff8,0x0000,0x0000,0x0000}; +#else +unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#ifdef MINUSZERO +unsigned short NEGZERO[4] = {0x8000,0x0000,0x0000,0x0000}; +#else +unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#endif + +#ifdef DEC + /* 2**-56 = 1.38777878078144567553E-17 */ +unsigned short MACHEP[4] = {0022200,0000000,0000000,0000000}; +unsigned short UFLOWTHRESH[4] = {0x0080,0x0000,0x0000,0x0000}; + /* log 2**127 = 88.029691931113054295988 */ +unsigned short MAXLOG[4] = {041660,007463,0143742,025733,}; + /* log 2**-128 = -88.72283911167299960540 */ +unsigned short MINLOG[4] = {0141661,071027,0173721,0147572,}; + /* 2**127 = 1.701411834604692317316873e38 */ +unsigned short MAXNUM[4] = {077777,0177777,0177777,0177777,}; +unsigned short PI[4] = {040511,007732,0121041,064302,}; +unsigned short PIO2[4] = {040311,007732,0121041,064302,}; +unsigned short PIO4[4] = {040111,007732,0121041,064302,}; +unsigned short SQRT2[4] = {040265,002363,031771,0157145,}; +unsigned short SQRTH[4] = {040065,002363,031771,0157144,}; +unsigned short LOG2E[4] = {040270,0125073,024534,013761,}; +unsigned short SQ2OPI[4] = {040114,041051,0117241,0131204,}; +unsigned short LOGE2[4] = {040061,071027,0173721,0147572,}; +unsigned short LOGSQ2[4] = {037661,071027,0173721,0147572,}; +unsigned short THPIO4[4] = {040426,0145743,0174631,007222,}; +unsigned short TWOOPI[4] = {040042,0174603,067116,042025,}; +/* Approximate infinity by MAXNUM. */ +unsigned short INFINITY[4] = {077777,0177777,0177777,0177777,}; +unsigned short NAN[4] = {0000000,0000000,0000000,0000000}; +#ifdef MINUSZERO +unsigned short NEGZERO[4] = {0000000,0000000,0000000,0100000}; +#else +unsigned short NEGZERO[4] = {0000000,0000000,0000000,0000000}; +#endif +#endif + +#ifndef UNK +extern unsigned short MACHEP[]; +extern unsigned short UFLOWTHRESH[]; +extern unsigned short MAXLOG[]; +extern unsigned short UNDLOG[]; +extern unsigned short MINLOG[]; +extern unsigned short MAXNUM[]; +extern unsigned short PI[]; +extern unsigned short PIO2[]; +extern unsigned short PIO4[]; +extern unsigned short SQRT2[]; +extern unsigned short SQRTH[]; +extern unsigned short LOG2E[]; +extern unsigned short SQ2OPI[]; +extern unsigned short LOGE2[]; +extern unsigned short LOGSQ2[]; +extern unsigned short THPIO4[]; +extern unsigned short TWOOPI[]; +extern unsigned short INFINITY[]; +extern unsigned short NAN[]; +extern unsigned short NEGZERO[]; +#endif diff --git a/src/math/cosh.c b/src/math/cosh.c new file mode 100644 index 000000000..d69f5b344 --- /dev/null +++ b/src/math/cosh.c @@ -0,0 +1,83 @@ +/* cosh.c + * + * Hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * double x, y, cosh(); + * + * y = cosh( x ); + * + * + * + * DESCRIPTION: + * + * Returns hyperbolic cosine of argument in the range MINLOG to + * MAXLOG. + * + * cosh(x) = ( exp(x) + exp(-x) )/2. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC +- 88 50000 4.0e-17 7.7e-18 + * IEEE +-MAXLOG 30000 2.6e-16 5.7e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * cosh overflow |x| > MAXLOG MAXNUM + * + * + */ + +/* cosh.c */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1985, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" +#ifdef ANSIPROT +extern double c_exp ( double ); +extern int isnan ( double ); +extern int isfinite ( double ); +#else +double c_exp(); +int isnan(), isfinite(); +#endif +extern double MAXLOG, INFINITY, LOGE2; + +double c_cosh(x) +double x; +{ +double y; + +#ifdef NANS +if( isnan(x) ) + return(x); +#endif +if( x < 0 ) + x = -x; +if( x > (MAXLOG + LOGE2) ) + { + mtherr( "cosh", OVERFLOW ); + return( INFINITY ); + } +if( x >= (MAXLOG - LOGE2) ) + { + y = c_exp(0.5 * x); + y = (0.5 * y) * y; + return(y); + } +y = c_exp(x); +y = 0.5 * (y + 1.0 / y); +return( y ); +} diff --git a/src/math/exp.c b/src/math/exp.c new file mode 100644 index 000000000..7d2b1e88f --- /dev/null +++ b/src/math/exp.c @@ -0,0 +1,182 @@ +/* exp.c + * + * Exponential function + * + * + * + * SYNOPSIS: + * + * double x, y, exp(); + * + * y = exp( x ); + * + * + * + * DESCRIPTION: + * + * Returns e (2.71828...) raised to the x power. + * + * Range reduction is accomplished by separating the argument + * into an integer k and fraction f such that + * + * x k f + * e = 2 e. + * + * A Pade' form 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) + * of degree 2/3 is used to approximate exp(f) in the basic + * interval [-0.5, 0.5]. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC 0, MAXLOG 38000 3.0e-17 6.2e-18 + * IEEE +- 708 40000 2.0e-16 5.6e-17 + * + * + * Error amplification in the exponential function can be + * a serious matter. The error propagation involves + * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), + * which shows that a 1 lsb error in representing X produces + * a relative error of X times 1 lsb in the function. + * While the routine gives an accurate result for arguments + * that are exactly represented by a double precision + * computer number, the result contains amplified roundoff + * error for large arguments not exactly represented. + * + * + * ERROR MESSAGES: + * + * message condition value returned + * exp underflow x < MINLOG 0.0 + * exp overflow x > MAXLOG MAXNUM + * + */ + +/* +Cephes Math Library Release 2.2: January, 1991 +Copyright 1984, 1991 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + + +/* Exponential function */ + +#include "mconf.h" +static char fname[] = {"exp"}; + +#ifdef UNK + +static double P[] = { + 1.26177193074810590878E-4, + 3.02994407707441961300E-2, + 9.99999999999999999910E-1, +}; +static double Q[] = { + 3.00198505138664455042E-6, + 2.52448340349684104192E-3, + 2.27265548208155028766E-1, + 2.00000000000000000009E0, +}; +static double C1 = 6.93145751953125E-1; +static double C2 = 1.42860682030941723212E-6; +#endif + +#ifdef DEC +static short P[] = { +0035004,0047156,0127442,0057502, +0036770,0033210,0063121,0061764, +0040200,0000000,0000000,0000000, +}; +static short Q[] = { +0033511,0072665,0160662,0176377, +0036045,0070715,0124105,0132777, +0037550,0134114,0142077,0001637, +0040400,0000000,0000000,0000000, +}; +static short sc1[] = {0040061,0071000,0000000,0000000}; +#define C1 (*(double *)sc1) +static short sc2[] = {0033277,0137216,0075715,0057117}; +#define C2 (*(double *)sc2) +#endif + +#ifdef IBMPC +static short P[] = { +0x4be8,0xd5e4,0x89cd,0x3f20, +0x2c7e,0x0cca,0x06d1,0x3f9f, +0x0000,0x0000,0x0000,0x3ff0, +}; +static short Q[] = { +0x5fa0,0xbc36,0x2eb6,0x3ec9, +0xb6c0,0xb508,0xae39,0x3f64, +0xe074,0x9887,0x1709,0x3fcd, +0x0000,0x0000,0x0000,0x4000, +}; +static short sc1[] = {0x0000,0x0000,0x2e40,0x3fe6}; +#define C1 (*(double *)sc1) +static short sc2[] = {0xabca,0xcf79,0xf7d1,0x3eb7}; +#define C2 (*(double *)sc2) +#endif + +#ifdef MIEEE +static short P[] = { +0x3f20,0x89cd,0xd5e4,0x4be8, +0x3f9f,0x06d1,0x0cca,0x2c7e, +0x3ff0,0x0000,0x0000,0x0000, +}; +static short Q[] = { +0x3ec9,0x2eb6,0xbc36,0x5fa0, +0x3f64,0xae39,0xb508,0xb6c0, +0x3fcd,0x1709,0x9887,0xe074, +0x4000,0x0000,0x0000,0x0000, +}; +static short sc1[] = {0x3fe6,0x2e40,0x0000,0x0000}; +#define C1 (*(double *)sc1) +static short sc2[] = {0x3eb7,0xf7d1,0xcf79,0xabca}; +#define C2 (*(double *)sc2) +#endif + +extern double LOGE2, LOG2E, MAXLOG, MINLOG, MAXNUM; + +double c_exp(x) +double x; +{ +double px, xx; +int n; +double polevl(), floor(), ldexp(); + +if( x > MAXLOG) + { + mtherr( fname, OVERFLOW ); + return( MAXNUM ); + } + +if( x < MINLOG ) + { + mtherr( fname, UNDERFLOW ); + return(0.0); + } + +/* Express e**x = e**g 2**n + * = e**g e**( n loge(2) ) + * = e**( g + n loge(2) ) + */ +px = floor( LOG2E * x + 0.5 ); /* floor() truncates toward -infinity. */ +n = (int)px; +x -= px * C1; +x -= px * C2; + +/* rational approximation for exponential + * of the fractional part: + * e**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) + */ +xx = x * x; +px = x * polevl( xx, P, 2 ); +x = px/( polevl( xx, Q, 3 ) - px ); +x = 1.0 + ldexp( x, 1 ); + +/* multiply by power of 2 */ +x = ldexp( x, n ); +return(x); +} diff --git a/src/math/fastsin.cpp b/src/math/fastsin.cpp new file mode 100644 index 000000000..36f59dbb4 --- /dev/null +++ b/src/math/fastsin.cpp @@ -0,0 +1,106 @@ +/* +** fastsin.cpp +** a table/linear interpolation-based sine function that is both +** precise and fast enough for most purposes. +** +**--------------------------------------------------------------------------- +** Copyright 2015 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include "cmath.h" + + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +FFastTrig fasttrig; + +FFastTrig::FFastTrig() +{ + const double pimul = M_PI * 2 / TBLPERIOD; + + for (int i = 0; i < 2049; i++) + { + sinetable[i] = (float)c_sin(i*pimul); + } +} + +__forceinline double FFastTrig::sinq1(unsigned bangle) +{ + unsigned int index = bangle >> BITSHIFT; + + if ((bangle &= (REMAINDER)) == 0) // This is to avoid precision problems at 180° + { + return double(sinetable[index]); + } + else + { + return (double(sinetable[index]) * (REMAINDER - bangle) + double(sinetable[index + 1]) * bangle) * (1. / REMAINDER); + } +} + +double FFastTrig::sin(unsigned bangle) +{ + switch (bangle & 0xc0000000) + { + default: + return sinq1(bangle); + + case 0x40000000: + return sinq1(0x80000000 - bangle); + + case 0x80000000: + return -sinq1(bangle - 0x80000000); + + case 0xc0000000: + return -sinq1(0 - bangle); + } +} + + +double FFastTrig::cos(unsigned bangle) +{ + switch (bangle & 0xc0000000) + { + default: + return sinq1(0x40000000 - bangle); + + case 0x40000000: + return -sinq1(bangle - 0x40000000); + + case 0x80000000: + return -sinq1(0xc0000000 - bangle); + + case 0xc0000000: + return sinq1(bangle - 0xc0000000); + } +} + diff --git a/src/math/isnan.c b/src/math/isnan.c new file mode 100644 index 000000000..b5341e650 --- /dev/null +++ b/src/math/isnan.c @@ -0,0 +1,237 @@ +/* isnan() + * signbit() + * isfinite() + * + * Floating point numeric utilities + * + * + * + * SYNOPSIS: + * + * double ceil(), floor(), frexp(), ldexp(); + * int signbit(), isnan(), isfinite(); + * double x, y; + * int expnt, n; + * + * y = floor(x); + * y = ceil(x); + * y = frexp( x, &expnt ); + * y = ldexp( x, n ); + * n = signbit(x); + * n = isnan(x); + * n = isfinite(x); + * + * + * + * DESCRIPTION: + * + * All four routines return a double precision floating point + * result. + * + * floor() returns the largest integer less than or equal to x. + * It truncates toward minus infinity. + * + * ceil() returns the smallest integer greater than or equal + * to x. It truncates toward plus infinity. + * + * frexp() extracts the exponent from x. It returns an integer + * power of two to expnt and the significand between 0.5 and 1 + * to y. Thus x = y * 2**expn. + * + * ldexp() multiplies x by 2**n. + * + * signbit(x) returns 1 if the sign bit of x is 1, else 0. + * + * These functions are part of the standard C run time library + * for many but not all C compilers. The ones supplied are + * written in C for either DEC or IEEE arithmetic. They should + * be used only if your compiler library does not already have + * them. + * + * The IEEE versions assume that denormal numbers are implemented + * in the arithmetic. Some modifications will be required if + * the arithmetic has abrupt rather than gradual underflow. + */ + + +/* +Cephes Math Library Release 2.3: March, 1995 +Copyright 1984, 1995 by Stephen L. Moshier +*/ + + +#include "mconf.h" + +#ifdef UNK +/* ceil(), floor(), frexp(), ldexp() may need to be rewritten. */ +#undef UNK +#if BIGENDIAN +#define MIEEE 1 +#else +#define IBMPC 1 +#endif +#endif + + +/* Return 1 if the sign bit of x is 1, else 0. */ + +int signbit(x) +double x; +{ +union + { + double d; + short s[4]; + int i[2]; + } u; + +u.d = x; + +if( sizeof(int) == 4 ) + { +#ifdef IBMPC + return( u.i[1] < 0 ); +#endif +#ifdef DEC + return( u.s[3] < 0 ); +#endif +#ifdef MIEEE + return( u.i[0] < 0 ); +#endif + } +else + { +#ifdef IBMPC + return( u.s[3] < 0 ); +#endif +#ifdef DEC + return( u.s[3] < 0 ); +#endif +#ifdef MIEEE + return( u.s[0] < 0 ); +#endif + } +} + + +/* Return 1 if x is a number that is Not a Number, else return 0. */ + +int isnan(x) +double x; +{ +#ifdef NANS +union + { + double d; + unsigned short s[4]; + unsigned int i[2]; + } u; + +u.d = x; + +if( sizeof(int) == 4 ) + { +#ifdef IBMPC + if( ((u.i[1] & 0x7ff00000) == 0x7ff00000) + && (((u.i[1] & 0x000fffff) != 0) || (u.i[0] != 0))) + return 1; +#endif +#ifdef DEC + if( (u.s[1] & 0x7fff) == 0) + { + if( (u.s[2] | u.s[1] | u.s[0]) != 0 ) + return(1); + } +#endif +#ifdef MIEEE + if( ((u.i[0] & 0x7ff00000) == 0x7ff00000) + && (((u.i[0] & 0x000fffff) != 0) || (u.i[1] != 0))) + return 1; +#endif + return(0); + } +else + { /* size int not 4 */ +#ifdef IBMPC + if( (u.s[3] & 0x7ff0) == 0x7ff0) + { + if( ((u.s[3] & 0x000f) | u.s[2] | u.s[1] | u.s[0]) != 0 ) + return(1); + } +#endif +#ifdef DEC + if( (u.s[3] & 0x7fff) == 0) + { + if( (u.s[2] | u.s[1] | u.s[0]) != 0 ) + return(1); + } +#endif +#ifdef MIEEE + if( (u.s[0] & 0x7ff0) == 0x7ff0) + { + if( ((u.s[0] & 0x000f) | u.s[1] | u.s[2] | u.s[3]) != 0 ) + return(1); + } +#endif + return(0); + } /* size int not 4 */ + +#else +/* No NANS. */ +return(0); +#endif +} + + +/* Return 1 if x is not infinite and is not a NaN. */ + +int isfinite(x) +double x; +{ +#ifdef INFINITIES +union + { + double d; + unsigned short s[4]; + unsigned int i[2]; + } u; + +u.d = x; + +if( sizeof(int) == 4 ) + { +#ifdef IBMPC + if( (u.i[1] & 0x7ff00000) != 0x7ff00000) + return 1; +#endif +#ifdef DEC + if( (u.s[3] & 0x7fff) != 0) + return 1; +#endif +#ifdef MIEEE + if( (u.i[0] & 0x7ff00000) != 0x7ff00000) + return 1; +#endif + return(0); + } +else + { +#ifdef IBMPC + if( (u.s[3] & 0x7ff0) != 0x7ff0) + return 1; +#endif +#ifdef DEC + if( (u.s[3] & 0x7fff) != 0) + return 1; +#endif +#ifdef MIEEE + if( (u.s[0] & 0x7ff0) != 0x7ff0) + return 1; +#endif + return(0); + } +#else +/* No INFINITY. */ +return(1); +#endif +} diff --git a/src/math/log.c b/src/math/log.c new file mode 100644 index 000000000..34a8faf02 --- /dev/null +++ b/src/math/log.c @@ -0,0 +1,341 @@ +/* log.c + * + * Natural logarithm + * + * + * + * SYNOPSIS: + * + * double x, y, log(); + * + * y = log( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base e (2.718...) logarithm of x. + * + * The argument is separated into its exponent and fractional + * parts. If the exponent is between -1 and +1, the logarithm + * of the fraction is approximated by + * + * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). + * + * Otherwise, setting z = 2(x-1)/x+1), + * + * log(x) = z + z**3 P(z)/Q(z). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.5, 2.0 150000 1.44e-16 5.06e-17 + * IEEE +-MAXNUM 30000 1.20e-16 4.78e-17 + * DEC 0, 10 170000 1.8e-17 6.3e-18 + * + * In the tests over the interval [+-MAXNUM], the logarithms + * of the random arguments were uniformly distributed over + * [0, MAXLOG]. + * + * ERROR MESSAGES: + * + * log singularity: x = 0; returns -INFINITY + * log domain: x < 0; returns NAN + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" +static char fname[] = {"log"}; + +/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + */ +#ifdef UNK +static double P[] = { + 1.01875663804580931796E-4, + 4.97494994976747001425E-1, + 4.70579119878881725854E0, + 1.44989225341610930846E1, + 1.79368678507819816313E1, + 7.70838733755885391666E0, +}; +static double Q[] = { +/* 1.00000000000000000000E0, */ + 1.12873587189167450590E1, + 4.52279145837532221105E1, + 8.29875266912776603211E1, + 7.11544750618563894466E1, + 2.31251620126765340583E1, +}; +#endif + +#ifdef DEC +static unsigned short P[] = { +0037777,0127270,0162547,0057274, +0041001,0054665,0164317,0005341, +0041451,0034104,0031640,0105773, +0041677,0011276,0123617,0160135, +0041701,0126603,0053215,0117250, +0041420,0115777,0135206,0030232, +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0041220,0144332,0045272,0174241, +0041742,0164566,0035720,0130431, +0042246,0126327,0166065,0116357, +0042372,0033420,0157525,0124560, +0042271,0167002,0066537,0172303, +0041730,0164777,0113711,0044407, +}; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x1bb0,0x93c3,0xb4c2,0x3f1a, +0x52f2,0x3f56,0xd6f5,0x3fdf, +0x6911,0xed92,0xd2ba,0x4012, +0xeb2e,0xc63e,0xff72,0x402c, +0xc84d,0x924b,0xefd6,0x4031, +0xdcf8,0x7d7e,0xd563,0x401e, +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0xef8e,0xae97,0x9320,0x4026, +0xc033,0x4e19,0x9d2c,0x4046, +0xbdbd,0xa326,0xbf33,0x4054, +0xae21,0xeb5e,0xc9e2,0x4051, +0x25b2,0x9e1f,0x200a,0x4037, +}; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0x3f1a,0xb4c2,0x93c3,0x1bb0, +0x3fdf,0xd6f5,0x3f56,0x52f2, +0x4012,0xd2ba,0xed92,0x6911, +0x402c,0xff72,0xc63e,0xeb2e, +0x4031,0xefd6,0x924b,0xc84d, +0x401e,0xd563,0x7d7e,0xdcf8, +}; +static unsigned short Q[] = { +/*0x3ff0,0x0000,0x0000,0x0000,*/ +0x4026,0x9320,0xae97,0xef8e, +0x4046,0x9d2c,0x4e19,0xc033, +0x4054,0xbf33,0xa326,0xbdbd, +0x4051,0xc9e2,0xeb5e,0xae21, +0x4037,0x200a,0x9e1f,0x25b2, +}; +#endif + +/* Coefficients for log(x) = z + z**3 P(z)/Q(z), + * where z = 2(x-1)/(x+1) + * 1/sqrt(2) <= x < sqrt(2) + */ + +#ifdef UNK +static double R[3] = { +-7.89580278884799154124E-1, + 1.63866645699558079767E1, +-6.41409952958715622951E1, +}; +static double S[3] = { +/* 1.00000000000000000000E0,*/ +-3.56722798256324312549E1, + 3.12093766372244180303E2, +-7.69691943550460008604E2, +}; +#endif +#ifdef DEC +static unsigned short R[12] = { +0140112,0020756,0161540,0072035, +0041203,0013743,0114023,0155527, +0141600,0044060,0104421,0050400, +}; +static unsigned short S[12] = { +/*0040200,0000000,0000000,0000000,*/ +0141416,0130152,0017543,0064122, +0042234,0006000,0104527,0020155, +0142500,0066110,0146631,0174731, +}; +#endif +#ifdef IBMPC +static unsigned short R[12] = { +0x0e84,0xdc6c,0x443d,0xbfe9, +0x7b6b,0x7302,0x62fc,0x4030, +0x2a20,0x1122,0x0906,0xc050, +}; +static unsigned short S[12] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0x6d0a,0x43ec,0xd60d,0xc041, +0xe40e,0x112a,0x8180,0x4073, +0x3f3b,0x19b3,0x0d89,0xc088, +}; +#endif +#ifdef MIEEE +static unsigned short R[12] = { +0xbfe9,0x443d,0xdc6c,0x0e84, +0x4030,0x62fc,0x7302,0x7b6b, +0xc050,0x0906,0x1122,0x2a20, +}; +static unsigned short S[12] = { +/*0x3ff0,0x0000,0x0000,0x0000,*/ +0xc041,0xd60d,0x43ec,0x6d0a, +0x4073,0x8180,0x112a,0xe40e, +0xc088,0x0d89,0x19b3,0x3f3b, +}; +#endif + +#ifdef ANSIPROT +extern double frexp ( double, int * ); +extern double ldexp ( double, int ); +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern int isnan ( double ); +extern int isfinite ( double ); +#else +double frexp(), ldexp(), polevl(), p1evl(); +int isnan(), isfinite(); +#endif +#define SQRTH 0.70710678118654752440 +extern double INFINITY, NAN; + +double c_log(x) +double x; +{ +int e; +#ifdef DEC +short *q; +#endif +double y, z; + +#ifdef NANS +if( isnan(x) ) + return(x); +#endif +#ifdef INFINITIES +if( x == INFINITY ) + return(x); +#endif +/* Test for domain */ +if( x <= 0.0 ) + { + if( x == 0.0 ) + { + mtherr( fname, SING ); + return( -INFINITY ); + } + else + { + mtherr( fname, DOMAIN ); + return( NAN ); + } + } + +/* separate mantissa from exponent */ + +#ifdef DEC +q = (short *)&x; +e = *q; /* short containing exponent */ +e = ((e >> 7) & 0377) - 0200; /* the exponent */ +*q &= 0177; /* strip exponent from x */ +*q |= 040000; /* x now between 0.5 and 1 */ +#endif + +/* Note, frexp is used so that denormal numbers + * will be handled properly. + */ +#ifdef IBMPC +x = frexp( x, &e ); +/* +q = (short *)&x; +q += 3; +e = *q; +e = ((e >> 4) & 0x0fff) - 0x3fe; +*q &= 0x0f; +*q |= 0x3fe0; +*/ +#endif + +/* Equivalent C language standard library function: */ +#ifdef UNK +x = frexp( x, &e ); +#endif + +#ifdef MIEEE +x = frexp( x, &e ); +#endif + + + +/* logarithm using log(x) = z + z**3 P(z)/Q(z), + * where z = 2(x-1)/x+1) + */ + +if( (e > 2) || (e < -2) ) +{ +if( x < SQRTH ) + { /* 2( 2x-1 )/( 2x+1 ) */ + e -= 1; + z = x - 0.5; + y = 0.5 * z + 0.5; + } +else + { /* 2 (x-1)/(x+1) */ + z = x - 0.5; + z -= 0.5; + y = 0.5 * x + 0.5; + } + +x = z / y; + + +/* rational form */ +z = x*x; +z = x * ( z * polevl( z, R, 2 ) / p1evl( z, S, 3 ) ); +y = e; +z = z - y * 2.121944400546905827679e-4; +z = z + x; +z = z + e * 0.693359375; +goto ldone; +} + + + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + +if( x < SQRTH ) + { + e -= 1; + x = ldexp( x, 1 ) - 1.0; /* 2x - 1 */ + } +else + { + x = x - 1.0; + } + + +/* rational form */ +z = x*x; +#if DEC +y = x * ( z * polevl( x, P, 5 ) / p1evl( x, Q, 6 ) ); +#else +y = x * ( z * polevl( x, P, 5 ) / p1evl( x, Q, 5 ) ); +#endif +if( e ) + y = y - e * 2.121944400546905827679e-4; +y = y - ldexp( z, -1 ); /* y - 0.5 * z */ +z = x + y; +if( e ) + z = z + e * 0.693359375; + +ldone: + +return( z ); +} diff --git a/src/math/log10.c b/src/math/log10.c new file mode 100644 index 000000000..df67d30b9 --- /dev/null +++ b/src/math/log10.c @@ -0,0 +1,250 @@ +/* log10.c + * + * Common logarithm + * + * + * + * SYNOPSIS: + * + * double x, y, log10(); + * + * y = log10( x ); + * + * + * + * DESCRIPTION: + * + * Returns logarithm to the base 10 of x. + * + * The argument is separated into its exponent and fractional + * parts. The logarithm of the fraction is approximated by + * + * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.5, 2.0 30000 1.5e-16 5.0e-17 + * IEEE 0, MAXNUM 30000 1.4e-16 4.8e-17 + * DEC 1, MAXNUM 50000 2.5e-17 6.0e-18 + * + * In the tests over the interval [1, MAXNUM], the logarithms + * of the random arguments were uniformly distributed over + * [0, MAXLOG]. + * + * ERROR MESSAGES: + * + * log10 singularity: x = 0; returns -INFINITY + * log10 domain: x < 0; returns NAN + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" +static char fname[] = {"log10"}; + +/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + */ +#ifdef UNK +static double P[] = { + 4.58482948458143443514E-5, + 4.98531067254050724270E-1, + 6.56312093769992875930E0, + 2.97877425097986925891E1, + 6.06127134467767258030E1, + 5.67349287391754285487E1, + 1.98892446572874072159E1 +}; +static double Q[] = { +/* 1.00000000000000000000E0, */ + 1.50314182634250003249E1, + 8.27410449222435217021E1, + 2.20664384982121929218E2, + 3.07254189979530058263E2, + 2.14955586696422947765E2, + 5.96677339718622216300E1 +}; +#endif + +#ifdef DEC +static unsigned short P[] = { +0034500,0046473,0051374,0135174, +0037777,0037566,0145712,0150321, +0040722,0002426,0031543,0123107, +0041356,0046513,0170752,0004346, +0041562,0071553,0023536,0163343, +0041542,0170221,0024316,0114216, +0041237,0016454,0046611,0104602 +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0041160,0100260,0067736,0102424, +0041645,0075552,0036563,0147072, +0042134,0125025,0021132,0025320, +0042231,0120211,0046030,0103271, +0042126,0172241,0052151,0120426, +0041556,0125702,0072116,0047103 +}; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x974f,0x6a5f,0x09a7,0x3f08, +0x5a1a,0xd979,0xe7ee,0x3fdf, +0x74c9,0xc66c,0x40a2,0x401a, +0x411d,0x7e3d,0xc9a9,0x403d, +0xdcdc,0x64eb,0x4e6d,0x404e, +0xd312,0x2519,0x5e12,0x404c, +0x3130,0x89b1,0xe3a5,0x4033 +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0xd0a2,0x0dfb,0x1016,0x402e, +0x79c7,0x47ae,0xaf6d,0x4054, +0x455a,0xa44b,0x9542,0x406b, +0x10d7,0x2983,0x3411,0x4073, +0x3423,0x2a8d,0xde94,0x406a, +0xc9c8,0x4e89,0xd578,0x404d +}; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0x3f08,0x09a7,0x6a5f,0x974f, +0x3fdf,0xe7ee,0xd979,0x5a1a, +0x401a,0x40a2,0xc66c,0x74c9, +0x403d,0xc9a9,0x7e3d,0x411d, +0x404e,0x4e6d,0x64eb,0xdcdc, +0x404c,0x5e12,0x2519,0xd312, +0x4033,0xe3a5,0x89b1,0x3130 +}; +static unsigned short Q[] = { +0x402e,0x1016,0x0dfb,0xd0a2, +0x4054,0xaf6d,0x47ae,0x79c7, +0x406b,0x9542,0xa44b,0x455a, +0x4073,0x3411,0x2983,0x10d7, +0x406a,0xde94,0x2a8d,0x3423, +0x404d,0xd578,0x4e89,0xc9c8 +}; +#endif + +#define SQRTH 0.70710678118654752440 +#define L102A 3.0078125E-1 +#define L102B 2.48745663981195213739E-4 +#define L10EA 4.3359375E-1 +#define L10EB 7.00731903251827651129E-4 + +#ifdef ANSIPROT +extern double frexp ( double, int * ); +extern double ldexp ( double, int ); +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern int isnan ( double ); +extern int isfinite ( double ); +#else +double frexp(), ldexp(), polevl(), p1evl(); +int isnan(), isfinite(); +#endif +extern double LOGE2, SQRT2, INFINITY, NAN; + +double c_log10(x) +double x; +{ +VOLATILE double z; +double y; +#ifdef DEC +short *q; +#endif +int e; + +#ifdef NANS +if( isnan(x) ) + return(x); +#endif +#ifdef INFINITIES +if( x == INFINITY ) + return(x); +#endif +/* Test for domain */ +if( x <= 0.0 ) + { + if( x == 0.0 ) + { + mtherr( fname, SING ); + return( -INFINITY ); + } + else + { + mtherr( fname, DOMAIN ); + return( NAN ); + } + } + +/* separate mantissa from exponent */ + +#ifdef DEC +q = (short *)&x; +e = *q; /* short containing exponent */ +e = ((e >> 7) & 0377) - 0200; /* the exponent */ +*q &= 0177; /* strip exponent from x */ +*q |= 040000; /* x now between 0.5 and 1 */ +#endif + +#ifdef IBMPC +x = frexp( x, &e ); +/* +q = (short *)&x; +q += 3; +e = *q; +e = ((e >> 4) & 0x0fff) - 0x3fe; +*q &= 0x0f; +*q |= 0x3fe0; +*/ +#endif + +/* Equivalent C language standard library function: */ +#ifdef UNK +x = frexp( x, &e ); +#endif + +#ifdef MIEEE +x = frexp( x, &e ); +#endif + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + +if( x < SQRTH ) + { + e -= 1; + x = ldexp( x, 1 ) - 1.0; /* 2x - 1 */ + } +else + { + x = x - 1.0; + } + + +/* rational form */ +z = x*x; +y = x * ( z * polevl( x, P, 6 ) / p1evl( x, Q, 6 ) ); +y = y - ldexp( z, -1 ); /* y - 0.5 * x**2 */ + +/* multiply log of fraction by log10(e) + * and base 2 exponent by log10(2) + */ +z = (x + y) * L10EB; /* accumulate terms in order of size */ +z += y * L10EA; +z += x * L10EA; +z += e * L102B; +z += e * L102A; + + +return( z ); +} diff --git a/src/math/mconf.h b/src/math/mconf.h new file mode 100644 index 000000000..6e8e982ff --- /dev/null +++ b/src/math/mconf.h @@ -0,0 +1,199 @@ +/* mconf.h + * + * Common include file for math routines + * + * + * + * SYNOPSIS: + * + * #include "mconf.h" + * + * + * + * DESCRIPTION: + * + * This file contains definitions for error codes that are + * passed to the common error handling routine mtherr() + * (which see). + * + * The file also includes a conditional assembly definition + * for the type of computer arithmetic (IEEE, DEC, Motorola + * IEEE, or UNKnown). + * + * For Digital Equipment PDP-11 and VAX computers, certain + * IBM systems, and others that use numbers with a 56-bit + * significand, the symbol DEC should be defined. In this + * mode, most floating point constants are given as arrays + * of octal integers to eliminate decimal to binary conversion + * errors that might be introduced by the compiler. + * + * For little-endian computers, such as IBM PC, that follow the + * IEEE Standard for Binary Floating Point Arithmetic (ANSI/IEEE + * Std 754-1985), the symbol IBMPC should be defined. These + * numbers have 53-bit significands. In this mode, constants + * are provided as arrays of hexadecimal 16 bit integers. + * + * Big-endian IEEE format is denoted MIEEE. On some RISC + * systems such as Sun SPARC, double precision constants + * must be stored on 8-byte address boundaries. Since integer + * arrays may be aligned differently, the MIEEE configuration + * may fail on such machines. + * + * To accommodate other types of computer arithmetic, all + * constants are also provided in a normal decimal radix + * which one can hope are correctly converted to a suitable + * format by the available C language compiler. To invoke + * this mode, define the symbol UNK. + * + * An important difference among these modes is a predefined + * set of machine arithmetic constants for each. The numbers + * MACHEP (the machine roundoff error), MAXNUM (largest number + * represented), and several other parameters are preset by + * the configuration symbol. Check the file const.c to + * ensure that these values are correct for your computer. + * + * Configurations NANS, INFINITIES, MINUSZERO, and DENORMAL + * may fail on many systems. Verify that they are supposed + * to work on your computer. + */ +/* +Cephes Math Library Release 2.3: June, 1995 +Copyright 1984, 1987, 1989, 1995 by Stephen L. Moshier +*/ + + +/* Define if the `long double' type works. */ +//#define HAVE_LONG_DOUBLE 0 + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define if floating point words are bigendian. */ +/* #undef FLOAT_WORDS_BIGENDIAN */ + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Name of package */ +#define PACKAGE "cephes" + +/* Version number of package */ +#define VERSION "2.7" + +/* Constant definitions for math error conditions + */ + +#define DOMAIN 1 /* argument domain error */ +#define SING 2 /* argument singularity */ +#define OVERFLOW 3 /* overflow range error */ +#define UNDERFLOW 4 /* underflow range error */ +#define TLOSS 5 /* total loss of precision */ +#define PLOSS 6 /* partial loss of precision */ + +#define EDOM 33 +#define ERANGE 34 +/* Complex numeral. */ +typedef struct + { + double r; + double i; + } cmplx; + +#ifdef HAVE_LONG_DOUBLE +/* Long double complex numeral. */ +typedef struct + { + long double r; + long double i; + } cmplxl; +#endif + + +/* Type of computer arithmetic */ + +/* PDP-11, Pro350, VAX: + */ +/* #define DEC 1 */ + +/* Intel IEEE, low order words come first: + */ +//#define IBMPC 1 + +/* Motorola IEEE, high order words come first + * (Sun 680x0 workstation): + */ +/* #define MIEEE 1 */ + +/* UNKnown arithmetic, invokes coefficients given in + * normal decimal format. Beware of range boundary + * problems (MACHEP, MAXLOG, etc. in const.c) and + * roundoff problems in pow.c: + * (Sun SPARCstation) + */ +#define UNK 1 + +/* If you define UNK, then be sure to set BIGENDIAN properly. */ +#ifdef FLOAT_WORDS_BIGENDIAN +#define BIGENDIAN 1 +#else +#define BIGENDIAN 0 +#endif +/* Define this `volatile' if your compiler thinks + * that floating point arithmetic obeys the associative + * and distributive laws. It will defeat some optimizations + * (but probably not enough of them). + * + * #define VOLATILE volatile + */ +#define VOLATILE + +/* For 12-byte long doubles on an i386, pad a 16-bit short 0 + * to the end of real constants initialized by integer arrays. + * + * #define XPD 0, + * + * Otherwise, the type is 10 bytes long and XPD should be + * defined blank (e.g., Microsoft C). + * + * #define XPD + */ +#define XPD 0, + +/* Define to support tiny denormal numbers, else undefine. */ +#define DENORMAL 1 + +/* Define to ask for infinity support, else undefine. */ +#define INFINITIES 1 + +/* Define to ask for support of numbers that are Not-a-Number, + else undefine. This may automatically define INFINITIES in some files. */ +#define NANS 1 + +/* Define to distinguish between -0.0 and +0.0. */ +#define MINUSZERO 1 + +/* Define 1 for ANSI C atan2() function + See atan.c and clog.c. */ +#define ANSIC 1 + +/* Get ANSI function prototypes, if you want them. */ +#if 1 +/* #ifdef __STDC__ */ +#define ANSIPROT 1 +int mtherr ( char *, int ); +#else +int mtherr(); +#endif + +/* Variable for error reporting. See mtherr.c. */ +extern int merror; diff --git a/src/math/mtherr.c b/src/math/mtherr.c new file mode 100644 index 000000000..0d94cd14d --- /dev/null +++ b/src/math/mtherr.c @@ -0,0 +1,102 @@ +/* mtherr.c + * + * Library common error handling routine + * + * + * + * SYNOPSIS: + * + * char *fctnam; + * int code; + * int mtherr(); + * + * mtherr( fctnam, code ); + * + * + * + * DESCRIPTION: + * + * This routine may be called to report one of the following + * error conditions (in the include file mconf.h). + * + * Mnemonic Value Significance + * + * DOMAIN 1 argument domain error + * SING 2 function singularity + * OVERFLOW 3 overflow range error + * UNDERFLOW 4 underflow range error + * TLOSS 5 total loss of precision + * PLOSS 6 partial loss of precision + * EDOM 33 Unix domain error code + * ERANGE 34 Unix range error code + * + * The default version of the file prints the function name, + * passed to it by the pointer fctnam, followed by the + * error condition. The display is directed to the standard + * output device. The routine then returns to the calling + * program. Users may wish to modify the program to abort by + * calling exit() under severe error conditions such as domain + * errors. + * + * Since all error conditions pass control to this function, + * the display may be easily changed, eliminated, or directed + * to an error logging device. + * + * SEE ALSO: + * + * mconf.h + * + */ + +/* +Cephes Math Library Release 2.0: April, 1987 +Copyright 1984, 1987 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + +#include +#include "mconf.h" + +int merror = 0; + +/* Notice: the order of appearance of the following + * messages is bound to the error codes defined + * in mconf.h. + */ +static char *ermsg[7] = { +"unknown", /* error code 0 */ +"domain", /* error code 1 */ +"singularity", /* et seq. */ +"overflow", +"underflow", +"total loss of precision", +"partial loss of precision" +}; + + +int mtherr( name, code ) +char *name; +int code; +{ + +/* Display string passed by calling program, + * which is supposed to be the name of the + * function in which the error occurred: + */ +printf( "\n%s ", name ); + +/* Set global error message word */ +merror = code; + +/* Display error message defined + * by the code argument. + */ +if( (code <= 0) || (code >= 7) ) + code = 0; +printf( "%s error\n", ermsg[code] ); + +/* Return to calling + * program + */ +return( 0 ); +} diff --git a/src/math/polevl.c b/src/math/polevl.c new file mode 100644 index 000000000..4d050fbfc --- /dev/null +++ b/src/math/polevl.c @@ -0,0 +1,97 @@ +/* polevl.c + * p1evl.c + * + * Evaluate polynomial + * + * + * + * SYNOPSIS: + * + * int N; + * double x, y, coef[N+1], polevl[]; + * + * y = polevl( x, coef, N ); + * + * + * + * DESCRIPTION: + * + * Evaluates polynomial of degree N: + * + * 2 N + * y = C + C x + C x +...+ C x + * 0 1 2 N + * + * Coefficients are stored in reverse order: + * + * coef[0] = C , ..., coef[N] = C . + * N 0 + * + * The function p1evl() assumes that coef[N] = 1.0 and is + * omitted from the array. Its calling arguments are + * otherwise the same as polevl(). + * + * + * SPEED: + * + * In the interest of speed, there are no checks for out + * of bounds arithmetic. This routine is used by most of + * the functions in the library. Depending on available + * equipment features, the user may wish to rewrite the + * program in microcode or assembly language. + * + */ + + +/* +Cephes Math Library Release 2.1: December, 1988 +Copyright 1984, 1987, 1988 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + + +double polevl( x, coef, N ) +double x; +double coef[]; +int N; +{ +double ans; +int i; +double *p; + +p = coef; +ans = *p++; +i = N; + +do + ans = ans * x + *p++; +while( --i ); + +return( ans ); +} + +/* p1evl() */ +/* N + * Evaluate polynomial when coefficient of x is 1.0. + * Otherwise same as polevl. + */ + +double p1evl( x, coef, N ) +double x; +double coef[]; +int N; +{ +double ans; +double *p; +int i; + +p = coef; +ans = x + *p++; +i = N-1; + +do + ans = ans * x + *p++; +while( --i ); + +return( ans ); +} diff --git a/src/math/readme.txt b/src/math/readme.txt new file mode 100644 index 000000000..965335ee6 --- /dev/null +++ b/src/math/readme.txt @@ -0,0 +1,15 @@ + Some software in this archive may be from the book _Methods and +Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster +International, 1989) or from the Cephes Mathematical Library, a +commercial product. In either event, it is copyrighted by the author. +What you see here may be used freely but it comes with no support or +guarantee. + + The two known misprints in the book are repaired here in the +source listings for the gamma function and the incomplete beta +integral. + + + Stephen L. Moshier + moshier@na-net.ornl.gov + \ No newline at end of file diff --git a/src/math/sin.c b/src/math/sin.c new file mode 100644 index 000000000..3eba0e22f --- /dev/null +++ b/src/math/sin.c @@ -0,0 +1,387 @@ +/* sin.c + * + * Circular sine + * + * + * + * SYNOPSIS: + * + * double x, y, sin(); + * + * y = sin( x ); + * + * + * + * DESCRIPTION: + * + * Range reduction is into intervals of pi/4. The reduction + * error is nearly eliminated by contriving an extended precision + * modular arithmetic. + * + * Two polynomial approximating functions are employed. + * Between 0 and pi/4 the sine is approximated by + * x + x**3 P(x**2). + * Between pi/4 and pi/2 the cosine is represented as + * 1 - x**2 Q(x**2). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC 0, 10 150000 3.0e-17 7.8e-18 + * IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 + * + * ERROR MESSAGES: + * + * message condition value returned + * sin total loss x > 1.073741824e9 0.0 + * + * Partial loss of accuracy begins to occur at x = 2**30 + * = 1.074e9. The loss is not gradual, but jumps suddenly to + * about 1 part in 10e7. Results may be meaningless for + * x > 2**49 = 5.6e14. The routine as implemented flags a + * TLOSS error for x > 2**30 and returns 0.0. + */ + /* cos.c + * + * Circular cosine + * + * + * + * SYNOPSIS: + * + * double x, y, cos(); + * + * y = cos( x ); + * + * + * + * DESCRIPTION: + * + * Range reduction is into intervals of pi/4. The reduction + * error is nearly eliminated by contriving an extended precision + * modular arithmetic. + * + * Two polynomial approximating functions are employed. + * Between 0 and pi/4 the cosine is approximated by + * 1 - x**2 Q(x**2). + * Between pi/4 and pi/2 the sine is represented as + * x + x**3 P(x**2). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 + * DEC 0,+1.07e9 17000 3.0e-17 7.2e-18 + */ + +/* sin.c */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1985, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +static double sincof[] = { + 1.58962301576546568060E-10, +-2.50507477628578072866E-8, + 2.75573136213857245213E-6, +-1.98412698295895385996E-4, + 8.33333333332211858878E-3, +-1.66666666666666307295E-1, +}; +static double coscof[6] = { +-1.13585365213876817300E-11, + 2.08757008419747316778E-9, +-2.75573141792967388112E-7, + 2.48015872888517045348E-5, +-1.38888888888730564116E-3, + 4.16666666666665929218E-2, +}; +static double DP1 = 7.85398125648498535156E-1; +static double DP2 = 3.77489470793079817668E-8; +static double DP3 = 2.69515142907905952645E-15; +/* static double lossth = 1.073741824e9; */ +#endif + +#ifdef DEC +static unsigned short sincof[] = { +0030056,0143750,0177214,0163153, +0131727,0027455,0044510,0175352, +0033470,0167432,0131752,0042414, +0135120,0006400,0146776,0174027, +0036410,0104210,0104207,0137202, +0137452,0125252,0125252,0125103, +}; +static unsigned short coscof[24] = { +0127107,0151115,0002060,0152325, +0031017,0072353,0155161,0174053, +0132623,0171173,0172542,0057056, +0034320,0006400,0147102,0023652, +0135666,0005540,0133012,0076213, +0037052,0125252,0125252,0125126, +}; +/* 7.853981629014015197753906250000E-1 */ +static unsigned short P1[] = {0040111,0007732,0120000,0000000,}; +/* 4.960467869796758577649598009884E-10 */ +static unsigned short P2[] = {0030410,0055060,0100000,0000000,}; +/* 2.860594363054915898381331279295E-18 */ +static unsigned short P3[] = {0021523,0011431,0105056,0001560,}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +#endif + +#ifdef IBMPC +static unsigned short sincof[] = { +0x9ccd,0x1fd1,0xd8fd,0x3de5, +0x1f5d,0xa929,0xe5e5,0xbe5a, +0x48a1,0x567d,0x1de3,0x3ec7, +0xdf03,0x19bf,0x01a0,0xbf2a, +0xf7d0,0x1110,0x1111,0x3f81, +0x5548,0x5555,0x5555,0xbfc5, +}; +static unsigned short coscof[24] = { +0x1a9b,0xa086,0xfa49,0xbda8, +0x3f05,0x7b4e,0xee9d,0x3e21, +0x4bc6,0x7eac,0x7e4f,0xbe92, +0x44f5,0x19c8,0x01a0,0x3efa, +0x4f91,0x16c1,0xc16c,0xbf56, +0x554b,0x5555,0x5555,0x3fa5, +}; +/* + 7.85398125648498535156E-1, + 3.77489470793079817668E-8, + 2.69515142907905952645E-15, +*/ +static unsigned short P1[] = {0x0000,0x4000,0x21fb,0x3fe9}; +static unsigned short P2[] = {0x0000,0x0000,0x442d,0x3e64}; +static unsigned short P3[] = {0x5170,0x98cc,0x4698,0x3ce8}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +#endif + +#ifdef MIEEE +static unsigned short sincof[] = { +0x3de5,0xd8fd,0x1fd1,0x9ccd, +0xbe5a,0xe5e5,0xa929,0x1f5d, +0x3ec7,0x1de3,0x567d,0x48a1, +0xbf2a,0x01a0,0x19bf,0xdf03, +0x3f81,0x1111,0x1110,0xf7d0, +0xbfc5,0x5555,0x5555,0x5548, +}; +static unsigned short coscof[24] = { +0xbda8,0xfa49,0xa086,0x1a9b, +0x3e21,0xee9d,0x7b4e,0x3f05, +0xbe92,0x7e4f,0x7eac,0x4bc6, +0x3efa,0x01a0,0x19c8,0x44f5, +0xbf56,0xc16c,0x16c1,0x4f91, +0x3fa5,0x5555,0x5555,0x554b, +}; +static unsigned short P1[] = {0x3fe9,0x21fb,0x4000,0x0000}; +static unsigned short P2[] = {0x3e64,0x442d,0x0000,0x0000}; +static unsigned short P3[] = {0x3ce8,0x4698,0x98cc,0x5170}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +#endif + +#ifdef ANSIPROT +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern double floor ( double ); +extern double ldexp ( double, int ); +extern int isnan ( double ); +extern int isfinite ( double ); +#else +double polevl(), floor(), ldexp(); +int isnan(), isfinite(); +#endif +extern double PIO4; +static double lossth = 1.073741824e9; +#ifdef NANS +extern double NAN; +#endif +#ifdef INFINITIES +extern double INFINITY; +#endif + + +double c_sin(x) +double x; +{ +double y, z, zz; +int j, sign; + +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +#ifdef NANS +if( isnan(x) ) + return(x); +if( !isfinite(x) ) + { + mtherr( "sin", DOMAIN ); + return(NAN); + } +#endif +/* make argument positive but save the sign */ +sign = 1; +if( x < 0 ) + { + x = -x; + sign = -1; + } + +if( x > lossth ) + { + mtherr( "sin", TLOSS ); + return(0.0); + } + +y = floor( x/PIO4 ); /* integer part of x/PIO4 */ + +/* strip high bits of integer part to prevent integer overflow */ +z = ldexp( y, -4 ); +z = floor(z); /* integer part of y/8 */ +z = y - ldexp( z, 4 ); /* y - 16 * (y/16) */ + +j = (int)z; /* convert to integer for tests on the phase angle */ +/* map zeros to origin */ +if( j & 1 ) + { + j += 1; + y += 1.0; + } +j = j & 07; /* octant modulo 360 degrees */ +/* reflect in x axis */ +if( j > 3) + { + sign = -sign; + j -= 4; + } + +/* Extended precision modular arithmetic */ +z = ((x - y * DP1) - y * DP2) - y * DP3; + +zz = z * z; + +if( (j==1) || (j==2) ) + { + y = 1.0 - ldexp(zz,-1) + zz * zz * polevl( zz, coscof, 5 ); + } +else + { +/* y = z + z * (zz * polevl( zz, sincof, 5 ));*/ + y = z + z * z * z * polevl( zz, sincof, 5 ); + } + +if(sign < 0) + y = -y; + +return(y); +} + + + + + +double c_cos(x) +double x; +{ +double y, z, zz; +int i; +int j, sign; + +#ifdef NANS +if( isnan(x) ) + return(x); +if( !isfinite(x) ) + { + mtherr( "cos", DOMAIN ); + return(NAN); + } +#endif + +/* make argument positive */ +sign = 1; +if( x < 0 ) + x = -x; + +if( x > lossth ) + { + mtherr( "cos", TLOSS ); + return(0.0); + } + +y = floor( x/PIO4 ); +z = ldexp( y, -4 ); +z = floor(z); /* integer part of y/8 */ +z = y - ldexp( z, 4 ); /* y - 16 * (y/16) */ + +/* integer and fractional part modulo one octant */ +i = (int)z; +if( i & 1 ) /* map zeros to origin */ + { + i += 1; + y += 1.0; + } +j = i & 07; +if( j > 3) + { + j -=4; + sign = -sign; + } + +if( j > 1 ) + sign = -sign; + +/* Extended precision modular arithmetic */ +z = ((x - y * DP1) - y * DP2) - y * DP3; + +zz = z * z; + +if( (j==1) || (j==2) ) + { +/* y = z + z * (zz * polevl( zz, sincof, 5 ));*/ + y = z + z * z * z * polevl( zz, sincof, 5 ); + } +else + { + y = 1.0 - ldexp(zz,-1) + zz * zz * polevl( zz, coscof, 5 ); + } + +if(sign < 0) + y = -y; + +return(y); +} + + + + + +/* Degrees, minutes, seconds to radians: */ + +/* 1 arc second, in radians = 4.8481368110953599358991410e-5 */ +#ifdef DEC +static unsigned short P648[] = {034513,054170,0176773,0116043,}; +#define P64800 *(double *)P648 +#else +static double P64800 = 4.8481368110953599358991410e-5; +#endif + +double radian(d,m,s) +double d,m,s; +{ + +return( ((d*60.0 + m)*60.0 + s)*P64800 ); +} diff --git a/src/math/sinh.c b/src/math/sinh.c new file mode 100644 index 000000000..b1d2a7500 --- /dev/null +++ b/src/math/sinh.c @@ -0,0 +1,148 @@ +/* sinh.c + * + * Hyperbolic sine + * + * + * + * SYNOPSIS: + * + * double x, y, sinh(); + * + * y = sinh( x ); + * + * + * + * DESCRIPTION: + * + * Returns hyperbolic sine of argument in the range MINLOG to + * MAXLOG. + * + * The range is partitioned into two segments. If |x| <= 1, a + * rational function of the form x + x**3 P(x)/Q(x) is employed. + * Otherwise the calculation is sinh(x) = ( exp(x) - exp(-x) )/2. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC +- 88 50000 4.0e-17 7.7e-18 + * IEEE +-MAXLOG 30000 2.6e-16 5.7e-17 + * + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +static double P[] = { +-7.89474443963537015605E-1, +-1.63725857525983828727E2, +-1.15614435765005216044E4, +-3.51754964808151394800E5 +}; +static double Q[] = { +/* 1.00000000000000000000E0,*/ +-2.77711081420602794433E2, + 3.61578279834431989373E4, +-2.11052978884890840399E6 +}; +#endif + +#ifdef DEC +static unsigned short P[] = { +0140112,0015377,0042731,0163255, +0142043,0134721,0146177,0123761, +0143464,0122706,0034353,0006017, +0144653,0140536,0157665,0054045 +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0142212,0155404,0133513,0022040, +0044015,0036723,0173271,0011053, +0145400,0150407,0023710,0001034 +}; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x3cd6,0xe8bb,0x435f,0xbfe9, +0xf4fe,0x398f,0x773a,0xc064, +0x6182,0xc71d,0x94b8,0xc0c6, +0xab05,0xdbf6,0x782b,0xc115 +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0x6484,0x96e9,0x5b60,0xc071, +0x2245,0x7ed7,0xa7ba,0x40e1, +0x0044,0xe4f9,0x1a20,0xc140 +}; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0xbfe9,0x435f,0xe8bb,0x3cd6, +0xc064,0x773a,0x398f,0xf4fe, +0xc0c6,0x94b8,0xc71d,0x6182, +0xc115,0x782b,0xdbf6,0xab05 +}; +static unsigned short Q[] = { +0xc071,0x5b60,0x96e9,0x6484, +0x40e1,0xa7ba,0x7ed7,0x2245, +0xc140,0x1a20,0xe4f9,0x0044 +}; +#endif + +#ifdef ANSIPROT +extern double fabs ( double ); +extern double c_exp ( double ); +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +#else +double fabs(), c_exp(), polevl(), p1evl(); +#endif +extern double INFINITY, MINLOG, MAXLOG, LOGE2; + +double c_sinh(x) +double x; +{ +double a; + +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +a = fabs(x); +if( (x > (MAXLOG + LOGE2)) || (x > -(MINLOG-LOGE2) ) ) + { + mtherr( "sinh", DOMAIN ); + if( x > 0 ) + return( INFINITY ); + else + return( -INFINITY ); + } +if( a > 1.0 ) + { + if( a >= (MAXLOG - LOGE2) ) + { + a = c_exp(0.5*a); + a = (0.5 * a) * a; + if( x < 0 ) + a = -a; + return(a); + } + a = c_exp(a); + a = 0.5*a - (0.5/a); + if( x < 0 ) + a = -a; + return(a); + } + +a *= a; +return( x + x * a * (polevl(a,P,3)/p1evl(a,Q,3)) ); +} diff --git a/src/math/sqrt.c b/src/math/sqrt.c new file mode 100644 index 000000000..22ebdc669 --- /dev/null +++ b/src/math/sqrt.c @@ -0,0 +1,178 @@ +/* _sqrt.c + * + * Square root + * + * + * + * SYNOPSIS: + * + * double x, y, _sqrt(); + * + * y = _sqrt( x ); + * + * + * + * DESCRIPTION: + * + * Returns the square root of x. + * + * Range reduction involves isolating the power of two of the + * argument and using a polynomial approximation to obtain + * a rough value for the square root. Then Heron's iteration + * is used three times to converge to an accurate value. + * + * + * + * ACCURACY: + * + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC 0, 10 60000 2.1e-17 7.9e-18 + * IEEE 0,1.7e308 30000 1.7e-16 6.3e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * _sqrt domain x < 0 0.0 + * + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1987, 1988, 2000 by Stephen L. Moshier +*/ + + +#include "mconf.h" +#ifdef ANSIPROT +extern double frexp ( double, int * ); +extern double ldexp ( double, int ); +#else +double frexp(), ldexp(); +#endif +extern double SQRT2; /* _sqrt2 = 1.41421356237309504880 */ + +double c_sqrt(x) +double x; +{ +int e; +#ifndef UNK +short *q; +#endif +double z, w; + +if( x <= 0.0 ) + { + if( x < 0.0 ) + mtherr( "_sqrt", DOMAIN ); + return( 0.0 ); + } +w = x; +/* separate exponent and significand */ +#ifdef UNK +z = frexp( x, &e ); +#endif +#ifdef DEC +q = (short *)&x; +e = ((*q >> 7) & 0377) - 0200; +*q &= 0177; +*q |= 040000; +z = x; +#endif + +/* Note, frexp and ldexp are used in order to + * handle denormal numbers properly. + */ +#ifdef IBMPC +z = frexp( x, &e ); +q = (short *)&x; +q += 3; +/* +e = ((*q >> 4) & 0x0fff) - 0x3fe; +*q &= 0x000f; +*q |= 0x3fe0; +z = x; +*/ +#endif +#ifdef MIEEE +z = frexp( x, &e ); +q = (short *)&x; +/* +e = ((*q >> 4) & 0x0fff) - 0x3fe; +*q &= 0x000f; +*q |= 0x3fe0; +z = x; +*/ +#endif + +/* approximate square root of number between 0.5 and 1 + * relative error of approximation = 7.47e-3 + */ +x = 4.173075996388649989089E-1 + 5.9016206709064458299663E-1 * z; + +/* adjust for odd powers of 2 */ +if( (e & 1) != 0 ) + x *= SQRT2; + +/* re-insert exponent */ +#ifdef UNK +x = ldexp( x, (e >> 1) ); +#endif +#ifdef DEC +*q += ((e >> 1) & 0377) << 7; +*q &= 077777; +#endif +#ifdef IBMPC +x = ldexp( x, (e >> 1) ); +/* +*q += ((e >>1) & 0x7ff) << 4; +*q &= 077777; +*/ +#endif +#ifdef MIEEE +x = ldexp( x, (e >> 1) ); +/* +*q += ((e >>1) & 0x7ff) << 4; +*q &= 077777; +*/ +#endif + +/* Newton iterations: */ +#ifdef UNK +x = 0.5*(x + w/x); +x = 0.5*(x + w/x); +x = 0.5*(x + w/x); +#endif + +/* Note, assume the square root cannot be denormal, + * so it is safe to use integer exponent operations here. + */ +#ifdef DEC +x += w/x; +*q -= 0200; +x += w/x; +*q -= 0200; +x += w/x; +*q -= 0200; +#endif +#ifdef IBMPC +x += w/x; +*q -= 0x10; +x += w/x; +*q -= 0x10; +x += w/x; +*q -= 0x10; +#endif +#ifdef MIEEE +x += w/x; +*q -= 0x10; +x += w/x; +*q -= 0x10; +x += w/x; +*q -= 0x10; +#endif + +return(x); +} diff --git a/src/math/tan.c b/src/math/tan.c new file mode 100644 index 000000000..8ef8af55c --- /dev/null +++ b/src/math/tan.c @@ -0,0 +1,304 @@ +/* tan.c + * + * Circular tangent + * + * + * + * SYNOPSIS: + * + * double x, y, tan(); + * + * y = tan( x ); + * + * + * + * DESCRIPTION: + * + * Returns the circular tangent of the radian argument x. + * + * Range reduction is modulo pi/4. A rational function + * x + x**3 P(x**2)/Q(x**2) + * is employed in the basic interval [0, pi/4]. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC +-1.07e9 44000 4.1e-17 1.0e-17 + * IEEE +-1.07e9 30000 2.9e-16 8.1e-17 + * + * ERROR MESSAGES: + * + * message condition value returned + * tan total loss x > 1.073741824e9 0.0 + * + */ + /* cot.c + * + * Circular cotangent + * + * + * + * SYNOPSIS: + * + * double x, y, cot(); + * + * y = cot( x ); + * + * + * + * DESCRIPTION: + * + * Returns the circular cotangent of the radian argument x. + * + * Range reduction is modulo pi/4. A rational function + * x + x**3 P(x**2)/Q(x**2) + * is employed in the basic interval [0, pi/4]. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE +-1.07e9 30000 2.9e-16 8.2e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * cot total loss x > 1.073741824e9 0.0 + * cot singularity x = 0 INFINITY + * + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +yright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +static double P[] = { +-1.30936939181383777646E4, + 1.15351664838587416140E6, +-1.79565251976484877988E7 +}; +static double Q[] = { +/* 1.00000000000000000000E0,*/ + 1.36812963470692954678E4, +-1.32089234440210967447E6, + 2.50083801823357915839E7, +-5.38695755929454629881E7 +}; +static double DP1 = 7.853981554508209228515625E-1; +static double DP2 = 7.94662735614792836714E-9; +static double DP3 = 3.06161699786838294307E-17; +static double lossth = 1.073741824e9; +#endif + +#ifdef DEC +static unsigned short P[] = { +0143514,0113306,0111171,0174674, +0045214,0147545,0027744,0167346, +0146210,0177526,0114514,0105660 +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0043525,0142457,0072633,0025617, +0145241,0036742,0140525,0162256, +0046276,0146176,0013526,0143573, +0146515,0077401,0162762,0150607 +}; +/* 7.853981629014015197753906250000E-1 */ +static unsigned short P1[] = {0040111,0007732,0120000,0000000,}; +/* 4.960467869796758577649598009884E-10 */ +static unsigned short P2[] = {0030410,0055060,0100000,0000000,}; +/* 2.860594363054915898381331279295E-18 */ +static unsigned short P3[] = {0021523,0011431,0105056,0001560,}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +static double lossth = 1.073741824e9; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x3f38,0xd24f,0x92d8,0xc0c9, +0x9ddd,0xa5fc,0x99ec,0x4131, +0x9176,0xd329,0x1fea,0xc171 +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0x6572,0xeeb3,0xb8a5,0x40ca, +0xbc96,0x582a,0x27bc,0xc134, +0xd8ef,0xc2ea,0xd98f,0x4177, +0x5a31,0x3cbe,0xafe0,0xc189 +}; +/* + 7.85398125648498535156E-1, + 3.77489470793079817668E-8, + 2.69515142907905952645E-15, +*/ +static unsigned short P1[] = {0x0000,0x4000,0x21fb,0x3fe9}; +static unsigned short P2[] = {0x0000,0x0000,0x442d,0x3e64}; +static unsigned short P3[] = {0x5170,0x98cc,0x4698,0x3ce8}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +static double lossth = 1.073741824e9; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0xc0c9,0x92d8,0xd24f,0x3f38, +0x4131,0x99ec,0xa5fc,0x9ddd, +0xc171,0x1fea,0xd329,0x9176 +}; +static unsigned short Q[] = { +0x40ca,0xb8a5,0xeeb3,0x6572, +0xc134,0x27bc,0x582a,0xbc96, +0x4177,0xd98f,0xc2ea,0xd8ef, +0xc189,0xafe0,0x3cbe,0x5a31 +}; +static unsigned short P1[] = { +0x3fe9,0x21fb,0x4000,0x0000 +}; +static unsigned short P2[] = { +0x3e64,0x442d,0x0000,0x0000 +}; +static unsigned short P3[] = { +0x3ce8,0x4698,0x98cc,0x5170, +}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +static double lossth = 1.073741824e9; +#endif + +#ifdef ANSIPROT +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern double floor ( double ); +extern double ldexp ( double, int ); +extern int isnan ( double ); +extern int isfinite ( double ); +static double tancot(double, int); +#else +double polevl(), p1evl(), floor(), ldexp(); +static double tancot(); +int isnan(), isfinite(); +#endif +extern double PIO4; +extern double INFINITY; +extern double NAN; + +double c_tan(x) +double x; +{ +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +#ifdef NANS +if( isnan(x) ) + return(x); +if( !isfinite(x) ) + { + mtherr( "tan", DOMAIN ); + return(NAN); + } +#endif +return( tancot(x,0) ); +} + + +double c_cot(x) +double x; +{ + +if( x == 0.0 ) + { + mtherr( "cot", SING ); + return( INFINITY ); + } +return( tancot(x,1) ); +} + + +static double tancot( xx, cotflg ) +double xx; +int cotflg; +{ +double x, y, z, zz; +int j, sign; + +/* make argument positive but save the sign */ +if( xx < 0 ) + { + x = -xx; + sign = -1; + } +else + { + x = xx; + sign = 1; + } + +if( x > lossth ) + { + if( cotflg ) + mtherr( "cot", TLOSS ); + else + mtherr( "tan", TLOSS ); + return(0.0); + } + +/* compute x mod PIO4 */ +y = floor( x/PIO4 ); + +/* strip high bits of integer part */ +z = ldexp( y, -3 ); +z = floor(z); /* integer part of y/8 */ +z = y - ldexp( z, 3 ); /* y - 16 * (y/16) */ + +/* integer and fractional part modulo one octant */ +j = (int)z; + +/* map zeros and singularities to origin */ +if( j & 1 ) + { + j += 1; + y += 1.0; + } + +z = ((x - y * DP1) - y * DP2) - y * DP3; + +zz = z * z; + +if( zz > 1.0e-14 ) + y = z + z * (zz * polevl( zz, P, 2 )/p1evl(zz, Q, 4)); +else + y = z; + +if( j & 2 ) + { + if( cotflg ) + y = -y; + else + y = -1.0/y; + } +else + { + if( cotflg ) + y = 1.0/y; + } + +if( sign < 0 ) + y = -y; + +return( y ); +} diff --git a/src/math/tanh.c b/src/math/tanh.c new file mode 100644 index 000000000..7590eca5c --- /dev/null +++ b/src/math/tanh.c @@ -0,0 +1,141 @@ +/* tanh.c + * + * Hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * double x, y, tanh(); + * + * y = tanh( x ); + * + * + * + * DESCRIPTION: + * + * Returns hyperbolic tangent of argument in the range MINLOG to + * MAXLOG. + * + * A rational function is used for |x| < 0.625. The form + * x + x**3 P(x)/Q(x) of Cody _& Waite is employed. + * Otherwise, + * tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -2,2 50000 3.3e-17 6.4e-18 + * IEEE -2,2 30000 2.5e-16 5.8e-17 + * + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +static double P[] = { +-9.64399179425052238628E-1, +-9.92877231001918586564E1, +-1.61468768441708447952E3 +}; +static double Q[] = { +/* 1.00000000000000000000E0,*/ + 1.12811678491632931402E2, + 2.23548839060100448583E3, + 4.84406305325125486048E3 +}; +#endif +#ifdef DEC +static unsigned short P[] = { +0140166,0161335,0053753,0075126, +0141706,0111520,0070463,0040552, +0142711,0153001,0101300,0025430 +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0041741,0117624,0051300,0156060, +0043013,0133720,0071251,0127717, +0043227,0060201,0021020,0020136 +}; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x6f4b,0xaafd,0xdc5b,0xbfee, +0x682d,0x0e26,0xd26a,0xc058, +0x0563,0x3058,0x3ac0,0xc099 +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0x1b86,0x8a58,0x33f2,0x405c, +0x35fa,0x0e55,0x76fa,0x40a1, +0x040c,0x2442,0xec10,0x40b2 +}; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0xbfee,0xdc5b,0xaafd,0x6f4b, +0xc058,0xd26a,0x0e26,0x682d, +0xc099,0x3ac0,0x3058,0x0563 +}; +static unsigned short Q[] = { +0x405c,0x33f2,0x8a58,0x1b86, +0x40a1,0x76fa,0x0e55,0x35fa, +0x40b2,0xec10,0x2442,0x040c +}; +#endif + +#ifdef ANSIPROT +extern double fabs ( double ); +extern double c_exp ( double ); +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +#else +double fabs(), c_exp(), polevl(), p1evl(); +#endif +extern double MAXLOG; + +double c_tanh(x) +double x; +{ +double s, z; + +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +z = fabs(x); +if( z > 0.5 * MAXLOG ) + { + if( x > 0 ) + return( 1.0 ); + else + return( -1.0 ); + } +if( z >= 0.625 ) + { + s = c_exp(2.0*z); + z = 1.0 - 2.0/(s + 1.0); + if( x < 0 ) + z = -z; + } +else + { + if( x == 0.0 ) + return(x); + s = x * x; + z = polevl( s, P, 2 )/p1evl(s, Q, 3); + z = x * s * z; + z = x + z; + } +return( z ); +} diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 115b6818f..fb0ea80d7 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -78,7 +78,7 @@ FButtonStatus MenuButtons[NUM_MKEYS]; int MenuButtonTickers[NUM_MKEYS]; bool MenuButtonOrigin[NUM_MKEYS]; int BackbuttonTime; -fixed_t BackbuttonAlpha; +float BackbuttonAlpha; static bool MenuEnabled = true; @@ -274,7 +274,7 @@ void DMenu::Drawer () } else { - screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_Alpha, BackbuttonAlpha, TAG_DONE); + screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_AlphaF, BackbuttonAlpha, TAG_DONE); } } } @@ -680,12 +680,13 @@ void M_Ticker (void) } if (BackbuttonTime > 0) { - if (BackbuttonAlpha < FRACUNIT) BackbuttonAlpha += FRACUNIT/10; + if (BackbuttonAlpha < 1.f) BackbuttonAlpha += .1f; + if (BackbuttonAlpha > 1.f) BackbuttonAlpha = 1.f; BackbuttonTime--; } else { - if (BackbuttonAlpha > 0) BackbuttonAlpha -= FRACUNIT/10; + if (BackbuttonAlpha > 0) BackbuttonAlpha -= .1f; if (BackbuttonAlpha < 0) BackbuttonAlpha = 0; } } diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index ccf3f5633..c3d11a43a 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -35,8 +35,6 @@ #include "doomtype.h" #include "doomstat.h" #include "d_player.h" -#include "tables.h" -#include "m_fixed.h" #include "templates.h" #include "menu/menu.h" #include "colormatcher.h" @@ -59,6 +57,22 @@ struct FBackdropTexture : public FTexture { + enum + { + COS_SIZE = 256, + ANGLESHIFT = 24 + }; + + static constexpr uint32_t DEGREES(double v) + { + return uint32_t((v)*(0x40000000 / 90.0)); + } + + static double TORAD(uint32_t x) + { + return x*(M_PI / 0x80000000); + } + public: FBackdropTexture(); @@ -68,12 +82,13 @@ public: bool CheckModified(); protected: + uint32_t costab[COS_SIZE]; BYTE Pixels[144*160]; static const Span DummySpan[2]; int LastRenderTic; - angle_t time1, time2, time3, time4; - angle_t t1ang, t2ang, z1ang, z2ang; + uint32_t time1, time2, time3, time4; + uint32_t t1ang, t2ang, z1ang, z2ang; void Render(); }; @@ -171,14 +186,19 @@ FBackdropTexture::FBackdropTexture() WidthMask = 255; LastRenderTic = 0; - time1 = ANGLE_1*180; - time2 = ANGLE_1*56; - time3 = ANGLE_1*99; - time4 = ANGLE_1*1; - t1ang = ANGLE_90; + for (int i = 0; i < COS_SIZE; ++i) + { + costab[i] = uint32_t(cos(i * (M_PI / (COS_SIZE / 2))) * 65536); + } + + time1 = DEGREES(180); + time2 = DEGREES(56); + time3 = DEGREES(99); + time4 = DEGREES(1); + t1ang = DEGREES(90); t2ang = 0; z1ang = 0; - z2ang = ANGLE_90/2; + z2ang = DEGREES(45); } //============================================================================= @@ -248,22 +268,23 @@ void FBackdropTexture::Render() int x, y; - const angle_t a1add = ANGLE_1/2; - const angle_t a2add = ANGLE_MAX-ANGLE_1; - const angle_t a3add = ANGLE_1*5/7; - const angle_t a4add = ANGLE_MAX-ANGLE_1*4/3; + const DWORD a1add = DEGREES(0.5); + const DWORD a2add = DEGREES(359); + const DWORD a3add = DEGREES(5 / 7.f); + const DWORD a4add = DEGREES(358.66666); - const angle_t t1add = ANGLE_MAX-ANGLE_1*2; - const angle_t t2add = ANGLE_MAX-ANGLE_1*3+ANGLE_1/6; - const angle_t t3add = ANGLE_1*16/7; - const angle_t t4add = ANGLE_MAX-ANGLE_1*2/3; - const angle_t x1add = 5<>ANGLETOFINESHIFT]>>2)+FRACUNIT/2; - fixed_t z2 = (finecosine[z1ang>>ANGLETOFINESHIFT]>>2)+FRACUNIT*3/4; + double z1 = (cos(TORAD(z2ang)) / 4 + 0.5) * (0x8000000); + double z2 = (cos(TORAD(z1ang)) / 4 + 0.75) * (0x8000000); - tc = MulScale5 (finecosine[t1ang>>ANGLETOFINESHIFT], z1); - ts = MulScale5 (finesine[t1ang>>ANGLETOFINESHIFT], z1); - uc = MulScale5 (finecosine[t2ang>>ANGLETOFINESHIFT], z2); - us = MulScale5 (finesine[t2ang>>ANGLETOFINESHIFT], z2); - - ltx = -width/2*tc; - lty = -width/2*ts; - lux = -width/2*uc; - luy = -width/2*us; + tc = SDWORD(cos(TORAD(t1ang)) * z1); + ts = SDWORD(sin(TORAD(t1ang)) * z1); + uc = SDWORD(cos(TORAD(t2ang)) * z2); + us = SDWORD(sin(TORAD(t2ang)) * z2); + + ltx = -width / 2 * tc; + lty = -width / 2 * ts; + lux = -width / 2 * uc; + luy = -width / 2 * us; for (y = 0; y < height; ++y) { a1 = time1; a2 = time2; - c3 = finecosine[a3>>ANGLETOFINESHIFT]; - c4 = finecosine[a4>>ANGLETOFINESHIFT]; - tx = ltx - (y-height/2)*ts; - ty = lty + (y-height/2)*tc; - ux = lux - (y-height/2)*us; - uy = luy + (y-height/2)*uc; + c3 = SDWORD(cos(TORAD(a3)) * 65536.0); + c4 = SDWORD(cos(TORAD(a4)) * 65536.0); + tx = ltx - (y - height / 2)*ts; + ty = lty + (y - height / 2)*tc; + ux = lux - (y - height / 2)*us; + uy = luy + (y - height / 2)*uc; for (x = 0; x < width; ++x) { - c1 = finecosine[a1>>ANGLETOFINESHIFT]; - c2 = finecosine[a2>>ANGLETOFINESHIFT]; - from[x] = ((c1 + c2 + c3 + c4) >> (FRACBITS+3-7)) + 128 // plasma - + pattern1[(tx>>27)+((ty>>22)&992)] // rotozoomer 1 - + pattern2[(ux>>27)+((uy>>22)&992)]; // rotozoomer 2 + c1 = costab[a1 >> ANGLESHIFT]; + c2 = costab[a2 >> ANGLESHIFT]; + from[x] = ((c1 + c2 + c3 + c4) >> (16 + 3 - 7)) + 128 // plasma + + pattern1[(tx >> 27) + ((ty >> 22) & 992)] // rotozoomer 1 + + pattern2[(ux >> 27) + ((uy >> 22) & 992)]; // rotozoomer 2 tx += tc; ty += ts; ux += uc; @@ -563,21 +584,19 @@ void FListMenuItemPlayerDisplay::Drawer(bool selected) V_DrawFrame (x, y, 72*CleanXfac, 80*CleanYfac-1); spriteframe_t *sprframe = NULL; - fixed_t scaleX, scaleY; + DVector2 Scale; if (mPlayerState != NULL) { if (mSkin == 0) { sprframe = &SpriteFrames[sprites[mPlayerState->sprite].spriteframes + mPlayerState->GetFrame()]; - scaleX = GetDefaultByType(mPlayerClass->Type)->scaleX; - scaleY = GetDefaultByType(mPlayerClass->Type)->scaleY; + Scale = GetDefaultByType(mPlayerClass->Type)->Scale; } else { sprframe = &SpriteFrames[sprites[skins[mSkin].sprite].spriteframes + mPlayerState->GetFrame()]; - scaleX = skins[mSkin].ScaleX; - scaleY = skins[mSkin].ScaleY; + Scale = skins[mSkin].Scale; } } @@ -590,8 +609,8 @@ void FListMenuItemPlayerDisplay::Drawer(bool selected) if (mTranslate) trans = translationtables[TRANSLATION_Players](MAXPLAYERS); screen->DrawTexture (tex, x + 36*CleanXfac, y + 71*CleanYfac, - DTA_DestWidth, MulScale16 (tex->GetScaledWidth() * CleanXfac, scaleX), - DTA_DestHeight, MulScale16 (tex->GetScaledHeight() * CleanYfac, scaleY), + DTA_DestWidthF, tex->GetScaledWidthDouble() * CleanXfac * Scale.X, + DTA_DestHeightF, tex->GetScaledHeightDouble() * CleanYfac * Scale.Y, DTA_Translation, trans, DTA_FlipX, sprframe->Flip & (1 << mRotation), TAG_DONE); diff --git a/src/menu/readthis.cpp b/src/menu/readthis.cpp index 82b20bf00..0aa3c2fcd 100644 --- a/src/menu/readthis.cpp +++ b/src/menu/readthis.cpp @@ -79,7 +79,7 @@ DReadThisMenu::DReadThisMenu(DMenu *parent) void DReadThisMenu::Drawer() { FTexture *tex = NULL, *prevpic = NULL; - fixed_t alpha; + double alpha; // Did the mapper choose a custom help page via MAPINFO? if ((level.info != NULL) && level.info->F1Pic.Len() != 0) @@ -99,12 +99,12 @@ void DReadThisMenu::Drawer() } screen->Dim(0, 1.0, 0,0, SCREENWIDTH, SCREENHEIGHT); - alpha = MIN (Scale (gametic - mInfoTic, OPAQUE, TICRATE/3), OPAQUE); - if (alpha < OPAQUE && prevpic != NULL) + alpha = MIN((gametic - mInfoTic) * (3. / TICRATE), 1.); + if (alpha < 1. && prevpic != NULL) { screen->DrawTexture (prevpic, 0, 0, DTA_Fullscreen, true, TAG_DONE); } - screen->DrawTexture (tex, 0, 0, DTA_Fullscreen, true, DTA_Alpha, alpha, TAG_DONE); + screen->DrawTexture (tex, 0, 0, DTA_Fullscreen, true, DTA_AlphaF, alpha, TAG_DONE); } diff --git a/src/nodebuild_events.cpp b/src/nodebuild_events.cpp index 345a6b6be..84e187081 100644 --- a/src/nodebuild_events.cpp +++ b/src/nodebuild_events.cpp @@ -219,7 +219,7 @@ void FEventTree::PrintTree (const FEvent *event) const { PrintTree(event->Left); sprintf(buff, " Distance %g, vertex %d, seg %u\n", - sqrt(event->Distance/4294967296.0), event->Info.Vertex, (unsigned)event->Info.FrontSeg); + g_sqrt(event->Distance/4294967296.0), event->Info.Vertex, (unsigned)event->Info.FrontSeg); Printf(PRINT_LOG, "%s", buff); PrintTree(event->Right); } diff --git a/src/nodebuild_extract.cpp b/src/nodebuild_extract.cpp index 0d5e0b91c..425c656e3 100644 --- a/src/nodebuild_extract.cpp +++ b/src/nodebuild_extract.cpp @@ -64,8 +64,7 @@ void FNodeBuilder::Extract (node_t *&outNodes, int &nodeCount, for (i = 0; i < vertCount; ++i) { - outVerts[i].x = Vertices[i].x; - outVerts[i].y = Vertices[i].y; + outVerts[i].set(Vertices[i].x, Vertices[i].y); } subCount = Subsectors.Size(); @@ -169,8 +168,7 @@ void FNodeBuilder::ExtractMini (FMiniBSP *bsp) bsp->Verts.Resize(Vertices.Size()); for (i = 0; i < Vertices.Size(); ++i) { - bsp->Verts[i].x = Vertices[i].x; - bsp->Verts[i].y = Vertices[i].y; + bsp->Verts[i].set(Vertices[i].x, Vertices[i].y); } bsp->Subsectors.Resize(Subsectors.Size()); @@ -400,14 +398,14 @@ int FNodeBuilder::CloseSubsector (TArray &segs, int subsector, vertex_t { Printf(PRINT_LOG, " Seg %5d%c(%5d,%5d)-(%5d,%5d) [%08x,%08x]-[%08x,%08x]\n", i, segs[i].linedef == NULL ? '+' : ' ', - segs[i].v1->x>>16, - segs[i].v1->y>>16, - segs[i].v2->x>>16, - segs[i].v2->y>>16, - segs[i].v1->x, - segs[i].v1->y, - segs[i].v2->x, - segs[i].v2->y); + segs[i].v1->fixX()>>16, + segs[i].v1->fixY()>>16, + segs[i].v2->fixX()>>16, + segs[i].v2->fixY()>>16, + segs[i].v1->fixX(), + segs[i].v1->fixY(), + segs[i].v2->fixX(), + segs[i].v2->fixY()); } #endif diff --git a/src/nodebuild_utility.cpp b/src/nodebuild_utility.cpp index a2edd19b9..dcf5b7036 100644 --- a/src/nodebuild_utility.cpp +++ b/src/nodebuild_utility.cpp @@ -50,6 +50,7 @@ #include "i_system.h" #include "po_man.h" #include "r_state.h" +#include "math/cmath.h" static const int PO_LINE_START = 1; static const int PO_LINE_EXPLICIT = 5; @@ -74,7 +75,7 @@ angle_t FNodeBuilder::PointToAngle (fixed_t x, fixed_t y) // See https://gcc.gnu.org/wiki/Math_Optimization_Flags for details long double ang = atan2l (double(y), double(x)); #else // !__APPLE__ || __llvm__ - double ang = atan2 (double(y), double(x)); + double ang = g_atan2 (double(y), double(x)); #endif // __APPLE__ && !__llvm__ // Convert to signed first since negative double to unsigned is undefined. return angle_t(int(ang * rad2bam)) << 1; @@ -95,14 +96,14 @@ void FNodeBuilder::FindUsedVertices (vertex_t *oldverts, int max) if (map[v1] == -1) { - newvert.x = oldverts[v1].x; - newvert.y = oldverts[v1].y; + newvert.x = oldverts[v1].fixX(); + newvert.y = oldverts[v1].fixY(); map[v1] = VertexMap->SelectVertexExact (newvert); } if (map[v2] == -1) { - newvert.x = oldverts[v2].x; - newvert.y = oldverts[v2].y; + newvert.x = oldverts[v2].fixX(); + newvert.y = oldverts[v2].fixY(); map[v2] = VertexMap->SelectVertexExact (newvert); } @@ -221,11 +222,11 @@ void FNodeBuilder::AddSegs(seg_t *segs, int numsegs) seg.frontsector = segs[i].frontsector; seg.backsector = segs[i].backsector; - vert.x = segs[i].v1->x; - vert.y = segs[i].v1->y; + vert.x = segs[i].v1->fixX(); + vert.y = segs[i].v1->fixY(); seg.v1 = VertexMap->SelectVertexExact(vert); - vert.x = segs[i].v2->x; - vert.y = segs[i].v2->y; + vert.x = segs[i].v2->fixX(); + vert.y = segs[i].v2->fixY(); seg.v2 = VertexMap->SelectVertexExact(vert); seg.linedef = int(segs[i].linedef - Level.Lines); seg.sidedef = segs[i].sidedef != NULL ? int(segs[i].sidedef - Level.Sides) : int(NO_SIDE); @@ -261,11 +262,11 @@ void FNodeBuilder::AddPolySegs(FPolySeg *segs, int numsegs) seg.frontsector = side->sector; seg.backsector = side->linedef->frontsector == side->sector ? side->linedef->backsector : side->linedef->frontsector; - vert.x = segs[i].v1.x; - vert.y = segs[i].v1.y; + vert.x = FLOAT2FIXED(segs[i].v1.pos.X); + vert.y = FLOAT2FIXED(segs[i].v1.pos.Y); seg.v1 = VertexMap->SelectVertexExact(vert); - vert.x = segs[i].v2.x; - vert.y = segs[i].v2.y; + vert.x = FLOAT2FIXED(segs[i].v2.pos.X); + vert.y = FLOAT2FIXED(segs[i].v2.pos.Y); seg.v2 = VertexMap->SelectVertexExact(vert); seg.linedef = int(side->linedef - Level.Lines); seg.sidedef = int(side - Level.Sides); @@ -429,18 +430,18 @@ void FNodeBuilder::FindPolyContainers (TArray &spots, TArrayx + spot->x; - center.y = mid.y - anchor->y + spot->y; + center.set(mid.fixX() - anchor->x + spot->x, + mid.fixY() - anchor->y + spot->y); // Scan right for the seg closest to the polyobject's center after it // gets moved to its start spot. fixed_t closestdist = FIXED_MAX; unsigned int closestseg = UINT_MAX; - P(Printf ("start %d,%d -- center %d, %d\n", spot->x>>16, spot->y>>16, center.x>>16, center.y>>16)); + P(Printf ("start %d,%d -- center %d, %d\n", spot->x>>16, spot->y>>16, center.fixX()>>16, center.fixY()>>16)); for (unsigned int j = 0; j < Segs.Size(); ++j) { @@ -453,16 +454,16 @@ void FNodeBuilder::FindPolyContainers (TArray &spots, TArrayy < center.y && v2->y < center.y) || (v1->y > center.y && v2->y > center.y)) + if ((v1->y < center.fixY() && v2->y < center.fixY()) || (v1->y > center.fixY() && v2->y > center.fixY())) { // Not crossed continue; } fixed_t dx = v2->x - v1->x; - if (PointOnSide (center.x, center.y, v1->x, v1->y, dx, dy) <= 0) + if (PointOnSide (center.fixX(), center.fixY(), v1->x, v1->y, dx, dy) <= 0) { - fixed_t t = DivScale30 (center.y - v1->y, dy); + fixed_t t = DivScale30 (center.fixY() - v1->y, dy); fixed_t sx = v1->x + MulScale30 (dx, t); fixed_t dist = sx - spot->x; @@ -564,8 +565,7 @@ bool FNodeBuilder::GetPolyExtents (int polynum, fixed_t bbox[4]) vert = Segs[i].v1; - start.x = Vertices[vert].x; - start.y = Vertices[vert].y; + start.set(Vertices[vert].x, Vertices[vert].y); do { @@ -573,7 +573,7 @@ bool FNodeBuilder::GetPolyExtents (int polynum, fixed_t bbox[4]) vert = Segs[i].v2; i = Vertices[vert].segs; count++; // to prevent endless loops. Stop when this reaches the number of segs. - } while (i != DWORD_MAX && (Vertices[vert].x != start.x || Vertices[vert].y != start.y) && count < Segs.Size()); + } while (i != DWORD_MAX && (Vertices[vert].x != start.fixX() || Vertices[vert].y != start.fixY()) && count < Segs.Size()); return true; } @@ -613,15 +613,15 @@ void FNodeBuilder::FLevel::FindMapBounds () { fixed_t minx, maxx, miny, maxy; - minx = maxx = Vertices[0].x; - miny = maxy = Vertices[0].y; + minx = maxx = Vertices[0].fixX(); + miny = maxy = Vertices[0].fixY(); for (int i = 1; i < NumVertices; ++i) { - if (Vertices[i].x < minx) minx = Vertices[i].x; - else if (Vertices[i].x > maxx) maxx = Vertices[i].x; - if (Vertices[i].y < miny) miny = Vertices[i].y; - else if (Vertices[i].y > maxy) maxy = Vertices[i].y; + if (Vertices[i].fixX() < minx) minx = Vertices[i].fixX(); + else if (Vertices[i].fixX() > maxx) maxx = Vertices[i].fixX(); + if (Vertices[i].fixY() < miny) miny = Vertices[i].fixY(); + else if (Vertices[i].fixY() > maxy) maxy = Vertices[i].fixY(); } MinX = minx; diff --git a/src/oplsynth/mlopl_io.cpp b/src/oplsynth/mlopl_io.cpp index 64c4ad962..e6ed3bba8 100644 --- a/src/oplsynth/mlopl_io.cpp +++ b/src/oplsynth/mlopl_io.cpp @@ -37,6 +37,7 @@ * Cleaned up the source */ +#include #ifdef _WIN32 #include #include @@ -45,7 +46,7 @@ #include "opl.h" #include "c_cvars.h" -#define HALF_PI (PI*0.5) +const double HALF_PI = (M_PI*0.5); EXTERN_CVAR(Int, opl_core) extern int current_opl_core; diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index ab47c1e47..04d12739e 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -133,14 +133,12 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag { ffloor->bottom.plane = &sec2->floorplane; ffloor->bottom.texture = &sec2->planes[sector_t::floor].Texture; - ffloor->bottom.texheight = &sec2->planes[sector_t::floor].TexZ; ffloor->bottom.isceiling = sector_t::floor; } else { ffloor->bottom.plane = &sec2->ceilingplane; ffloor->bottom.texture = &sec2->planes[sector_t::ceiling].Texture; - ffloor->bottom.texheight = &sec2->planes[sector_t::ceiling].TexZ; ffloor->bottom.isceiling = sector_t::ceiling; } @@ -148,7 +146,6 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag { ffloor->top.plane = &sec2->ceilingplane; ffloor->top.texture = &sec2->planes[sector_t::ceiling].Texture; - ffloor->top.texheight = &sec2->planes[sector_t::ceiling].TexZ; ffloor->toplightlevel = &sec2->lightlevel; ffloor->top.isceiling = sector_t::ceiling; } @@ -156,7 +153,6 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag { ffloor->top.plane = &sec->floorplane; ffloor->top.texture = &sec2->planes[sector_t::floor].Texture; - ffloor->top.texheight = &sec2->planes[sector_t::floor].TexZ; ffloor->toplightlevel = &sec->lightlevel; ffloor->top.isceiling = sector_t::floor; ffloor->top.model = sec; @@ -187,9 +183,9 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag ffloor->top.vindex = ffloor->bottom.vindex = -1; // The engine cannot handle sloped translucent floors. Sorry - if (ffloor->top.plane->a || ffloor->top.plane->b || ffloor->bottom.plane->a || ffloor->bottom.plane->b) + if (ffloor->top.plane->isSlope() || ffloor->bottom.plane->isSlope()) { - ffloor->alpha = FRACUNIT; + ffloor->alpha = OPAQUE; ffloor->flags &= ~FF_ADDITIVETRANS; } @@ -324,12 +320,8 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) void P_PlayerOnSpecial3DFloor(player_t* player) { - sector_t * sector = player->mo->Sector; - - for(unsigned i=0;ie->XFloor.ffloors.Size();i++) + for(auto rover : player->mo->Sector->e->XFloor.ffloors) { - F3DFloor* rover=sector->e->XFloor.ffloors[i]; - if (!(rover->flags & FF_EXISTS)) continue; if (rover->flags & FF_FIX) continue; @@ -366,19 +358,15 @@ void P_PlayerOnSpecial3DFloor(player_t* player) //========================================================================== bool P_CheckFor3DFloorHit(AActor * mo) { - sector_t * sector = mo->Sector; - if ((mo->player && (mo->player->cheats & CF_PREDICTING))) return false; - for(unsigned i=0;ie->XFloor.ffloors.Size();i++) + for (auto rover : mo->Sector->e->XFloor.ffloors) { - F3DFloor* rover=sector->e->XFloor.ffloors[i]; - if (!(rover->flags & FF_EXISTS)) continue; if(rover->flags & FF_SOLID && rover->model->SecActTarget) { - if(mo->floorz == rover->top.plane->ZatPoint(mo)) + if(mo->Z() == rover->top.plane->ZatPoint(mo)) { rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitFloor); return true; @@ -396,19 +384,15 @@ bool P_CheckFor3DFloorHit(AActor * mo) //========================================================================== bool P_CheckFor3DCeilingHit(AActor * mo) { - sector_t * sector = mo->Sector; - if ((mo->player && (mo->player->cheats & CF_PREDICTING))) return false; - for(unsigned i=0;ie->XFloor.ffloors.Size();i++) + for (auto rover : mo->Sector->e->XFloor.ffloors) { - F3DFloor* rover=sector->e->XFloor.ffloors[i]; - if (!(rover->flags & FF_EXISTS)) continue; if(rover->flags & FF_SOLID && rover->model->SecActTarget) { - if(mo->ceilingz == rover->bottom.plane->ZatPoint(mo)) + if(mo->Top() == rover->bottom.plane->ZatPoint(mo)) { rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitCeiling); return true; @@ -434,10 +418,10 @@ void P_Recalculate3DFloors(sector_t * sector) unsigned pickindex; F3DFloor * clipped=NULL; F3DFloor * solid=NULL; - fixed_t solid_bottom=0; - fixed_t clipped_top; - fixed_t clipped_bottom=0; - fixed_t maxheight, minheight; + double solid_bottom=0; + double clipped_top; + double clipped_bottom=0; + double maxheight, minheight; unsigned i, j; lightlist_t newlight; lightlist_t resetlight; // what it goes back to after FF_DOUBLESHADOW @@ -476,13 +460,13 @@ void P_Recalculate3DFloors(sector_t * sector) while (oldlist.Size()) { pick=oldlist[0]; - fixed_t height=pick->top.plane->ZatPoint(sector->centerspot); + double height=pick->top.plane->ZatPoint(sector->centerspot); // find highest starting ffloor - intersections are not supported! pickindex=0; for (j=1;jtop.plane->ZatPoint(sector->centerspot); + double h2=oldlist[j]->top.plane->ZatPoint(sector->centerspot); if (h2>height) { @@ -493,7 +477,7 @@ void P_Recalculate3DFloors(sector_t * sector) } oldlist.Delete(pickindex); - fixed_t pick_bottom=pick->bottom.plane->ZatPoint(sector->centerspot); + double pick_bottom=pick->bottom.plane->ZatPoint(sector->centerspot); if (pick->flags & FF_THISINSIDE) { @@ -598,8 +582,8 @@ void P_Recalculate3DFloors(sector_t * sector) resetlight = lightlist[0]; - maxheight = sector->CenterCeiling(); - minheight = sector->CenterFloor(); + maxheight = sector->ceilingplane.ZatPoint(sector->centerspot); + minheight = sector->floorplane.ZatPoint(sector->centerspot); for(i = 0; i < ffloors.Size(); i++) { rover=ffloors[i]; @@ -607,7 +591,7 @@ void P_Recalculate3DFloors(sector_t * sector) if ( !(rover->flags & FF_EXISTS) || rover->flags & FF_NOSHADE ) continue; - fixed_t ff_top=rover->top.plane->ZatPoint(sector->centerspot); + double ff_top=rover->top.plane->ZatPoint(sector->centerspot); if (ff_top < minheight) break; // reached the floor if (ff_top < maxheight) { @@ -622,7 +606,7 @@ void P_Recalculate3DFloors(sector_t * sector) } else { - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(sector->centerspot); + double ff_bottom=rover->bottom.plane->ZatPoint(sector->centerspot); if (ff_bottomflags&FF_DOUBLESHADOW) { - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(sector->centerspot); + double ff_bottom=rover->bottom.plane->ZatPoint(sector->centerspot); if(ff_bottom < maxheight && ff_bottom>minheight) { newlight.caster = rover; @@ -736,7 +720,7 @@ lightlist_t * P_GetPlaneLight(sector_t * sector, secplane_t * plane, bool unders unsigned i; TArray &lightlist = sector->e->XFloor.lightlist; - fixed_t planeheight=plane->ZatPoint(sector->centerspot); + double planeheight=plane->ZatPoint(sector->centerspot); if(underside) planeheight--; for(i = 1; i < lightlist.Size(); i++) @@ -753,23 +737,24 @@ lightlist_t * P_GetPlaneLight(sector_t * sector, secplane_t * plane, bool unders //========================================================================== void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *linedef, - fixed_t x, fixed_t y, fixed_t refx, fixed_t refy, bool restrict) + double x, double y, bool restrict) { if(thing) { - fixed_t thingbot, thingtop; + double thingbot, thingtop; thingbot = thing->Z(); - thingtop = thingbot + (thing->height==0? 1:thing->height); + thingtop = thing->Top(); + extsector_t::xfloor *xf[2] = {&linedef->frontsector->e->XFloor, &linedef->backsector->e->XFloor}; // Check for 3D-floors in the sector (mostly identical to what Legacy does here) if(xf[0]->ffloors.Size() || xf[1]->ffloors.Size()) { - fixed_t lowestceiling = open.top; - fixed_t highestfloor = open.bottom; - fixed_t lowestfloor[2] = { + double lowestceiling = open.top; + double highestfloor = open.bottom; + double lowestfloor[2] = { linedef->frontsector->floorplane.ZatPoint(x, y), linedef->backsector->floorplane.ZatPoint(x, y) }; FTextureID highestfloorpic; @@ -790,13 +775,13 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li if (!(rover->flags & FF_EXISTS)) continue; if (!(rover->flags & FF_SOLID)) continue; - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(x, y); - fixed_t ff_top=rover->top.plane->ZatPoint(x, y); + double ff_bottom=rover->bottom.plane->ZatPoint(x, y); + double ff_top=rover->top.plane->ZatPoint(x, y); - fixed_t delta1 = abs(thingbot - ((ff_bottom + ff_top) / 2)); - fixed_t delta2 = abs(thingtop - ((ff_bottom + ff_top) / 2)); + double delta1 = fabs(thingbot - ((ff_bottom + ff_top) / 2)); + double delta2 = fabs(thingtop - ((ff_bottom + ff_top) / 2)); - if(ff_bottom < lowestceiling && delta1 >= delta2) + if(ff_bottom < lowestceiling && delta1 > delta2) { lowestceiling = ff_bottom; lowestceilingpic = *rover->bottom.texture; @@ -824,12 +809,12 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li if (highestfloorplanes[0]) { open.frontfloorplane = *highestfloorplanes[0]; - if (open.frontfloorplane.c < 0) open.frontfloorplane.FlipVert(); + if (open.frontfloorplane.fC() < 0) open.frontfloorplane.FlipVert(); } if (highestfloorplanes[1]) { open.backfloorplane = *highestfloorplanes[1]; - if (open.backfloorplane.c < 0) open.backfloorplane.FlipVert(); + if (open.backfloorplane.fC() < 0) open.backfloorplane.FlipVert(); } } @@ -862,12 +847,6 @@ void P_Spawn3DFloors (void) switch(line->special) { case ExtraFloor_LightOnly: - // Note: I am spawning both this and ZDoom's ExtraLight data - // I don't want to mess with both at the same time during rendering - // so inserting this into the 3D-floor table as well seemed to be - // the best option. - // - // This does not yet handle case 0 properly! if (line->args[1] < 0 || line->args[1] > 2) line->args[1] = 0; P_Set3DFloor(line, 3, flagvals[line->args[1]], 0); break; @@ -911,20 +890,19 @@ void P_Spawn3DFloors (void) // //========================================================================== -secplane_t P_FindFloorPlane(sector_t * sector, fixed_t x, fixed_t y, fixed_t z) +secplane_t P_FindFloorPlane(sector_t * sector, const DVector3 &pos) { secplane_t retplane = sector->floorplane; if (sector->e) // apparently this can be called when the data is already gone { - for(unsigned int i=0;ie->XFloor.ffloors.Size();i++) + for(auto rover : sector->e->XFloor.ffloors) { - F3DFloor * rover= sector->e->XFloor.ffloors[i]; if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - if (rover->top.plane->ZatPoint(x, y) == z) + if (rover->top.plane->ZatPoint(pos) == pos.Z) { retplane = *rover->top.plane; - if (retplane.c<0) retplane.FlipVert(); + if (retplane.fC() < 0) retplane.FlipVert(); break; } } @@ -939,20 +917,20 @@ secplane_t P_FindFloorPlane(sector_t * sector, fixed_t x, fixed_t y, fixed_t z) // //========================================================================== -int P_Find3DFloor(sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool above, bool floor, fixed_t &cmpz) +int P_Find3DFloor(sector_t * sec, const DVector3 &pos, bool above, bool floor, double &cmpz) { // If no sector given, find the one appropriate if (sec == NULL) - sec = R_PointInSubsector(x, y)->sector; + sec = P_PointInSector(pos); // Above normal ceiling - cmpz = sec->ceilingplane.ZatPoint(x, y); - if (z >= cmpz) + cmpz = sec->ceilingplane.ZatPoint(pos); + if (pos.Z >= cmpz) return -1; // Below normal floor - cmpz = sec->floorplane.ZatPoint(x, y); - if (z <= cmpz) + cmpz = sec->floorplane.ZatPoint(pos); + if (pos.Z <= cmpz) return -1; // Looking through planes from top to bottom @@ -966,19 +944,19 @@ int P_Find3DFloor(sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool above, b if (above) { // z is above that floor - if (floor && (z >= (cmpz = rover->top.plane->ZatPoint(x, y)))) + if (floor && (pos.Z >= (cmpz = rover->top.plane->ZatPoint(pos)))) return i - 1; // z is above that ceiling - if (z >= (cmpz = rover->bottom.plane->ZatPoint(x, y))) + if (pos.Z >= (cmpz = rover->bottom.plane->ZatPoint(pos))) return i - 1; } else // below { // z is below that ceiling - if (!floor && (z <= (cmpz = rover->bottom.plane->ZatPoint(x, y)))) + if (!floor && (pos.Z <= (cmpz = rover->bottom.plane->ZatPoint(pos)))) return i; // z is below that floor - if (z <= (cmpz = rover->top.plane->ZatPoint(x, y))) + if (pos.Z <= (cmpz = rover->top.plane->ZatPoint(pos))) return i; } } @@ -1000,13 +978,13 @@ CCMD (dump3df) for (unsigned int i = 0; i < ffloors.Size(); i++) { - fixed_t height=ffloors[i]->top.plane->ZatPoint(sector->centerspot); - fixed_t bheight=ffloors[i]->bottom.plane->ZatPoint(sector->centerspot); + double height=ffloors[i]->top.plane->ZatPoint(sector->centerspot); + double bheight=ffloors[i]->bottom.plane->ZatPoint(sector->centerspot); IGNORE_FORMAT_PRE Printf("FFloor %d @ top = %f (model = %d), bottom = %f (model = %d), flags = %B, alpha = %d %s %s\n", - i, height / 65536., ffloors[i]->top.model->sectornum, - bheight / 65536., ffloors[i]->bottom.model->sectornum, + i, height, ffloors[i]->top.model->sectornum, + bheight, ffloors[i]->bottom.model->sectornum, ffloors[i]->flags, ffloors[i]->alpha, (ffloors[i]->flags&FF_EXISTS)? "Exists":"", (ffloors[i]->flags&FF_DYNAMIC)? "Dynamic":""); IGNORE_FORMAT_POST } diff --git a/src/p_3dfloors.h b/src/p_3dfloors.h index 4b8829d32..5268da0e2 100644 --- a/src/p_3dfloors.h +++ b/src/p_3dfloors.h @@ -68,7 +68,6 @@ struct F3DFloor { secplane_t * plane; const FTextureID * texture; - const fixed_t * texheight; sector_t * model; int isceiling; int vindex; @@ -86,8 +85,6 @@ struct F3DFloor short *toplightlevel; - fixed_t delta; - unsigned int flags; line_t* master; @@ -125,7 +122,6 @@ struct lightlist_t class player_s; void P_PlayerOnSpecial3DFloor(player_t* player); -void P_Get3DFloorAndCeiling(AActor * thing, sector_t * sector, fixed_t * floorz, fixed_t * ceilingz, int * floorpic); bool P_CheckFor3DFloorHit(AActor * mo); bool P_CheckFor3DCeilingHit(AActor * mo); void P_Recalculate3DFloors(sector_t *); @@ -139,14 +135,9 @@ void P_Spawn3DFloors( void ); struct FLineOpening; void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *linedef, - fixed_t x, fixed_t y, fixed_t refx, fixed_t refy, bool restrict); + double x, double y, bool restrict); -secplane_t P_FindFloorPlane(sector_t * sector, fixed_t x, fixed_t y, fixed_t z); -int P_Find3DFloor(sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool above, bool floor, fixed_t &cmpz); -inline int P_Find3DFloor(sector_t * sec, const fixedvec3 &pos, bool above, bool floor, fixed_t &cmpz) -{ - return P_Find3DFloor(sec, pos.x, pos.y, pos.z, above, floor, cmpz); -} - +secplane_t P_FindFloorPlane(sector_t * sector, const DVector3 &pos); +int P_Find3DFloor(sector_t * sec, const DVector3 &pos, bool above, bool floor, double &cmpz); #endif \ No newline at end of file diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index 1fc741915..4bb9ec4ba 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -36,6 +36,7 @@ #include "templates.h" +#include "p_3dmidtex.h" #include "p_local.h" #include "p_terrain.h" #include "p_maputl.h" @@ -50,7 +51,7 @@ // //============================================================================ -bool P_Scroll3dMidtex(sector_t *sector, int crush, fixed_t move, bool ceiling) +bool P_Scroll3dMidtex(sector_t *sector, int crush, double move, bool ceiling) { extsector_t::midtex::plane &scrollplane = ceiling? sector->e->Midtex.Ceiling : sector->e->Midtex.Floor; @@ -220,7 +221,7 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c // Retrieves top and bottom of the current line's mid texture. // //============================================================================ -bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, fixed_t *ptexbot) +bool P_GetMidTexturePosition(const line_t *line, int sideno, double *ptextop, double *ptexbot) { if (line->sidedef[0]==NULL || line->sidedef[1]==NULL) return false; @@ -230,32 +231,31 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, f FTexture * tex= TexMan(texnum); if (!tex) return false; - fixed_t totalscale = abs(FixedMul(side->GetTextureYScale(side_t::mid), tex->yScale)); - fixed_t y_offset = side->GetTextureYOffset(side_t::mid); - fixed_t textureheight = tex->GetScaledHeight(totalscale) << FRACBITS; - if (totalscale != FRACUNIT && !tex->bWorldPanning) + double totalscale = fabs(side->GetTextureYScaleF(side_t::mid)) * tex->GetScaleY(); + double y_offset = side->GetTextureYOffsetF(side_t::mid); + double textureheight = tex->GetHeight() / totalscale; + if (totalscale != 1. && !tex->bWorldPanning) { - y_offset = FixedDiv(y_offset, totalscale); + y_offset *= totalscale; } if(line->flags & ML_DONTPEGBOTTOM) { *ptexbot = y_offset + - MAX(line->frontsector->GetPlaneTexZ(sector_t::floor), line->backsector->GetPlaneTexZ(sector_t::floor)); + MAX(line->frontsector->GetPlaneTexZF(sector_t::floor), line->backsector->GetPlaneTexZF(sector_t::floor)); *ptextop = *ptexbot + textureheight; } else { *ptextop = y_offset + - MIN(line->frontsector->GetPlaneTexZ(sector_t::ceiling), line->backsector->GetPlaneTexZ(sector_t::ceiling)); + MIN(line->frontsector->GetPlaneTexZF(sector_t::ceiling), line->backsector->GetPlaneTexZF(sector_t::ceiling)); *ptexbot = *ptextop - textureheight; } return true; } - //============================================================================ // // P_LineOpening_3dMidtex @@ -273,12 +273,12 @@ bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, FLineOpening & return false; } - fixed_t tt, tb; + double tt, tb; open.abovemidtex = false; if (P_GetMidTexturePosition(linedef, 0, &tt, &tb)) { - if (thing->Z() + (thing->height/2) < (tt + tb)/2) + if (thing->Center() < (tt + tb)/2) { if (tb < open.top) { @@ -299,7 +299,7 @@ bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, FLineOpening & } // returns true if it touches the midtexture - return (abs(thing->Z() - tt) <= thing->MaxStepHeight); + return (fabs(thing->Z() - tt) <= thing->MaxStepHeight); } } return false; @@ -307,7 +307,7 @@ bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, FLineOpening & /* still have to figure out what this code from Eternity means... if((linedef->flags & ML_BLOCKMONSTERS) && !(mo->flags & (MF_FLOAT | MF_DROPOFF)) && - D_abs(mo->z - textop) <= 24*FRACUNIT) + fabs(mo->Z() - tt) <= 24) { opentop = openbottom; openrange = 0; diff --git a/src/p_3dmidtex.h b/src/p_3dmidtex.h index d308f4f3c..a24daff83 100644 --- a/src/p_3dmidtex.h +++ b/src/p_3dmidtex.h @@ -9,14 +9,14 @@ struct sector_t; struct line_t; class AActor; -bool P_Scroll3dMidtex(sector_t *sector, int crush, fixed_t move, bool ceiling); +bool P_Scroll3dMidtex(sector_t *sector, int crush, double move, bool ceiling); void P_Start3dMidtexInterpolations(TArray &list, sector_t *sec, bool ceiling); void P_Attach3dMidtexLinesToSector(sector_t *dest, int lineid, int tag, bool ceiling); -bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, fixed_t *ptexbot); +bool P_GetMidTexturePosition(const line_t *line, int sideno, double *ptextop, double *ptexbot); bool P_Check3dMidSwitch(AActor *actor, line_t *line, int side); bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, struct FLineOpening &open, bool restrict=false); -bool P_MoveLinkedSectors(sector_t *sector, int crush, fixed_t move, bool ceiling); +bool P_MoveLinkedSectors(sector_t *sector, int crush, double move, bool ceiling); void P_StartLinkedSectorInterpolations(TArray &list, sector_t *sector, bool ceiling); bool P_AddSectorLinks(sector_t *control, int tag, INTBOOL ceiling, int movetype); void P_AddSectorLinksByID(sector_t *control, int id, INTBOOL ceiling); diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 2668fd4a1..40fe650c1 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -148,6 +148,36 @@ enum PICKAF_RETURNTID = 2, }; +// ACS specific conversion functions to and from fixed point. +// These should be used to convert from and to sctipt variables +// so that there is a clear distinction between leftover fixed point code +// and genuinely needed conversions. + +inline double ACSToDouble(int acsval) +{ + return acsval / 65536.; +} + +inline float ACSToFloat(int acsval) +{ + return acsval / 65536.f; +} + +inline int DoubleToACS(double val) +{ + return xs_Fix<16>::ToFix(val); +} + +inline DAngle ACSToAngle(int acsval) +{ + return acsval * (360. / 65536.); +} + +inline int AngleToACS(DAngle ang) +{ + return ang.BAMs() >> 16; +} + struct CallReturn { CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway) @@ -692,7 +722,7 @@ void ACSStringPool::ReadStrings(PNGHandle *png, DWORD id) if (len != 0) { FPNGChunkArchive arc(png->File->GetFile(), id, len); - int32 i, j, poolsize; + int32_t i, j, poolsize; unsigned int h, bucketnum; char *str = NULL; @@ -738,7 +768,7 @@ void ACSStringPool::ReadStrings(PNGHandle *png, DWORD id) void ACSStringPool::WriteStrings(FILE *file, DWORD id) const { - int32 i, poolsize = (int32)Pool.Size(); + int32_t i, poolsize = (int32_t)Pool.Size(); if (poolsize == 0) { // No need to write if we don't have anything. @@ -1120,7 +1150,7 @@ static void DoGiveInv (AActor *actor, PClassActor *info, int amount) ? actor->player->PendingWeapon : NULL; bool hadweap = actor->player != NULL ? actor->player->ReadyWeapon != NULL : true; - AInventory *item = static_cast(Spawn (info, 0,0,0, NO_REPLACE)); + AInventory *item = static_cast(Spawn (info)); // This shouldn't count for the item statistics! item->ClearCounters(); @@ -1360,7 +1390,7 @@ public: void Serialize (FArchive &arc); private: sector_t *Sector; - fixed_t WatchD, LastD; + double WatchD, LastD; int Special, Arg0, Arg1, Arg2, Arg3, Arg4; TObjPtr Activator; line_t *Line; @@ -1396,9 +1426,9 @@ DPlaneWatcher::DPlaneWatcher (AActor *it, line_t *line, int lineSide, bool ceili { plane = Sector->floorplane; } - LastD = plane.d; - plane.ChangeHeight (height << FRACBITS); - WatchD = plane.d; + LastD = plane.fD(); + plane.ChangeHeight (height); + WatchD = plane.fD(); } else { @@ -1424,15 +1454,15 @@ void DPlaneWatcher::Tick () return; } - fixed_t newd; + double newd; if (bCeiling) { - newd = Sector->ceilingplane.d; + newd = Sector->ceilingplane.fD(); } else { - newd = Sector->floorplane.d; + newd = Sector->floorplane.fD(); } if ((LastD < WatchD && newd >= WatchD) || @@ -1624,13 +1654,13 @@ void FBehavior::StaticSerializeModuleStates (FArchive &arc) if (arc.IsStoring()) { arc.WriteString (module->ModuleName); - if (SaveVersion >= 4516) arc << ModSize; + arc << ModSize; } else { char *modname = NULL; arc << modname; - if (SaveVersion >= 4516) arc << ModSize; + arc << ModSize; if (stricmp (modname, module->ModuleName) != 0) { delete[] modname; @@ -2869,35 +2899,19 @@ void FBehavior::StaticStopMyScripts (AActor *actor) void P_SerializeACSScriptNumber(FArchive &arc, int &scriptnum, bool was2byte) { - if (SaveVersion < 3359) + arc << scriptnum; + // If the script number is negative, then it's really a name. + // So read/store the name after it. + if (scriptnum < 0) { - if (was2byte) + if (arc.IsStoring()) { - WORD oldver; - arc << oldver; - scriptnum = oldver; + arc.WriteName(FName(ENamedName(-scriptnum)).GetChars()); } else { - arc << scriptnum; - } - } - else - { - arc << scriptnum; - // If the script number is negative, then it's really a name. - // So read/store the name after it. - if (scriptnum < 0) - { - if (arc.IsStoring()) - { - arc.WriteName(FName(ENamedName(-scriptnum)).GetChars()); - } - else - { - const char *nam = arc.ReadName(); - scriptnum = -FName(nam); - } + const char *nam = arc.ReadName(); + scriptnum = -FName(nam); } } } @@ -2939,52 +2953,47 @@ void DACSThinker::Serialize (FArchive &arc) int scriptcount = 0; Super::Serialize (arc); - if (SaveVersion < 4515) - arc << Scripts << LastScript; + if (arc.IsStoring()) + { + DLevelScript *script; + script = Scripts; + while (script) + { + scriptcount++; + + // We want to store this list backwards, so we can't loose the last pointer + if (script->next == NULL) + break; + script = script->next; + } + arc << scriptcount; + + while (script) + { + arc << script; + script = script->prev; + } + } else { - if (arc.IsStoring()) + // We are running through this list backwards, so the next entry is the last processed + DLevelScript *next = NULL; + arc << scriptcount; + Scripts = NULL; + LastScript = NULL; + for (int i = 0; i < scriptcount; i++) { - DLevelScript *script; - script = Scripts; - while (script) - { - scriptcount++; + arc << Scripts; - // We want to store this list backwards, so we can't loose the last pointer - if (script->next == NULL) - break; - script = script->next; - } - arc << scriptcount; + Scripts->next = next; + Scripts->prev = NULL; + if (next != NULL) + next->prev = Scripts; - while (script) - { - arc << script; - script = script->prev; - } - } - else - { - // We are running through this list backwards, so the next entry is the last processed - DLevelScript *next = NULL; - arc << scriptcount; - Scripts = NULL; - LastScript = NULL; - for (int i = 0; i < scriptcount; i++) - { - arc << Scripts; + next = Scripts; - Scripts->next = next; - Scripts->prev = NULL; - if (next != NULL) - next->prev = Scripts; - - next = Scripts; - - if (i == 0) - LastScript = Scripts; - } + if (i == 0) + LastScript = Scripts; } } if (arc.IsStoring ()) @@ -3072,8 +3081,6 @@ void DLevelScript::Serialize (FArchive &arc) DWORD i; Super::Serialize (arc); - if (SaveVersion < 4515) - arc << next << prev; P_SerializeACSScriptNumber(arc, script, false); @@ -3110,23 +3117,9 @@ void DLevelScript::Serialize (FArchive &arc) arc << activefont << hudwidth << hudheight; - if (SaveVersion >= 3960) - { - arc << ClipRectLeft << ClipRectTop << ClipRectWidth << ClipRectHeight - << WrapWidth; - } - else - { - ClipRectLeft = ClipRectTop = ClipRectWidth = ClipRectHeight = WrapWidth = 0; - } - if (SaveVersion >= 4058) - { - arc << InModuleScriptNumber; - } - else - { // Don't worry about locating profiling info for old saves. - InModuleScriptNumber = -1; - } + arc << ClipRectLeft << ClipRectTop << ClipRectWidth << ClipRectHeight + << WrapWidth; + arc << InModuleScriptNumber; } DLevelScript::DLevelScript () @@ -3432,7 +3425,7 @@ void DLevelScript::ReplaceTextures (int fromnamei, int tonamei, int flags) } } -int DLevelScript::DoSpawn (int type, fixed_t x, fixed_t y, fixed_t z, int tid, int angle, bool force) +int DLevelScript::DoSpawn (int type, const DVector3 &pos, int tid, DAngle angle, bool force) { PClassActor *info = PClass::FindActor(FBehavior::StaticLookupString (type)); AActor *actor = NULL; @@ -3448,14 +3441,14 @@ int DLevelScript::DoSpawn (int type, fixed_t x, fixed_t y, fixed_t z, int tid, i return 0; } - actor = Spawn (info, x, y, z, ALLOW_REPLACE); + actor = Spawn (info, pos, ALLOW_REPLACE); if (actor != NULL) { ActorFlags2 oldFlags2 = actor->flags2; actor->flags2 |= MF2_PASSMOBJ; if (force || P_TestMobjLocation (actor)) { - actor->angle = angle << 24; + actor->Angles.Yaw = angle; actor->tid = tid; actor->AddToHash (); if (actor->flags & MF_SPECIAL) @@ -3476,6 +3469,12 @@ int DLevelScript::DoSpawn (int type, fixed_t x, fixed_t y, fixed_t z, int tid, i return spawncount; } +int DLevelScript::DoSpawn(int type, int x, int y, int z, int tid, int angle, bool force) +{ + return DoSpawn(type, DVector3(ACSToDouble(x), ACSToDouble(y), ACSToDouble(z)), tid, angle * (360. / 256), force); +} + + int DLevelScript::DoSpawnSpot (int type, int spot, int tid, int angle, bool force) { int spawned = 0; @@ -3487,12 +3486,12 @@ int DLevelScript::DoSpawnSpot (int type, int spot, int tid, int angle, bool forc while ( (aspot = iterator.Next ()) ) { - spawned += DoSpawn (type, aspot->X(), aspot->Y(), aspot->Z(), tid, angle, force); + spawned += DoSpawn (type, aspot->Pos(), tid, angle * (360. / 256), force); } } else if (activator != NULL) { - spawned += DoSpawn (type, activator->X(), activator->Y(), activator->Z(), tid, angle, force); + spawned += DoSpawn (type, activator->Pos(), tid, angle * (360. / 256), force); } return spawned; } @@ -3508,23 +3507,23 @@ int DLevelScript::DoSpawnSpotFacing (int type, int spot, int tid, bool force) while ( (aspot = iterator.Next ()) ) { - spawned += DoSpawn (type, aspot->X(), aspot->Y(), aspot->Z(), tid, aspot->angle >> 24, force); + spawned += DoSpawn (type, aspot->Pos(), tid, aspot->Angles.Yaw, force); } } else if (activator != NULL) { - spawned += DoSpawn (type, activator->X(), activator->Y(), activator->Z(), tid, activator->angle >> 24, force); + spawned += DoSpawn (type, activator->Pos(), tid, activator->Angles.Yaw, force); } return spawned; } -void DLevelScript::DoFadeTo (int r, int g, int b, int a, fixed_t time) +void DLevelScript::DoFadeTo (int r, int g, int b, int a, int time) { - DoFadeRange (0, 0, 0, -1, clamp(r, 0, 255), clamp(g, 0, 255), clamp(b, 0, 255), clamp(a, 0, FRACUNIT), time); + DoFadeRange (0, 0, 0, -1, clamp(r, 0, 255), clamp(g, 0, 255), clamp(b, 0, 255), clamp(a, 0, 65536), time); } void DLevelScript::DoFadeRange (int r1, int g1, int b1, int a1, - int r2, int g2, int b2, int a2, fixed_t time) + int r2, int g2, int b2, int a2, int time) { player_t *viewer; float ftime = (float)time / 65536.f; @@ -3805,7 +3804,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_Speed: - actor->Speed = value; + actor->Speed = ACSToDouble(value); break; case APROP_Damage: @@ -3813,7 +3812,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_Alpha: - actor->alpha = value; + actor->Alpha = ACSToDouble(value); break; case APROP_RenderStyle: @@ -3849,7 +3848,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) case APROP_JumpZ: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) - static_cast(actor)->JumpZ = value; + static_cast(actor)->JumpZ = ACSToDouble(value); break; // [GRB] case APROP_ChaseGoal: @@ -3888,7 +3887,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_Gravity: - actor->gravity = value; + actor->Gravity = ACSToDouble(value); break; case APROP_SeeSound: @@ -3924,11 +3923,11 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_DamageFactor: - actor->DamageFactor = value; + actor->DamageFactor = ACSToDouble(value); break; case APROP_DamageMultiplier: - actor->DamageMultiply = value; + actor->DamageMultiply = ACSToDouble(value); break; case APROP_MasterTID: @@ -3938,11 +3937,11 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_ScaleX: - actor->scaleX = value; + actor->Scale.X = ACSToDouble(value); break; case APROP_ScaleY: - actor->scaleY = value; + actor->Scale.Y = ACSToDouble(value); break; case APROP_Mass: @@ -3962,23 +3961,23 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_MeleeRange: - actor->meleerange = value; + actor->meleerange = ACSToDouble(value); break; case APROP_ViewHeight: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) { - static_cast(actor)->ViewHeight = value; + static_cast(actor)->ViewHeight = ACSToDouble(value); if (actor->player != NULL) { - actor->player->viewheight = value; + actor->player->viewheight = ACSToDouble(value); } } break; case APROP_AttackZOffset: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) - static_cast(actor)->AttackZOffset = value; + static_cast(actor)->AttackZOffset = ACSToDouble(value); break; case APROP_StencilColor: @@ -3986,7 +3985,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_Friction: - actor->Friction = value; + actor->Friction = ACSToDouble(value); default: // do nothing. @@ -4005,11 +4004,11 @@ int DLevelScript::GetActorProperty (int tid, int property) switch (property) { case APROP_Health: return actor->health; - case APROP_Speed: return actor->Speed; + case APROP_Speed: return DoubleToACS(actor->Speed); case APROP_Damage: return actor->GetMissileDamage(0,1); - case APROP_DamageFactor:return actor->DamageFactor; - case APROP_DamageMultiplier: return actor->DamageMultiply; - case APROP_Alpha: return actor->alpha; + case APROP_DamageFactor:return DoubleToACS(actor->DamageFactor); + case APROP_DamageMultiplier: return DoubleToACS(actor->DamageMultiply); + case APROP_Alpha: return DoubleToACS(actor->Alpha); case APROP_RenderStyle: for (int style = STYLE_None; style < STYLE_Count; ++style) { // Check for a legacy render style that matches. if (LegacyRenderStyles[style] == actor->RenderStyle) @@ -4020,7 +4019,7 @@ int DLevelScript::GetActorProperty (int tid, int property) // The current render style isn't expressable as a legacy style, // so pretends it's normal. return STYLE_Normal; - case APROP_Gravity: return actor->gravity; + case APROP_Gravity: return DoubleToACS(actor->Gravity); case APROP_Invulnerable:return !!(actor->flags2 & MF2_INVULNERABLE); case APROP_Ambush: return !!(actor->flags & MF_AMBUSH); case APROP_Dropped: return !!(actor->flags & MF_DROPPED); @@ -4041,7 +4040,7 @@ int DLevelScript::GetActorProperty (int tid, int property) case APROP_JumpZ: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) { - return static_cast(actor)->JumpZ; // [GRB] + return DoubleToACS(static_cast(actor)->JumpZ); // [GRB] } else { @@ -4052,18 +4051,18 @@ int DLevelScript::GetActorProperty (int tid, int property) case APROP_TargetTID: return (actor->target != NULL)? actor->target->tid : 0; case APROP_TracerTID: return (actor->tracer != NULL)? actor->tracer->tid : 0; case APROP_WaterLevel: return actor->waterlevel; - case APROP_ScaleX: return actor->scaleX; - case APROP_ScaleY: return actor->scaleY; + case APROP_ScaleX: return DoubleToACS(actor->Scale.X); + case APROP_ScaleY: return DoubleToACS(actor->Scale.Y); case APROP_Mass: return actor->Mass; case APROP_Accuracy: return actor->accuracy; case APROP_Stamina: return actor->stamina; - case APROP_Height: return actor->height; - case APROP_Radius: return actor->radius; + case APROP_Height: return DoubleToACS(actor->Height); + case APROP_Radius: return DoubleToACS(actor->radius); case APROP_ReactionTime:return actor->reactiontime; - case APROP_MeleeRange: return actor->meleerange; + case APROP_MeleeRange: return DoubleToACS(actor->meleerange); case APROP_ViewHeight: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) { - return static_cast(actor)->ViewHeight; + return DoubleToACS(static_cast(actor)->ViewHeight); } else { @@ -4072,7 +4071,7 @@ int DLevelScript::GetActorProperty (int tid, int property) case APROP_AttackZOffset: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) { - return static_cast(actor)->AttackZOffset; + return DoubleToACS(static_cast(actor)->AttackZOffset); } else { @@ -4087,7 +4086,7 @@ int DLevelScript::GetActorProperty (int tid, int property) case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies()); case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag()); case APROP_StencilColor:return actor->fillcolor; - case APROP_Friction: return actor->Friction; + case APROP_Friction: return DoubleToACS(actor->Friction); default: return 0; } @@ -4584,7 +4583,7 @@ static void SetUserVariable(AActor *self, FName varname, int index, int value) } else { - type->SetValue(addr, FIXED2DBL(value)); + type->SetValue(addr, ACSToDouble(value)); } } } @@ -4598,7 +4597,7 @@ static int GetUserVariable(AActor *self, FName varname, int index) { if (type->IsKindOf(RUNTIME_CLASS(PFloat))) { - return FLOAT2FIXED(type->GetValueFloat(addr)); + return DoubleToACS(type->GetValueFloat(addr)); } else if (type->IsA(RUNTIME_CLASS(PName))) { @@ -4636,7 +4635,7 @@ static void DoSetCVar(FBaseCVar *cvar, int value, bool is_string, bool force=fal } else if (cvar->GetRealType() == CVAR_Float) { - val.Float = FIXED2FLOAT(value); + val.Float = ACSToFloat(value); type = CVAR_Float; } else @@ -4667,7 +4666,7 @@ static int DoGetCVar(FBaseCVar *cvar, bool is_string) else if (cvar->GetRealType() == CVAR_Float) { val = cvar->GetGenericRep(CVAR_Float); - return FLOAT2FIXED(val.Float); + return DoubleToACS(val.Float); } else { @@ -4765,24 +4764,25 @@ static int SetCVar(AActor *activator, const char *cvarname, int value, bool is_s return 1; } -static bool DoSpawnDecal(AActor *actor, const FDecalTemplate *tpl, int flags, angle_t angle, fixed_t zofs, fixed_t distance) +static bool DoSpawnDecal(AActor *actor, const FDecalTemplate *tpl, int flags, DAngle angle, double zofs, double distance) { if (!(flags & SDF_ABSANGLE)) { - angle += actor->angle; + angle += actor->Angles.Yaw; } return NULL != ShootDecal(tpl, actor, actor->Sector, actor->X(), actor->Y(), - actor->Z() + (actor->height>>1) - actor->floorclip + actor->GetBobOffset() + zofs, + actor->Center() - actor->Floorclip + actor->GetBobOffset() + zofs, angle, distance, !!(flags & SDF_PERMANENT)); } static void SetActorAngle(AActor *activator, int tid, int angle, bool interpolate) { + DAngle an = ACSToAngle(angle); if (tid == 0) { if (activator != NULL) { - activator->SetAngle(angle << 16, interpolate); + activator->SetAngle(an, interpolate); } } else @@ -4792,18 +4792,19 @@ static void SetActorAngle(AActor *activator, int tid, int angle, bool interpolat while ((actor = iterator.Next())) { - actor->SetAngle(angle << 16, interpolate); + actor->SetAngle(an, interpolate); } } } static void SetActorPitch(AActor *activator, int tid, int angle, bool interpolate) { + DAngle an = ACSToAngle(angle); if (tid == 0) { if (activator != NULL) { - activator->SetPitch(angle << 16, interpolate); + activator->SetPitch(an, interpolate); } } else @@ -4813,18 +4814,19 @@ static void SetActorPitch(AActor *activator, int tid, int angle, bool interpolat while ((actor = iterator.Next())) { - actor->SetPitch(angle << 16, interpolate); + actor->SetPitch(an, interpolate); } } } static void SetActorRoll(AActor *activator, int tid, int angle, bool interpolate) { + DAngle an = ACSToAngle(angle); if (tid == 0) { if (activator != NULL) { - activator->SetRoll(angle << 16, interpolate); + activator->SetRoll(an, interpolate); } } else @@ -4834,7 +4836,7 @@ static void SetActorRoll(AActor *activator, int tid, int angle, bool interpolate while ((actor = iterator.Next())) { - actor->SetRoll(angle << 16, interpolate); + actor->SetRoll(an, interpolate); } } } @@ -4910,7 +4912,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) return GetUDMFInt(UDMF_Line, LineFromID(args[0]), FBehavior::StaticLookupString(args[1])); case ACSF_GetLineUDMFFixed: - return GetUDMFFixed(UDMF_Line, LineFromID(args[0]), FBehavior::StaticLookupString(args[1])); + return DoubleToACS(GetUDMFFloat(UDMF_Line, LineFromID(args[0]), FBehavior::StaticLookupString(args[1]))); case ACSF_GetThingUDMFInt: case ACSF_GetThingUDMFFixed: @@ -4920,25 +4922,25 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) return GetUDMFInt(UDMF_Sector, P_FindFirstSectorFromTag(args[0]), FBehavior::StaticLookupString(args[1])); case ACSF_GetSectorUDMFFixed: - return GetUDMFFixed(UDMF_Sector, P_FindFirstSectorFromTag(args[0]), FBehavior::StaticLookupString(args[1])); + return DoubleToACS(GetUDMFFloat(UDMF_Sector, P_FindFirstSectorFromTag(args[0]), FBehavior::StaticLookupString(args[1]))); case ACSF_GetSideUDMFInt: return GetUDMFInt(UDMF_Side, SideFromID(args[0], args[1]), FBehavior::StaticLookupString(args[2])); case ACSF_GetSideUDMFFixed: - return GetUDMFFixed(UDMF_Side, SideFromID(args[0], args[1]), FBehavior::StaticLookupString(args[2])); + return DoubleToACS(GetUDMFFloat(UDMF_Side, SideFromID(args[0], args[1]), FBehavior::StaticLookupString(args[2]))); case ACSF_GetActorVelX: actor = SingleActorFromTID(args[0], activator); - return actor != NULL? actor->vel.x : 0; + return actor != NULL? DoubleToACS(actor->Vel.X) : 0; case ACSF_GetActorVelY: actor = SingleActorFromTID(args[0], activator); - return actor != NULL? actor->vel.y : 0; + return actor != NULL? DoubleToACS(actor->Vel.Y) : 0; case ACSF_GetActorVelZ: actor = SingleActorFromTID(args[0], activator); - return actor != NULL? actor->vel.z : 0; + return actor != NULL? DoubleToACS(actor->Vel.Z) : 0; case ACSF_SetPointer: if (activator) @@ -4994,11 +4996,11 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) { if (actor->player != NULL) { - return actor->player->mo->ViewHeight + actor->player->crouchviewdelta; + return DoubleToACS(actor->player->mo->ViewHeight + actor->player->crouchviewdelta); } else { - return actor->GetCameraHeight(); + return DoubleToACS(actor->GetCameraHeight()); } } else return 0; @@ -5043,8 +5045,8 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) case ACSF_SetSkyScrollSpeed: { - if (args[0] == 1) level.skyspeed1 = FIXED2FLOAT(args[1]); - else if (args[0] == 2) level.skyspeed2 = FIXED2FLOAT(args[1]); + if (args[0] == 1) level.skyspeed1 = ACSToFloat(args[1]); + else if (args[0] == 2) level.skyspeed2 = ACSToFloat(args[1]); return 1; } @@ -5080,7 +5082,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) return equippedarmor->MaxAmount; case ARMORINFO_SAVEPERCENT: - return equippedarmor->SavePercent; + return DoubleToACS(equippedarmor->SavePercent); case ARMORINFO_MAXABSORB: return equippedarmor->MaxAbsorb; @@ -5108,20 +5110,23 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) return (CheckActorProperty(args[0], args[1], args[2])); case ACSF_SetActorVelocity: - if (args[0] == 0) - { - P_Thing_SetVelocity(activator, args[1], args[2], args[3], !!args[4], !!args[5]); - } - else - { - TActorIterator iterator (args[0]); - - while ( (actor = iterator.Next ()) ) - { - P_Thing_SetVelocity(actor, args[1], args[2], args[3], !!args[4], !!args[5]); - } - } - return 0; + { + DVector3 vel(ACSToDouble(args[1]), ACSToDouble(args[2]), ACSToDouble(args[3])); + if (args[0] == 0) + { + P_Thing_SetVelocity(activator, vel, !!args[4], !!args[5]); + } + else + { + TActorIterator iterator(args[0]); + + while ((actor = iterator.Next())) + { + P_Thing_SetVelocity(actor, vel, !!args[4], !!args[5]); + } + } + return 0; + } case ACSF_SetUserVariable: { @@ -5278,7 +5283,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) FPolyObj *poly = PO_GetPolyobj(args[0]); if (poly != NULL) { - return poly->StartSpot.x; + return DoubleToACS(poly->StartSpot.pos.X); } } return FIXED_MAX; @@ -5288,7 +5293,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) FPolyObj *poly = PO_GetPolyobj(args[0]); if (poly != NULL) { - return poly->StartSpot.y; + return DoubleToACS(poly->StartSpot.pos.Y); } } return FIXED_MAX; @@ -5368,13 +5373,13 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) return P_IsTIDUsed(args[0]); case ACSF_Sqrt: - return xs_FloorToInt(sqrt(double(args[0]))); + return xs_FloorToInt(g_sqrt(double(args[0]))); case ACSF_FixedSqrt: - return FLOAT2FIXED(sqrt(FIXED2DBL(args[0]))); + return DoubleToACS(g_sqrt(ACSToDouble(args[0]))); case ACSF_VectorLength: - return FLOAT2FIXED(DVector2(FIXED2DBL(args[0]), FIXED2DBL(args[1])).Length()); + return DoubleToACS(DVector2(ACSToDouble(args[0]), ACSToDouble(args[1])).Length()); case ACSF_SetHUDClipRect: ClipRectLeft = argCount > 0 ? args[0] : 0; @@ -5441,12 +5446,12 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) //[RC] A bullet firing function for ACS. Thanks to DavidPH. case ACSF_LineAttack: { - fixed_t angle = args[1] << FRACBITS; - fixed_t pitch = args[2] << FRACBITS; + DAngle angle = ACSToAngle(args[1]); + DAngle pitch = ACSToAngle(args[2]); int damage = args[3]; FName pufftype = argCount > 4 && args[4]? FName(FBehavior::StaticLookupString(args[4])) : NAME_BulletPuff; FName damagetype = argCount > 5 && args[5]? FName(FBehavior::StaticLookupString(args[5])) : NAME_None; - fixed_t range = argCount > 6 && args[6]? args[6] : MISSILERANGE; + double range = argCount > 6 && args[6]? ACSToDouble(args[6]) : MISSILERANGE; int flags = argCount > 7 && args[7]? args[7] : 0; int pufftid = argCount > 8 && args[8]? args[8] : 0; @@ -5501,9 +5506,9 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) AActor *spot; int chan = argCount > 2 ? args[2] : CHAN_BODY; - float vol = argCount > 3 ? FIXED2FLOAT(args[3]) : 1.f; + float vol = argCount > 3 ? ACSToFloat(args[3]) : 1.f; INTBOOL looping = argCount > 4 ? args[4] : false; - float atten = argCount > 5 ? FIXED2FLOAT(args[5]) : ATTN_NORM; + float atten = argCount > 5 ? ACSToFloat(args[5]) : ATTN_NORM; if (args[0] == 0) { @@ -5557,7 +5562,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) // SoundVolume(int tid, int channel, fixed volume) { int chan = args[1]; - float volume = FIXED2FLOAT(args[2]); + float volume = ACSToFloat(args[2]); if (args[0] == 0) { @@ -5665,9 +5670,9 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (tpl != NULL) { int flags = (argCount > 2) ? args[2] : 0; - angle_t angle = (argCount > 3) ? (args[3] << FRACBITS) : 0; - fixed_t zoffset = (argCount > 4) ? (args[4] << FRACBITS) : 0; - fixed_t distance = (argCount > 5) ? (args[5] << FRACBITS) : 64*FRACUNIT; + DAngle angle = ACSToAngle((argCount > 3) ? args[3] : 0); + int zoffset = (argCount > 4) ? args[4]: 0; + int distance = (argCount > 5) ? args[5] : 64; if (args[0] == 0) { @@ -5778,9 +5783,9 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) { return P_StartQuakeXYZ(activator, args[0], args[1], args[2], args[3], args[4], args[5], args[6], FBehavior::StaticLookupString(args[7]), argCount > 8 ? args[8] : 0, - argCount > 9 ? FIXED2DBL(args[9]) : 1.0, - argCount > 10 ? FIXED2DBL(args[10]) : 1.0, - argCount > 11 ? FIXED2DBL(args[11]) : 1.0, + argCount > 9 ? ACSToDouble(args[9]) : 1.0, + argCount > 10 ? ACSToDouble(args[10]) : 1.0, + argCount > 11 ? ACSToDouble(args[11]) : 1.0, argCount > 12 ? args[12] : 0, argCount > 13 ? args[13] : 0); } @@ -5876,7 +5881,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) flags = args[7]; } - AActor* pickedActor = P_LinePickActor(actor, args[1] << 16, args[3], args[2] << 16, actorMask, wallMask); + AActor* pickedActor = P_LinePickActor(actor, ACSToAngle(args[1]), ACSToDouble(args[3]), ACSToAngle(args[2]), actorMask, wallMask); if (pickedActor == NULL) { return 0; } @@ -5936,11 +5941,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) // [Nash] Actor roll functions. Let's roll! case ACSF_SetActorRoll: - actor = SingleActorFromTID(args[0], activator); - if (actor != NULL) - { - actor->SetRoll(args[1] << 16, false); - } + SetActorRoll(activator, args[0], args[1], false); return 0; case ACSF_ChangeActorRoll: @@ -5952,22 +5953,22 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) case ACSF_GetActorRoll: actor = SingleActorFromTID(args[0], activator); - return actor != NULL? actor->roll >> 16 : 0; + return actor != NULL? AngleToACS(actor->Angles.Roll) : 0; // [ZK] A_Warp in ACS case ACSF_Warp: { int tid_dest = args[0]; - fixed_t xofs = args[1]; - fixed_t yofs = args[2]; - fixed_t zofs = args[3]; - angle_t angle = args[4]; + int xofs = args[1]; + int yofs = args[2]; + int zofs = args[3]; + int angle = args[4]; int flags = args[5]; const char *statename = argCount > 6 ? FBehavior::StaticLookupString(args[6]) : ""; bool exact = argCount > 7 ? !!args[7] : false; - fixed_t heightoffset = argCount > 8 ? args[8] : 0; - fixed_t radiusoffset = argCount > 9 ? args[9] : 0; - fixed_t pitch = argCount > 10 ? args[10] : 0; + int heightoffset = argCount > 8 ? args[8] : 0; + int radiusoffset = argCount > 9 ? args[9] : 0; + int pitch = argCount > 10 ? args[10] : 0; FState *state = argCount > 6 ? activator->GetClass()->FindStateByString(statename, exact) : 0; @@ -5985,7 +5986,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (activator == NULL || !reference) return false; - if (P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags, heightoffset, radiusoffset, pitch)) + if (P_Thing_Warp(activator, reference, ACSToDouble(xofs), ACSToDouble(yofs), ACSToDouble(zofs), ACSToAngle(angle), flags, ACSToDouble(heightoffset), ACSToDouble(radiusoffset), ACSToAngle(pitch))) { if (state && argCount > 6) { @@ -6042,15 +6043,15 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) bool fullbright = argCount > 1 ? !!args[1] : false; int lifetime = argCount > 2 ? args[2] : 35; int size = argCount > 3 ? args[3] : 1; - fixed_t x = argCount > 4 ? args[4] : 0; - fixed_t y = argCount > 5 ? args[5] : 0; - fixed_t z = argCount > 6 ? args[6] : 0; - fixed_t xvel = argCount > 7 ? args[7] : 0; - fixed_t yvel = argCount > 8 ? args[8] : 0; - fixed_t zvel = argCount > 9 ? args[9] : 0; - fixed_t accelx = argCount > 10 ? args[10] : 0; - fixed_t accely = argCount > 11 ? args[11] : 0; - fixed_t accelz = argCount > 12 ? args[12] : 0; + int x = argCount > 4 ? args[4] : 0; + int y = argCount > 5 ? args[5] : 0; + int z = argCount > 6 ? args[6] : 0; + int xvel = argCount > 7 ? args[7] : 0; + int yvel = argCount > 8 ? args[8] : 0; + int zvel = argCount > 9 ? args[9] : 0; + int accelx = argCount > 10 ? args[10] : 0; + int accely = argCount > 11 ? args[11] : 0; + int accelz = argCount > 12 ? args[12] : 0; int startalpha = argCount > 13 ? args[13] : 0xFF; // Byte trans int fadestep = argCount > 14 ? args[14] : -1; @@ -6060,7 +6061,10 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) size = clamp(size, 0, 65535); // Clamp to word if (lifetime != 0) - P_SpawnParticle(x, y, z, xvel, yvel, zvel, color, fullbright, startalpha, lifetime, size, fadestep, accelx, accely, accelz); + P_SpawnParticle(DVector3(ACSToDouble(x), ACSToDouble(y), ACSToDouble(z)), + DVector3(ACSToDouble(xvel), ACSToDouble(yvel), ACSToDouble(zvel)), + DVector3(ACSToDouble(accelx), ACSToDouble(accely), ACSToDouble(accelz)), + color, fullbright, startalpha/255., lifetime, size, fadestep/255.); } break; @@ -7772,7 +7776,7 @@ scriptwait: break; case PCD_PRINTFIXED: - work.AppendFormat ("%g", FIXED2FLOAT(STACK(1))); + work.AppendFormat ("%g", ACSToDouble(STACK(1))); --sp; break; @@ -7985,10 +7989,10 @@ scriptwait: int type = Stack[optstart-6]; int id = Stack[optstart-5]; EColorRange color; - float x = FIXED2FLOAT(Stack[optstart-3]); - float y = FIXED2FLOAT(Stack[optstart-2]); - float holdTime = FIXED2FLOAT(Stack[optstart-1]); - fixed_t alpha; + float x = ACSToFloat(Stack[optstart-3]); + float y = ACSToFloat(Stack[optstart-2]); + float holdTime = ACSToFloat(Stack[optstart-1]); + float alpha; DHUDMessage *msg; if (type & HUDMSG_COLORSTRING) @@ -8003,29 +8007,29 @@ scriptwait: switch (type & 0xFF) { default: // normal - alpha = (optstart < sp) ? Stack[optstart] : FRACUNIT; + alpha = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 1.f; msg = new DHUDMessage (activefont, work, x, y, hudwidth, hudheight, color, holdTime); break; case 1: // fade out { - float fadeTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.5f; - alpha = (optstart < sp-1) ? Stack[optstart+1] : FRACUNIT; + float fadeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f; + alpha = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 1.f; msg = new DHUDMessageFadeOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, fadeTime); } break; case 2: // type on, then fade out { - float typeTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.05f; - float fadeTime = (optstart < sp-1) ? FIXED2FLOAT(Stack[optstart+1]) : 0.5f; - alpha = (optstart < sp-2) ? Stack[optstart+2] : FRACUNIT; + float typeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.05f; + float fadeTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f; + alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart+2]) : 1.f; msg = new DHUDMessageTypeOnFadeOut (activefont, work, x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime); } break; case 3: // fade in, then fade out { - float inTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.5f; - float outTime = (optstart < sp-1) ? FIXED2FLOAT(Stack[optstart+1]) : 0.5f; - alpha = (optstart < sp-2) ? Stack[optstart+2] : FRACUNIT; + float inTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f; + float outTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f; + alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart + 2]) : 1.f; msg = new DHUDMessageFadeInOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, inTime, outTime); } break; @@ -8385,23 +8389,23 @@ scriptwait: break; case PCD_SETGRAVITY: - level.gravity = (float)STACK(1) / 65536.f; + level.gravity = ACSToDouble(STACK(1)); sp--; break; case PCD_SETGRAVITYDIRECT: - level.gravity = (float)uallong(pc[0]) / 65536.f; + level.gravity = ACSToDouble(uallong(pc[0])); pc++; break; case PCD_SETAIRCONTROL: - level.aircontrol = STACK(1); + level.aircontrol = ACSToDouble(STACK(1)); sp--; G_AirControlChanged (); break; case PCD_SETAIRCONTROLDIRECT: - level.aircontrol = uallong(pc[0]); + level.aircontrol = ACSToDouble(uallong(pc[0])); pc++; G_AirControlChanged (); break; @@ -8682,7 +8686,7 @@ scriptwait: bool result = false; AActor *actor = SingleActorFromTID (STACK(5), activator); if (actor != NULL) - result = P_MoveThing(actor, STACK(4), STACK(3), STACK(2), !!STACK(1)); + result = P_MoveThing(actor, DVector3(ACSToDouble(STACK(4)), ACSToDouble(STACK(3)), ACSToDouble(STACK(2))), !!STACK(1)); sp -= 4; STACK(1) = result; } @@ -8699,11 +8703,11 @@ scriptwait: } else if (pcd == PCD_GETACTORZ) { - STACK(1) = actor->Z() + actor->GetBobOffset(); + STACK(1) = DoubleToACS(actor->Z() + actor->GetBobOffset()); } else { - STACK(1) = pcd == PCD_GETACTORX ? actor->X() : pcd == PCD_GETACTORY ? actor->Y() : actor->Z(); + STACK(1) = DoubleToACS(pcd == PCD_GETACTORX ? actor->X() : pcd == PCD_GETACTORY ? actor->Y() : actor->Z()); } } break; @@ -8711,35 +8715,35 @@ scriptwait: case PCD_GETACTORFLOORZ: { AActor *actor = SingleActorFromTID(STACK(1), activator); - STACK(1) = actor == NULL ? 0 : actor->floorz; + STACK(1) = actor == NULL ? 0 : DoubleToACS(actor->floorz); } break; case PCD_GETACTORCEILINGZ: { AActor *actor = SingleActorFromTID(STACK(1), activator); - STACK(1) = actor == NULL ? 0 : actor->ceilingz; + STACK(1) = actor == NULL ? 0 : DoubleToACS(actor->ceilingz); } break; case PCD_GETACTORANGLE: { AActor *actor = SingleActorFromTID(STACK(1), activator); - STACK(1) = actor == NULL ? 0 : actor->angle >> 16; + STACK(1) = actor == NULL ? 0 : AngleToACS(actor->Angles.Yaw); } break; case PCD_GETACTORPITCH: { AActor *actor = SingleActorFromTID(STACK(1), activator); - STACK(1) = actor == NULL ? 0 : actor->pitch >> 16; + STACK(1) = actor == NULL ? 0 : AngleToACS(actor->Angles.Pitch); } break; case PCD_GETLINEROWOFFSET: if (activationline != NULL) { - PushToStack (activationline->sidedef[0]->GetTextureYOffset(side_t::mid) >> FRACBITS); + PushToStack (int(activationline->sidedef[0]->GetTextureYOffsetF(side_t::mid))); } else { @@ -8756,28 +8760,27 @@ scriptwait: { int tag = STACK(3); int secnum; - fixed_t x = STACK(2) << FRACBITS; - fixed_t y = STACK(1) << FRACBITS; - fixed_t z = 0; + DVector2 pos(ACSToDouble(STACK(2)), ACSToDouble(STACK(1))); + double z = 0; if (tag != 0) secnum = P_FindFirstSectorFromTag (tag); else - secnum = int(P_PointInSector (x, y) - sectors); + secnum = int(P_PointInSector (pos) - sectors); if (secnum >= 0) { if (pcd == PCD_GETSECTORFLOORZ) { - z = sectors[secnum].floorplane.ZatPoint (x, y); + z = sectors[secnum].floorplane.ZatPoint (pos); } else { - z = sectors[secnum].ceilingplane.ZatPoint (x, y); + z = sectors[secnum].ceilingplane.ZatPoint (pos); } } sp -= 2; - STACK(1) = z; + STACK(1) = DoubleToACS(z); } break; @@ -8858,18 +8861,18 @@ scriptwait: { // translation using desaturation int start = STACK(8); int end = STACK(7); - fixed_t r1 = STACK(6); - fixed_t g1 = STACK(5); - fixed_t b1 = STACK(4); - fixed_t r2 = STACK(3); - fixed_t g2 = STACK(2); - fixed_t b2 = STACK(1); + int r1 = STACK(6); + int g1 = STACK(5); + int b1 = STACK(4); + int r2 = STACK(3); + int g2 = STACK(2); + int b2 = STACK(1); sp -= 8; if (translation != NULL) translation->AddDesaturation(start, end, - FIXED2DBL(r1), FIXED2DBL(g1), FIXED2DBL(b1), - FIXED2DBL(r2), FIXED2DBL(g2), FIXED2DBL(b2)); + ACSToDouble(r1), ACSToDouble(g1), ACSToDouble(b1), + ACSToDouble(r2), ACSToDouble(g2), ACSToDouble(b2)); } break; @@ -8881,15 +8884,15 @@ scriptwait: break; case PCD_SIN: - STACK(1) = finesine[angle_t(STACK(1)<<16)>>ANGLETOFINESHIFT]; + STACK(1) = DoubleToACS(ACSToAngle(STACK(1)).Sin()); break; case PCD_COS: - STACK(1) = finecosine[angle_t(STACK(1)<<16)>>ANGLETOFINESHIFT]; + STACK(1) = DoubleToACS(ACSToAngle(STACK(1)).Cos()); break; case PCD_VECTORANGLE: - STACK(2) = R_PointToAngle2 (0, 0, STACK(2), STACK(1)) >> 16; + STACK(2) = AngleToACS(VecToAngle(STACK(2), STACK(1)).Degrees); sp--; break; @@ -9069,15 +9072,15 @@ scriptwait: // Like Thing_Projectile(Gravity) specials, but you can give the // projectile a TID. // Thing_Projectile2 (tid, type, angle, speed, vspeed, gravity, newtid); - P_Thing_Projectile (STACK(7), activator, STACK(6), NULL, ((angle_t)(STACK(5)<<24)), - STACK(4)<<(FRACBITS-3), STACK(3)<<(FRACBITS-3), 0, NULL, STACK(2), STACK(1), false); + P_Thing_Projectile(STACK(7), activator, STACK(6), NULL, STACK(5) * (360. / 256.), + STACK(4) / 8., STACK(3) / 8., 0, NULL, STACK(2), STACK(1), false); sp -= 7; break; case PCD_SPAWNPROJECTILE: // Same, but takes an actor name instead of a spawn ID. - P_Thing_Projectile (STACK(7), activator, 0, FBehavior::StaticLookupString (STACK(6)), ((angle_t)(STACK(5)<<24)), - STACK(4)<<(FRACBITS-3), STACK(3)<<(FRACBITS-3), 0, NULL, STACK(2), STACK(1), false); + P_Thing_Projectile(STACK(7), activator, 0, FBehavior::StaticLookupString(STACK(6)), STACK(5) * (360. / 256.), + STACK(4) / 8., STACK(3) / 8., 0, NULL, STACK(2), STACK(1), false); sp -= 7; break; @@ -9256,12 +9259,12 @@ scriptwait: switch (STACK(1)) { case PLAYERINFO_TEAM: STACK(2) = userinfo->GetTeam(); break; - case PLAYERINFO_AIMDIST: STACK(2) = userinfo->GetAimDist(); break; + case PLAYERINFO_AIMDIST: STACK(2) = (SDWORD)(userinfo->GetAimDist() * (0x40000000/90.)); break; // Yes, this has been returning a BAM since its creation. case PLAYERINFO_COLOR: STACK(2) = userinfo->GetColor(); break; case PLAYERINFO_GENDER: STACK(2) = userinfo->GetGender(); break; case PLAYERINFO_NEVERSWITCH: STACK(2) = userinfo->GetNeverSwitch(); break; - case PLAYERINFO_MOVEBOB: STACK(2) = userinfo->GetMoveBob(); break; - case PLAYERINFO_STILLBOB: STACK(2) = userinfo->GetStillBob(); break; + case PLAYERINFO_MOVEBOB: STACK(2) = DoubleToACS(userinfo->GetMoveBob()); break; + case PLAYERINFO_STILLBOB: STACK(2) = DoubleToACS(userinfo->GetStillBob()); break; case PLAYERINFO_PLAYERCLASS: STACK(2) = userinfo->GetPlayerClassNum(); break; case PLAYERINFO_DESIREDFOV: STACK(2) = (int)pl->DesiredFOV; break; case PLAYERINFO_FOV: STACK(2) = (int)pl->FOV; break; diff --git a/src/p_acs.h b/src/p_acs.h index c418dfe1a..6a7a8d3a1 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -907,16 +907,17 @@ protected: static int CountPlayers (); static void SetLineTexture (int lineid, int side, int position, int name); static void ReplaceTextures (int fromname, int toname, int flags); - static int DoSpawn (int type, fixed_t x, fixed_t y, fixed_t z, int tid, int angle, bool force); + static int DoSpawn (int type, const DVector3 &pos, int tid, DAngle angle, bool force); + static int DoSpawn(int type, int x, int y, int z, int tid, int angle, bool force); static bool DoCheckActorTexture(int tid, AActor *activator, int string, bool floor); int DoSpawnSpot (int type, int spot, int tid, int angle, bool forced); int DoSpawnSpotFacing (int type, int spot, int tid, bool forced); int DoClassifyActor (int tid); int CallFunction(int argCount, int funcIndex, SDWORD *args); - void DoFadeTo (int r, int g, int b, int a, fixed_t time); + void DoFadeTo (int r, int g, int b, int a, int time); void DoFadeRange (int r1, int g1, int b1, int a1, - int r2, int g2, int b2, int a2, fixed_t time); + int r2, int g2, int b2, int a2, int time); void DoSetFont (int fontnum); void SetActorProperty (int tid, int property, int value); void DoSetActorProperty (AActor *actor, int property, int value); diff --git a/src/p_blockmap.h b/src/p_blockmap.h index 9cbe2e84b..b2cee1bdd 100644 --- a/src/p_blockmap.h +++ b/src/p_blockmap.h @@ -27,8 +27,18 @@ extern int* blockmaplump; // offsets in blockmap are from here extern int* blockmap; extern int bmapwidth; extern int bmapheight; // in mapblocks -extern fixed_t bmaporgx; -extern fixed_t bmaporgy; // origin of block map +extern double bmaporgx; +extern double bmaporgy; // origin of block map extern FBlockNode** blocklinks; // for thing chains +inline int GetBlockX(double xpos) +{ + return int((xpos - bmaporgx) / MAPBLOCKUNITS); +} + +inline int GetBlockY(double ypos) +{ + return int((ypos - bmaporgy) / MAPBLOCKUNITS); +} + #endif diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 3da00fbaf..f7adf2cdd 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -45,7 +45,7 @@ struct sectortype { SWORD wallptr, wallnum; - SDWORD ceilingz, floorz; + SDWORD ceilingZ, floorZ; SWORD ceilingstat, floorstat; SWORD ceilingpicnum, ceilingheinum; SBYTE ceilingshade; @@ -145,8 +145,8 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **sprites, int *nu static void LoadSectors (sectortype *bsectors); static void LoadWalls (walltype *walls, int numwalls, sectortype *bsectors); static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, sectortype *bsectors, FMapThing *mapthings); -static vertex_t *FindVertex (fixed_t x, fixed_t y); -static void CreateStartSpot (fixed_t *pos, FMapThing *start); +static vertex_t *FindVertex (SDWORD x, SDWORD y); +static void CreateStartSpot (SDWORD *pos, FMapThing *start); static void CalcPlane (SlopeWork &slope, secplane_t &plane); static void Decrypt (void *to, const void *from, int len, int key); @@ -232,7 +232,7 @@ bool P_LoadBuildMap (BYTE *data, size_t len, FMapThing **sprites, int *numspr) numsprites = *(WORD *)(data + 24 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype)); *sprites = new FMapThing[numsprites + 1]; - CreateStartSpot ((fixed_t *)(data + 4), *sprites); + CreateStartSpot ((SDWORD *)(data + 4), *sprites); *numspr = 1 + LoadSprites ((spritetype *)(data + 26 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype)), NULL, numsprites, (sectortype *)(data + 22), *sprites + 1); @@ -402,23 +402,21 @@ static void LoadSectors (sectortype *bsec) bsec->floorstat = WORD(bsec->floorstat); sec->e = §ors[0].e[i]; - sec->SetPlaneTexZ(sector_t::floor, -(LittleLong(bsec->floorz) << 8)); - sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor); - sec->floorplane.c = FRACUNIT; - sec->floorplane.ic = FRACUNIT; + double floorheight = -LittleLong(bsec->floorZ) / 256.; + sec->SetPlaneTexZ(sector_t::floor, floorheight); + sec->floorplane.SetAtHeight(floorheight, sector_t::floor); mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->floorpicnum)); sec->SetTexture(sector_t::floor, TexMan.GetTexture (tnam, FTexture::TEX_Build)); - sec->SetXScale(sector_t::floor, (bsec->floorstat & 8) ? FRACUNIT*2 : FRACUNIT); - sec->SetYScale(sector_t::floor, (bsec->floorstat & 8) ? FRACUNIT*2 : FRACUNIT); - sec->SetXOffset(sector_t::floor, (bsec->floorxpanning << FRACBITS) + (32 << FRACBITS)); - sec->SetYOffset(sector_t::floor, bsec->floorypanning << FRACBITS); + sec->SetXScale(sector_t::floor, (bsec->floorstat & 8) ? 2. : 1.); + sec->SetYScale(sector_t::floor, (bsec->floorstat & 8) ? 2. : 1.); + sec->SetXOffset(sector_t::floor, bsec->floorxpanning + 32.); + sec->SetYOffset(sector_t::floor, bsec->floorypanning + 0.); sec->SetPlaneLight(sector_t::floor, SHADE2LIGHT (bsec->floorshade)); sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING); - sec->SetPlaneTexZ(sector_t::ceiling, -(LittleLong(bsec->ceilingz) << 8)); - sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling); - sec->ceilingplane.c = -FRACUNIT; - sec->ceilingplane.ic = -FRACUNIT; + double ceilingheight = -LittleLong(bsec->ceilingZ) / 256.; + sec->SetPlaneTexZ(sector_t::ceiling, ceilingheight); + sec->ceilingplane.SetAtHeight(ceilingheight, sector_t::ceiling); mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->ceilingpicnum)); sec->SetTexture(sector_t::ceiling, TexMan.GetTexture (tnam, FTexture::TEX_Build)); if (bsec->ceilingstat & 1) @@ -426,10 +424,10 @@ static void LoadSectors (sectortype *bsec) sky1texture = sky2texture = sec->GetTexture(sector_t::ceiling); sec->SetTexture(sector_t::ceiling, skyflatnum); } - sec->SetXScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? FRACUNIT*2 : FRACUNIT); - sec->SetYScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? FRACUNIT*2 : FRACUNIT); - sec->SetXOffset(sector_t::ceiling, (bsec->ceilingxpanning << FRACBITS) + (32 << FRACBITS)); - sec->SetYOffset(sector_t::ceiling, bsec->ceilingypanning << FRACBITS); + sec->SetXScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? 2. : 1.); + sec->SetYScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? 2. : 1.); + sec->SetXOffset(sector_t::ceiling, bsec->ceilingxpanning + 32.); + sec->SetYOffset(sector_t::ceiling, bsec->ceilingypanning + 0.); sec->SetPlaneLight(sector_t::ceiling, SHADE2LIGHT (bsec->ceilingshade)); sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING); @@ -448,30 +446,30 @@ static void LoadSectors (sectortype *bsec) if (bsec->floorstat & 4) { - sec->SetAngle(sector_t::floor, ANGLE_90); - sec->SetXScale(sector_t::floor, -sec->GetXScale(sector_t::floor)); + sec->SetAngle(sector_t::floor, DAngle(90.)); + sec->SetXScale(sector_t::floor, -sec->GetXScaleF(sector_t::floor)); } if (bsec->floorstat & 16) { - sec->SetXScale(sector_t::floor, -sec->GetXScale(sector_t::floor)); + sec->SetXScale(sector_t::floor, -sec->GetXScaleF(sector_t::floor)); } if (bsec->floorstat & 32) { - sec->SetYScale(sector_t::floor, -sec->GetYScale(sector_t::floor)); + sec->SetYScale(sector_t::floor, -sec->GetYScaleF(sector_t::floor)); } if (bsec->ceilingstat & 4) { - sec->SetAngle(sector_t::ceiling, ANGLE_90); - sec->SetYScale(sector_t::ceiling, -sec->GetYScale(sector_t::ceiling)); + sec->SetAngle(sector_t::ceiling, DAngle(90.)); + sec->SetYScale(sector_t::ceiling, -sec->GetYScaleF(sector_t::ceiling)); } if (bsec->ceilingstat & 16) { - sec->SetXScale(sector_t::ceiling, -sec->GetXScale(sector_t::ceiling)); + sec->SetXScale(sector_t::ceiling, -sec->GetXScaleF(sector_t::ceiling)); } if (bsec->ceilingstat & 32) { - sec->SetYScale(sector_t::ceiling, -sec->GetYScale(sector_t::ceiling)); + sec->SetYScale(sector_t::ceiling, -sec->GetYScaleF(sector_t::ceiling)); } } } @@ -527,8 +525,8 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) walls[i].nextwall = LittleShort(walls[i].nextwall); walls[i].nextsector = LittleShort(walls[i].nextsector); - sides[i].SetTextureXOffset(walls[i].xpanning << FRACBITS); - sides[i].SetTextureYOffset(walls[i].ypanning << FRACBITS); + sides[i].SetTextureXOffset((double)walls[i].xpanning); + sides[i].SetTextureYOffset((double)walls[i].ypanning); sides[i].SetTexture(side_t::top, pic); sides[i].SetTexture(side_t::bottom, pic); @@ -546,8 +544,8 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) } sides[i].TexelLength = walls[i].xrepeat * 8; - sides[i].SetTextureYScale(walls[i].yrepeat << (FRACBITS - 3)); - sides[i].SetTextureXScale(FRACUNIT); + sides[i].SetTextureYScale(walls[i].yrepeat / 8.); + sides[i].SetTextureXScale(1.); sides[i].SetLight(SHADE2LIGHT(walls[i].shade)); sides[i].Flags = WALLF_ABSLIGHTING; sides[i].RightSide = walls[i].point2; @@ -595,11 +593,11 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) { if (walls[i].cstat & 512) { - lines[j].Alpha = FRACUNIT/3; + lines[j].Alpha = TRANSLUC33; } else { - lines[j].Alpha = FRACUNIT*2/3; + lines[j].Alpha = TRANSLUC66; } } if (walls[i].cstat & 1) @@ -639,7 +637,7 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) slope.wal2 = &walls[slope.wal->point2]; slope.dx = slope.wal2->x - slope.wal->x; slope.dy = slope.wal2->y - slope.wal->y; - slope.i = long (sqrt ((double)(slope.dx*slope.dx+slope.dy*slope.dy))) << 5; + slope.i = long (g_sqrt ((double)(slope.dx*slope.dx+slope.dy*slope.dy))) << 5; if (slope.i == 0) { continue; @@ -647,13 +645,13 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) if ((bsec->floorstat & 2) && (bsec->floorheinum != 0)) { // floor is sloped slope.heinum = -LittleShort(bsec->floorheinum); - slope.z[0] = slope.z[1] = slope.z[2] = -bsec->floorz; + slope.z[0] = slope.z[1] = slope.z[2] = -bsec->floorZ; CalcPlane (slope, sectors[i].floorplane); } if ((bsec->ceilingstat & 2) && (bsec->ceilingheinum != 0)) { // ceiling is sloped slope.heinum = -LittleShort(bsec->ceilingheinum); - slope.z[0] = slope.z[1] = slope.z[2] = -bsec->ceilingz; + slope.z[0] = slope.z[1] = slope.z[2] = -bsec->ceilingZ; CalcPlane (slope, sectors[i].ceilingplane); } int linenum = int(intptr_t(sides[bsec->wallptr].linedef)); @@ -697,17 +695,17 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, for (int i = 0; i < numsprites; ++i) { mapthings[count].thingid = 0; - mapthings[count].x = (sprites[i].x << 12); - mapthings[count].y = -(sprites[i].y << 12); - mapthings[count].z = (bsectors[sprites[i].sectnum].floorz - sprites[i].z) << 8; + mapthings[count].pos.X = sprites[i].x / 16.; + mapthings[count].pos.Y = -sprites[i].y / 16.; + mapthings[count].pos.Z = (bsectors[sprites[i].sectnum].floorZ - sprites[i].z) / 256.; mapthings[count].angle = (((2048-sprites[i].ang) & 2047) * 360) >> 11; mapthings[count].ClassFilter = 0xffff; mapthings[count].SkillFilter = 0xffff; mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH; mapthings[count].special = 0; - mapthings[count].gravity = FRACUNIT; + mapthings[count].Gravity = 1.; mapthings[count].RenderStyle = STYLE_Count; - mapthings[count].alpha = -1; + mapthings[count].Alpha = -1; mapthings[count].health = -1; mapthings[count].FloatbobPhase = -1; @@ -755,22 +753,21 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, // //========================================================================== -vertex_t *FindVertex (fixed_t x, fixed_t y) +vertex_t *FindVertex (SDWORD xx, SDWORD yy) { int i; - x <<= 12; - y = -(y << 12); + double x = xx / 64.; + double y = -yy / 64.; for (i = 0; i < numvertexes; ++i) { - if (vertexes[i].x == x && vertexes[i].y == y) + if (vertexes[i].fX() == x && vertexes[i].fY() == y) { return &vertexes[i]; } } - vertexes[i].x = x; - vertexes[i].y = y; + vertexes[i].set(x, y); numvertexes++; return &vertexes[i]; } @@ -781,13 +778,13 @@ vertex_t *FindVertex (fixed_t x, fixed_t y) // //========================================================================== -static void CreateStartSpot (fixed_t *pos, FMapThing *start) +static void CreateStartSpot (SDWORD *pos, FMapThing *start) { short angle = LittleShort(*(WORD *)(&pos[3])); FMapThing mt = { 0, }; - mt.x = LittleLong(pos[0])<<12; - mt.y = (-LittleLong(pos[1]))<<12; + mt.pos.X = LittleLong(pos[0]) / 16.; + mt.pos.Y = -LittleLong(pos[1]) / 16.; mt.angle = short(Scale((2048-angle)&2047, 360, 2048)); mt.info = DoomEdMap.CheckKey(1); mt.EdNum = 1; @@ -819,25 +816,20 @@ static void CalcPlane (SlopeWork &slope, secplane_t &plane) slope.x[2] = slope.x[0]; slope.y[2] = slope.y[0] + 64; } - j = DMulScale3 (slope.dx, slope.y[2]-slope.wal->y, - -slope.dy, slope.x[2]-slope.wal->x); + j = DMulScale3 (slope.dx, slope.y[2]-slope.wal->y, -slope.dy, slope.x[2]-slope.wal->x); slope.z[2] += Scale (slope.heinum, j, slope.i); pt[0] = DVector3(slope.dx, -slope.dy, 0); pt[1] = DVector3(slope.x[2] - slope.x[0], slope.y[0] - slope.y[2], (slope.z[2] - slope.z[0]) / 16); pt[2] = (pt[0] ^ pt[1]).Unit(); - if ((pt[2][2] < 0 && plane.c > 0) || (pt[2][2] > 0 && plane.c < 0)) + if ((pt[2][2] < 0 && plane.fC() > 0) || (pt[2][2] > 0 && plane.fC() < 0)) { pt[2] = -pt[2]; } - plane.a = FLOAT2FIXED(pt[2][0]); - plane.b = FLOAT2FIXED(pt[2][1]); - plane.c = FLOAT2FIXED(pt[2][2]); - plane.ic = DivScale32(1, plane.c); - plane.d = -TMulScale8 - (plane.a, slope.x[0]<<4, plane.b, (-slope.y[0])<<4, plane.c, slope.z[0]); + double dist = -pt[2][0] * slope.x[0] * 16 + pt[2][1] * slope.y[0] * 16 - pt[2][2] * slope.z[0]; + plane.set(pt[2][0], pt[2][1], pt[2][2], dist); } //========================================================================== @@ -883,14 +875,14 @@ void ACustomSprite::BeginPlay () mysnprintf (name, countof(name), "BTIL%04d", args[0] & 0xffff); picnum = TexMan.GetTexture (name, FTexture::TEX_Build); - scaleX = args[2] * (FRACUNIT/64); - scaleY = args[3] * (FRACUNIT/64); + Scale.X = args[2] / 64.; + Scale.Y = args[3] / 64.; int cstat = args[4]; if (cstat & 2) { RenderStyle = STYLE_Translucent; - alpha = (cstat & 512) ? TRANSLUC66 : TRANSLUC33; + Alpha = (cstat & 512) ? 0.6666 : 0.3333; } if (cstat & 4) renderflags |= RF_XFLIP; diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 95be8f7bc..00af933ef 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -205,7 +205,7 @@ void DCeiling::Tick () case ceilCrushAndRaise: case ceilLowerAndCrush: if (m_CrushMode == ECrushMode::crushSlowdown) - m_Speed = FRACUNIT / 8; + m_Speed = 1. / 8; break; default: @@ -228,7 +228,7 @@ DCeiling::DCeiling (sector_t *sec) { } -DCeiling::DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent) +DCeiling::DCeiling (sector_t *sec, double speed1, double speed2, int silent) : DMovingCeiling (sec) { m_Crush = -1; @@ -245,10 +245,10 @@ DCeiling::DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent) //============================================================================ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, int tag, - fixed_t speed, fixed_t speed2, fixed_t height, + double speed, double speed2, double height, int crush, int silent, int change, ECrushMode hexencrush) { - fixed_t targheight = 0; // Silence, GCC + double targheight = 0; // Silence, GCC // if ceiling already moving, don't start a second function on it if (sec->PlaneMoving(sector_t::ceiling)) @@ -264,7 +264,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, { case ceilCrushAndRaise: case ceilCrushRaiseAndStay: - ceiling->m_TopHeight = sec->ceilingplane.d; + ceiling->m_TopHeight = sec->ceilingplane.fD(); case ceilLowerAndCrush: targheight = sec->FindHighestFloorPoint (&spot); targheight += height; @@ -292,7 +292,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, case ceilMoveToValue: { - int diff = height - sec->ceilingplane.ZatPoint (spot); + double diff = height - sec->ceilingplane.ZatPoint (spot); targheight = height; if (diff < 0) @@ -400,15 +400,15 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, // Do not interpolate instant movement ceilings. // Note for ZDoomGL: Check to make sure that you update the sector // after the ceiling moves, because it hasn't actually moved yet. - fixed_t movedist; + double movedist; if (ceiling->m_Direction < 0) { - movedist = sec->ceilingplane.d - ceiling->m_BottomHeight; + movedist = sec->ceilingplane.fD() - ceiling->m_BottomHeight; } else { - movedist = ceiling->m_TopHeight - sec->ceilingplane.d; + movedist = ceiling->m_TopHeight - sec->ceilingplane.fD(); } if (ceiling->m_Speed >= movedist) { @@ -483,7 +483,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, //============================================================================ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, - int tag, fixed_t speed, fixed_t speed2, fixed_t height, + int tag, double speed, double speed2, double height, int crush, int silent, int change, DCeiling::ECrushMode hexencrush) { int secnum; diff --git a/src/p_checkposition.h b/src/p_checkposition.h index 4ab67634e..d0d4a3826 100644 --- a/src/p_checkposition.h +++ b/src/p_checkposition.h @@ -13,15 +13,13 @@ struct FCheckPosition { // in AActor *thing; - fixed_t x; - fixed_t y; - fixed_t z; + DVector3 pos; // out sector_t *sector; - fixed_t floorz; - fixed_t ceilingz; - fixed_t dropoffz; + double floorz; + double ceilingz; + double dropoffz; FTextureID floorpic; int floorterrain; sector_t *floorsector; diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 77de53345..e8aaa6912 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -989,10 +989,10 @@ public: mysnprintf (goldstr, countof(goldstr), "%d", coin != NULL ? coin->Amount : 0); screen->DrawText (SmallFont, CR_GRAY, 21, 191, goldstr, DTA_320x200, true, - DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE); + DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, TAG_DONE); screen->DrawTexture (TexMan(((AInventory *)GetDefaultByType (RUNTIME_CLASS(ACoin)))->Icon), 3, 190, DTA_320x200, true, - DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE); + DTA_FillColor, 0, DTA_AlphaF, HR_SHADOW, TAG_DONE); screen->DrawText (SmallFont, CR_GRAY, 20, 190, goldstr, DTA_320x200, true, TAG_DONE); screen->DrawTexture (TexMan(((AInventory *)GetDefaultByType (RUNTIME_CLASS(ACoin)))->Icon), 2, 189, DTA_320x200, true, TAG_DONE); @@ -1091,8 +1091,8 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang return; } - pc->vel.x = pc->vel.y = 0; // Stop moving - pc->player->vel.x = pc->player->vel.y = 0; + pc->Vel.Zero(); + pc->player->Vel.Zero(); static_cast(pc)->PlayIdle (); pc->player->ConversationPC = pc; @@ -1110,14 +1110,14 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang pc->player->ConversationFaceTalker = facetalker; if (saveangle) { - pc->player->ConversationNPCAngle = npc->angle; + pc->player->ConversationNPCAngle = npc->Angles.Yaw; } oldtarget = npc->target; npc->target = pc; if (facetalker) { A_FaceTarget (npc); - pc->angle = pc->AngleTo(npc); + pc->Angles.Yaw = pc->AngleTo(npc); } if ((npc->flags & MF_FRIENDLY) || (npc->flags4 & MF4_NOHATEPLAYERS)) { @@ -1227,7 +1227,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply if (reply == NULL) { // The default reply was selected - npc->angle = player->ConversationNPCAngle; + npc->Angles.Yaw = player->ConversationNPCAngle; npc->flags5 &= ~MF5_INCONVERSATION; return; } @@ -1243,7 +1243,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply TerminalResponse(reply->QuickNo); } npc->ConversationAnimation(2); - npc->angle = player->ConversationNPCAngle; + npc->Angles.Yaw = player->ConversationNPCAngle; npc->flags5 &= ~MF5_INCONVERSATION; return; } @@ -1268,7 +1268,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply if (takestuff) { - AInventory *item = static_cast(Spawn(reply->GiveType, 0, 0, 0, NO_REPLACE)); + AInventory *item = static_cast(Spawn(reply->GiveType)); // Items given here should not count as items! item->ClearCounters(); if (item->GetClass()->TypeName == NAME_FlameThrower) @@ -1371,7 +1371,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply } } - npc->angle = player->ConversationNPCAngle; + npc->Angles.Yaw = player->ConversationNPCAngle; // [CW] Set these to NULL because we're not using to them // anymore. However, this can interfere with slideshows @@ -1382,7 +1382,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply player->ConversationFaceTalker = false; player->ConversationNPC = NULL; player->ConversationPC = NULL; - player->ConversationNPCAngle = 0; + player->ConversationNPCAngle = 0.; } if (isconsole) @@ -1421,7 +1421,7 @@ void P_ConversationCommand (int netcode, int pnum, BYTE **stream) assert(netcode == DEM_CONVNULL || netcode == DEM_CONVCLOSE); if (player->ConversationNPC != NULL) { - player->ConversationNPC->angle = player->ConversationNPCAngle; + player->ConversationNPC->Angles.Yaw = player->ConversationNPCAngle; player->ConversationNPC->flags5 &= ~MF5_INCONVERSATION; } if (netcode == DEM_CONVNULL) @@ -1429,7 +1429,7 @@ void P_ConversationCommand (int netcode, int pnum, BYTE **stream) player->ConversationFaceTalker = false; player->ConversationNPC = NULL; player->ConversationPC = NULL; - player->ConversationNPCAngle = 0; + player->ConversationNPCAngle = 0.; } } } diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 3cf66119c..ba2fba399 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -82,14 +82,14 @@ void DDoor::Tick () { EResult res; - if (m_Sector->floorplane.d != m_OldFloorDist) + // Adjust bottom height - but only if there isn't an active lift attached to the floor. + if (m_Sector->floorplane.fD() != m_OldFloorDist) { if (!m_Sector->floordata || !m_Sector->floordata->IsKindOf(RUNTIME_CLASS(DPlat)) || !(barrier_cast(m_Sector->floordata))->IsLift()) { - m_OldFloorDist = m_Sector->floorplane.d; - m_BotDist = m_Sector->ceilingplane.PointToDist (m_BotSpot, - m_Sector->floorplane.ZatPoint (m_BotSpot)); + m_OldFloorDist = m_Sector->floorplane.fD(); + m_BotDist = m_Sector->ceilingplane.PointToDist (m_BotSpot, m_Sector->floorplane.ZatPoint (m_BotSpot)); } } @@ -140,10 +140,10 @@ void DDoor::Tick () res = MoveCeiling (m_Speed, m_BotDist, -1, m_Direction, false); // killough 10/98: implement gradual lighting effects - if (m_LightTag != 0 && m_TopDist != -m_Sector->floorplane.d) + if (m_LightTag != 0 && m_TopDist != -m_Sector->floorplane.fD()) { - EV_LightTurnOnPartway (m_LightTag, FixedDiv (m_Sector->ceilingplane.d + m_Sector->floorplane.d, - m_TopDist + m_Sector->floorplane.d)); + EV_LightTurnOnPartway (m_LightTag, + (m_Sector->ceilingplane.fD() + m_Sector->floorplane.fD()) / (m_TopDist + m_Sector->floorplane.fD())); } if (res == pastdest) @@ -186,10 +186,10 @@ void DDoor::Tick () res = MoveCeiling (m_Speed, m_TopDist, -1, m_Direction, false); // killough 10/98: implement gradual lighting effects - if (m_LightTag != 0 && m_TopDist != -m_Sector->floorplane.d) + if (m_LightTag != 0 && m_TopDist != -m_Sector->floorplane.fD()) { - EV_LightTurnOnPartway (m_LightTag, FixedDiv (m_Sector->ceilingplane.d + m_Sector->floorplane.d, - m_TopDist + m_Sector->floorplane.d)); + EV_LightTurnOnPartway (m_LightTag, + (m_Sector->ceilingplane.fD() + m_Sector->floorplane.fD()) / (m_TopDist + m_Sector->floorplane.fD())); } if (res == pastdest) @@ -254,7 +254,7 @@ void DDoor::DoorSound(bool raise, DSeqNode *curseq) const if (m_Sector->Flags & SECF_SILENTMOVE) return; - if (m_Speed >= FRACUNIT*8) + if (m_Speed >= 8) { choice += 2; } @@ -350,12 +350,12 @@ DDoor::DDoor (sector_t *sector) // //============================================================================ -DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTag, int topcountdown) +DDoor::DDoor (sector_t *sec, EVlDoor type, double speed, int delay, int lightTag, int topcountdown) : DMovingCeiling (sec), m_Type (type), m_Speed (speed), m_TopWait (delay), m_TopCountdown(topcountdown), m_LightTag (lightTag) { vertex_t *spot; - fixed_t height; + double height; if (i_compatflags & COMPATF_NODOORLIGHT) { @@ -367,7 +367,7 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa case doorClose: m_Direction = -1; height = sec->FindLowestCeilingSurrounding (&spot); - m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4*FRACUNIT); + m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4); DoorSound (false); break; @@ -375,13 +375,13 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa case doorRaise: m_Direction = 1; height = sec->FindLowestCeilingSurrounding (&spot); - m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4*FRACUNIT); - if (m_TopDist != sec->ceilingplane.d) + m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4); + if (m_TopDist != sec->ceilingplane.fD()) DoorSound (true); break; case doorCloseWaitOpen: - m_TopDist = sec->ceilingplane.d; + m_TopDist = sec->ceilingplane.fD(); m_Direction = -1; DoorSound (false); break; @@ -389,7 +389,7 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa case doorWaitRaise: m_Direction = 2; height = sec->FindLowestCeilingSurrounding (&spot); - m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4*FRACUNIT); + m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4); break; case doorWaitClose: @@ -397,8 +397,8 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa m_Type = DDoor::doorRaise; height = sec->FindHighestFloorPoint (&m_BotSpot); m_BotDist = sec->ceilingplane.PointToDist (m_BotSpot, height); - m_OldFloorDist = sec->floorplane.d; - m_TopDist = sec->ceilingplane.d; + m_OldFloorDist = sec->floorplane.fD(); + m_TopDist = sec->ceilingplane.fD(); break; } @@ -414,7 +414,7 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa height = sec->FindLowestCeilingPoint(&m_BotSpot); m_BotDist = sec->ceilingplane.PointToDist (m_BotSpot, height); } - m_OldFloorDist = sec->floorplane.d; + m_OldFloorDist = sec->floorplane.fD(); } //============================================================================ @@ -425,7 +425,7 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa //============================================================================ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, - int tag, int speed, int delay, int lock, int lightTag, bool boomgen, int topcountdown) + int tag, double speed, int delay, int lock, int lightTag, bool boomgen, int topcountdown) { bool rtn = false; int secnum; @@ -559,13 +559,13 @@ bool DAnimatedDoor::StartClosing () return false; } - fixed_t topdist = m_Sector->ceilingplane.d; - if (MoveCeiling (2048*FRACUNIT, m_BotDist, 0, -1, false) == crushed) + double topdist = m_Sector->ceilingplane.fD(); + if (MoveCeiling (2048., m_BotDist, 0, -1, false) == crushed) { return false; } - MoveCeiling (2048*FRACUNIT, topdist, 1); + MoveCeiling (2048., topdist, 1); m_Line1->flags |= ML_BLOCKING; m_Line2->flags |= ML_BLOCKING; @@ -650,7 +650,7 @@ void DAnimatedDoor::Tick () if (--m_Frame < 0) { // IF DOOR IS DONE CLOSING... - MoveCeiling (2048*FRACUNIT, m_BotDist, -1); + MoveCeiling (2048., m_BotDist, -1); m_Sector->ceilingdata = NULL; Destroy (); // Unset blocking flags on lines that didn't start with them. Since the @@ -690,7 +690,7 @@ void DAnimatedDoor::Tick () DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim) : DMovingCeiling (sec) { - fixed_t topdist; + double topdist; FTextureID picnum; // The DMovingCeiling constructor automatically sets up an interpolation for us. @@ -722,7 +722,7 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FTexture *tex = TexMan[picnum]; topdist = tex ? tex->GetScaledHeight() : 64; - topdist = m_Sector->ceilingplane.d - topdist * m_Sector->ceilingplane.c; + topdist = m_Sector->ceilingplane.fD() - topdist * m_Sector->ceilingplane.fC(); m_Status = Opening; m_Speed = speed; @@ -733,8 +733,8 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, m_SetBlocking2 = !!(m_Line2->flags & ML_BLOCKING); m_Line1->flags |= ML_BLOCKING; m_Line2->flags |= ML_BLOCKING; - m_BotDist = m_Sector->ceilingplane.d; - MoveCeiling (2048*FRACUNIT, topdist, 1); + m_BotDist = m_Sector->ceilingplane.fD(); + MoveCeiling (2048., topdist, 1); if (m_DoorAnim->OpenSound != NAME_None) { SN_StartSequence (m_Sector, CHAN_INTERIOR, m_DoorAnim->OpenSound, 1); diff --git a/src/p_effect.cpp b/src/p_effect.cpp index bf1490825..249ba80f9 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -149,15 +149,16 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE ) void P_InitParticles () { const char *i; + int num; if ((i = Args->CheckValue ("-numparticles"))) - NumParticles = atoi (i); + num = atoi (i); // [BC] Use r_maxparticles now. else - NumParticles = r_maxparticles; + num = r_maxparticles; // This should be good, but eh... - NumParticles = clamp(NumParticles, 100, 65535); + NumParticles = (WORD)clamp(num, 100, 65535); P_DeinitParticles(); Particles = new particle_t[NumParticles]; @@ -206,7 +207,7 @@ void P_FindParticleSubsectors () for (WORD i = ActiveParticles; i != NO_PARTICLE; i = Particles[i].tnext) { // Try to reuse the subsector from the last portal check, if still valid. - if (Particles[i].subsector == NULL) Particles[i].subsector = R_PointInSubsector(Particles[i].x, Particles[i].y); + if (Particles[i].subsector == NULL) Particles[i].subsector = R_PointInSubsector(Particles[i].Pos); int ssnum = int(Particles[i].subsector - subsectors); Particles[i].snext = ParticlesInSubsec[ssnum]; ParticlesInSubsec[ssnum] = i; @@ -279,33 +280,29 @@ void P_ThinkParticles () continue; } - fixedvec2 newxy = P_GetOffsetPosition(particle->x, particle->y, particle->vel.x, particle->vel.y); - particle->x = newxy.x; - particle->y = newxy.y; - //particle->x += particle->vel.x; - //particle->y += particle->vel.y; - particle->z += particle->vel.z; - particle->vel.x += particle->accx; - particle->vel.y += particle->accy; - particle->vel.z += particle->accz; - particle->subsector = R_PointInSubsector(particle->x, particle->y); + // Handle crossing a line portal + DVector2 newxy = P_GetOffsetPosition(particle->Pos.X, particle->Pos.Y, particle->Vel.X, particle->Vel.Y); + particle->Pos.X = newxy.X; + particle->Pos.Y = newxy.Y; + particle->Pos.Z += particle->Vel.Z; + particle->Vel += particle->Acc; + particle->subsector = R_PointInSubsector(particle->Pos); + // Handle crossing a sector portal. if (!particle->subsector->sector->PortalBlocksMovement(sector_t::ceiling)) { AActor *skybox = particle->subsector->sector->SkyBoxes[sector_t::ceiling]; - if (particle->z > skybox->threshold) + if (particle->Pos.Z > skybox->specialf1) { - particle->x += skybox->scaleX; - particle->y += skybox->scaleY; + particle->Pos += skybox->Scale; particle->subsector = NULL; } } else if (!particle->subsector->sector->PortalBlocksMovement(sector_t::floor)) { AActor *skybox = particle->subsector->sector->SkyBoxes[sector_t::floor]; - if (particle->z < skybox->threshold) + if (particle->Pos.Z < skybox->specialf1) { - particle->x += skybox->scaleX; - particle->y += skybox->scaleY; + particle->Pos += skybox->Scale; particle->subsector = NULL; } } @@ -313,28 +310,23 @@ void P_ThinkParticles () } } -void P_SpawnParticle(fixed_t x, fixed_t y, fixed_t z, fixed_t vx, fixed_t vy, fixed_t vz, PalEntry color, bool fullbright, BYTE startalpha, BYTE lifetime, WORD size, int fadestep, fixed_t accelx, fixed_t accely, fixed_t accelz) + +void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, bool fullbright, double startalpha, int lifetime, WORD size, double fadestep) { particle_t *particle = NewParticle(); if (particle) { - particle->x = x; - particle->y = y; - particle->z = z; - particle->vel.x = vx; - particle->vel.y = vy; - particle->vel.z = vz; + particle->Pos = pos; + particle->Vel = vel; + particle->Acc = accel; particle->color = ParticleColor(color); - particle->trans = startalpha; - if (fadestep < 0) fadestep = FADEFROMTTL(lifetime); - particle->fade = fadestep; + particle->trans = BYTE(startalpha*255); + if (fadestep < 0) particle->fade = FADEFROMTTL(lifetime); + else particle->fade = int(fadestep * 255); particle->ttl = lifetime; - particle->accx = accelx; - particle->accy = accely; - particle->accz = accelz; particle->bright = fullbright; - particle->size = size; + particle->size = (WORD)size; } } @@ -379,15 +371,14 @@ particle_t *JitterParticle (int ttl, double drift) particle_t *particle = NewParticle (); if (particle) { - fixed_t *val = &particle->vel.x; int i; // Set initial velocities - for (i = 3; i; i--, val++) - *val = (int)((FRACUNIT/4096) * (M_Random () - 128) * drift); + for (i = 3; i; i--) + particle->Vel[i] = ((1./4096) * (M_Random () - 128) * drift); // Set initial accelerations - for (i = 3; i; i--, val++) - *val = (int)((FRACUNIT/16384) * (M_Random () - 128) * drift); + for (i = 3; i; i--) + particle->Acc[i] = ((1./16384) * (M_Random () - 128) * drift); particle->trans = 255; // fully opaque particle->ttl = ttl; @@ -407,18 +398,15 @@ static void MakeFountain (AActor *actor, int color1, int color2) if (particle) { - angle_t an = M_Random()<<(24-ANGLETOFINESHIFT); - fixed_t out = FixedMul (actor->radius, M_Random()<<8); + DAngle an = M_Random() * (360. / 256); + double out = actor->radius * M_Random() / 256.; - fixedvec3 pos = actor->Vec3Offset(FixedMul(out, finecosine[an]), FixedMul(out, finesine[an]), actor->height + FRACUNIT); - particle->x = pos.x; - particle->y = pos.y; - particle->z = pos.z; + particle->Pos = actor->Vec3Angle(out, an, actor->Height + 1); if (out < actor->radius/8) - particle->vel.z += FRACUNIT*10/3; + particle->Vel.Z += 10./3; else - particle->vel.z += FRACUNIT*3; - particle->accz -= FRACUNIT/11; + particle->Vel.Z += 3; + particle->Acc.Z -= 1./11; if (M_Random() < 30) { particle->size = 4; particle->color = color2; @@ -431,17 +419,7 @@ static void MakeFountain (AActor *actor, int color1, int color2) void P_RunEffect (AActor *actor, int effects) { - angle_t moveangle; - - // 512 is the limit below which R_PointToAngle2 does no longer returns usable values. - if (abs(actor->vel.x) > 512 || abs(actor->vel.y) > 512) - { - moveangle = R_PointToAngle2(0,0,actor->vel.x,actor->vel.y); - } - else - { - moveangle = actor->angle; - } + DAngle moveangle = actor->Vel.Angle(); particle_t *particle; int i; @@ -449,49 +427,44 @@ void P_RunEffect (AActor *actor, int effects) if ((effects & FX_ROCKET) && (cl_rockettrails & 1)) { // Rocket trail + double backx = -actor->radius * 2 * moveangle.Cos(); + double backy = -actor->radius * 2 * moveangle.Sin(); + double backz = actor->Height * ((2. / 3) - actor->Vel.Z / 8); - - fixed_t backx = - FixedMul (finecosine[(moveangle)>>ANGLETOFINESHIFT], actor->radius*2); - fixed_t backy = - FixedMul (finesine[(moveangle)>>ANGLETOFINESHIFT], actor->radius*2); - fixed_t backz = - (actor->height>>3) * (actor->vel.z>>16) + (2*actor->height)/3; - - angle_t an = (moveangle + ANG90) >> ANGLETOFINESHIFT; - int speed; + DAngle an = moveangle + 90.; + double speed; particle = JitterParticle (3 + (M_Random() & 31)); if (particle) { - fixed_t pathdist = M_Random()<<8; - fixedvec3 pos = actor->Vec3Offset( - backx - FixedMul(actor->vel.x, pathdist), - backy - FixedMul(actor->vel.y, pathdist), - backz - FixedMul(actor->vel.z, pathdist)); - particle->x = pos.x; - particle->y = pos.y; - particle->z = pos.z; - speed = (M_Random () - 128) * (FRACUNIT/200); - particle->vel.x += FixedMul (speed, finecosine[an]); - particle->vel.y += FixedMul (speed, finesine[an]); - particle->vel.z -= FRACUNIT/36; - particle->accz -= FRACUNIT/20; + double pathdist = M_Random() / 256.; + DVector3 pos = actor->Vec3Offset( + backx - actor->Vel.X * pathdist, + backy - actor->Vel.Y * pathdist, + backz - actor->Vel.Z * pathdist); + particle->Pos = pos; + speed = (M_Random () - 128) * (1./200); + particle->Vel.X += speed * an.Cos(); + particle->Vel.Y += speed * an.Sin(); + particle->Vel.Z -= 1./36; + particle->Acc.Z -= 1./20; particle->color = yellow; particle->size = 2; } for (i = 6; i; i--) { particle_t *particle = JitterParticle (3 + (M_Random() & 31)); if (particle) { - fixed_t pathdist = M_Random()<<8; - fixedvec3 pos = actor->Vec3Offset( - backx - FixedMul(actor->vel.x, pathdist), - backy - FixedMul(actor->vel.y, pathdist), - backz - FixedMul(actor->vel.z, pathdist) + (M_Random() << 10)); - particle->x = pos.x; - particle->y = pos.y; - particle->z = pos.z; - speed = (M_Random () - 128) * (FRACUNIT/200); - particle->vel.x += FixedMul (speed, finecosine[an]); - particle->vel.y += FixedMul (speed, finesine[an]); - particle->vel.z += FRACUNIT/80; - particle->accz += FRACUNIT/40; + double pathdist = M_Random() / 256.; + DVector3 pos = actor->Vec3Offset( + backx - actor->Vel.X * pathdist, + backy - actor->Vel.Y * pathdist, + backz - actor->Vel.Z * pathdist + (M_Random() / 64.)); + particle->Pos = pos; + + speed = (M_Random () - 128) * (1./200); + particle->Vel.X += speed * an.Cos(); + particle->Vel.Y += speed * an.Sin(); + particle->Vel.Z -= 1. / 80; + particle->Acc.Z -= 1. / 40; if (M_Random () & 7) particle->color = grey2; else @@ -505,11 +478,9 @@ void P_RunEffect (AActor *actor, int effects) { // Grenade trail - fixedvec3 pos = actor->Vec3Angle(-actor->radius * 2, moveangle, - -(actor->height >> 3) * (actor->vel.z >> 16) + (2 * actor->height) / 3); + DVector3 pos = actor->Vec3Angle(-actor->radius * 2, moveangle, -actor->Height * actor->Vel.Z / 8 + actor->Height * (2. / 3)); - P_DrawSplash2 (6, pos.x, pos.y, pos.z, - moveangle + ANG180, 2, 2); + P_DrawSplash2 (6, pos, moveangle + 180, 2, 2); } if (effects & FX_FOUNTAINMASK) { @@ -539,27 +510,25 @@ void P_RunEffect (AActor *actor, int effects) particle = JitterParticle (16); if (particle != NULL) { - angle_t ang = M_Random () << (32-ANGLETOFINESHIFT-8); - fixedvec3 pos = actor->Vec3Offset(FixedMul (actor->radius, finecosine[ang]), FixedMul (actor->radius, finesine[ang]), 0); - particle->x = pos.x; - particle->y = pos.y; - particle->z = pos.z; + DAngle ang = M_Random() * (360 / 256.); + DVector3 pos = actor->Vec3Angle(actor->radius, ang, 0); + particle->Pos = pos; particle->color = *protectColors[M_Random() & 1]; - particle->vel.z = FRACUNIT; - particle->accz = M_Random () << 7; + particle->Vel.Z = 1; + particle->Acc.Z = M_Random () / 512.; particle->size = 1; if (M_Random () < 128) { // make particle fall from top of actor - particle->z += actor->height; - particle->vel.z = -particle->vel.z; - particle->accz = -particle->accz; + particle->Pos.Z += actor->Height; + particle->Vel.Z = -particle->Vel.Z; + particle->Acc.Z = -particle->Acc.Z; } } } } } -void P_DrawSplash (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int kind) +void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind) { int color1, color2; @@ -576,27 +545,27 @@ void P_DrawSplash (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, in for (; count; count--) { particle_t *p = JitterParticle (10); - angle_t an; if (!p) break; p->size = 2; p->color = M_Random() & 0x80 ? color1 : color2; - p->vel.z -= M_Random () * 512; - p->accz -= FRACUNIT/8; - p->accx += (M_Random () - 128) * 8; - p->accy += (M_Random () - 128) * 8; - p->z = z - M_Random () * 1024; - an = (angle + (M_Random() << 21)) >> ANGLETOFINESHIFT; - p->x = x + (M_Random () & 15)*finecosine[an]; - p->y = y + (M_Random () & 15)*finesine[an]; + p->Vel.Z -= M_Random () / 128.; + p->Acc.Z -= 1./8; + p->Acc.X += (M_Random () - 128) / 8192.; + p->Acc.Y += (M_Random () - 128) / 8192.; + p->Pos.Z = pos.Z - M_Random () / 64.; + angle += M_Random() * (45./256); + p->Pos.X = pos.X + (M_Random() & 15)*angle.Cos(); + p->Pos.Y = pos.Y + (M_Random() & 15)*angle.Sin(); } } -void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int updown, int kind) +void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, int kind) { - int color1, color2, zvel, zspread, zadd; + int color1, color2, zadd; + double zvel, zspread; switch (kind) { @@ -618,14 +587,14 @@ void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, i break; } - zvel = -128; - zspread = updown ? -6000 : 6000; - zadd = (updown == 2) ? -128 : 0; + zvel = -0.5; + zspread = updown ? -6000 / 65536. : 6000 / 65536.; + zadd = (updown == 2) ? 128 : 0; for (; count; count--) { particle_t *p = NewParticle (); - angle_t an; + DAngle an; if (!p) break; @@ -635,23 +604,24 @@ void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, i p->trans = 255; p->size = 4; p->color = M_Random() & 0x80 ? color1 : color2; - p->vel.z = M_Random () * zvel; - p->accz = -FRACUNIT/22; - if (kind) { - an = (angle + ((M_Random() - 128) << 23)) >> ANGLETOFINESHIFT; - p->vel.x = (M_Random () * finecosine[an]) >> 11; - p->vel.y = (M_Random () * finesine[an]) >> 11; - p->accx = p->vel.x >> 4; - p->accy = p->vel.y >> 4; + p->Vel.Z = M_Random() * zvel; + p->Acc.Z = -1 / 22.; + if (kind) + { + an = angle + ((M_Random() - 128) * (180 / 256.)); + p->Vel.X = M_Random() * an.Cos() / 2048.; + p->Vel.Y = M_Random() * an.Sin() / 2048.; + p->Acc.X = p->Vel.X / 16.; + p->Acc.Y = p->Vel.Y / 16.; } - p->z = z + (M_Random () + zadd - 128) * zspread; - an = (angle + ((M_Random() - 128) << 22)) >> ANGLETOFINESHIFT; - p->x = x + ((M_Random () & 31)-15)*finecosine[an]; - p->y = y + ((M_Random () & 31)-15)*finesine[an]; + an = angle + ((M_Random() - 128) * (90 / 256.)); + p->Pos.X = pos.X + ((M_Random() & 31) - 15) * an.Cos(); + p->Pos.Y = pos.Y + ((M_Random() & 31) - 15) * an.Sin(); + p->Pos.Z = pos.Z + (M_Random() + zadd - 128) * zspread; } } -void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, int color1, int color2, double maxdiff_d, int flags, PClassActor *spawnclass, angle_t angle, int duration, double sparsity, double drift, int SpiralOffset) +void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, int color1, int color2, double maxdiff_d, int flags, PClassActor *spawnclass, DAngle angle, int duration, double sparsity, double drift, int SpiralOffset) { double length, lengthsquared; int steps, i; @@ -660,9 +630,10 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, bool fullbright; float maxdiff = (float)maxdiff_d; + dir = end - start; lengthsquared = dir | dir; - length = sqrt(lengthsquared); + length = g_sqrt(lengthsquared); steps = xs_FloorToInt(length / 3); fullbright = !!(flags & RAF_FULLBRIGHT); @@ -685,8 +656,8 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, double r; double dirz; - if (abs(mo->X() - FLOAT2FIXED(start.X)) < 20 * FRACUNIT - && (mo->Y() - FLOAT2FIXED(start.Y)) < 20 * FRACUNIT) + if (fabs(mo->X() - start.X) < 20 + && fabs(mo->Y() - start.Y) < 20) { // This player (probably) fired the railgun S_Sound (mo, CHAN_WEAPON, sound, 1, ATTN_NORM); } @@ -696,7 +667,7 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, // Only consider sound in 2D (for now, anyway) // [BB] You have to divide by lengthsquared here, not multiply with it. - r = ((start.Y - FIXED2DBL(mo->Y())) * (-dir.Y) - (start.X - FIXED2DBL(mo->X())) * (dir.X)) / lengthsquared; + r = ((start.Y - mo->Y()) * (-dir.Y) - (start.X - mo->X()) * (dir.X)) / lengthsquared; r = clamp(r, 0., 1.); dirz = dir.Z; @@ -704,8 +675,7 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, point = start + r * dir; dir.Z = dirz; - S_Sound (FLOAT2FIXED(point.X), FLOAT2FIXED(point.Y), viewz, - CHAN_WEAPON, sound, 1, ATTN_NORM); + S_Sound (DVector3(point.X, point.Y, ViewPos.Z), CHAN_WEAPON, sound, 1, ATTN_NORM); } } } @@ -744,7 +714,7 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, color1 = color1 == 0 ? -1 : ParticleColor(color1); pos = start; - deg = TAngle(SpiralOffset); + deg = (double)SpiralOffset; for (i = spiral_steps; i; i--) { particle_t *p = NewParticle (); @@ -762,15 +732,10 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, p->bright = fullbright; tempvec = DMatrix3x3(dir, deg) * extend; - p->vel.x = FLOAT2FIXED(tempvec.X * drift)>>4; - p->vel.y = FLOAT2FIXED(tempvec.Y * drift)>>4; - p->vel.z = FLOAT2FIXED(tempvec.Z * drift)>>4; - tempvec += pos; - p->x = FLOAT2FIXED(tempvec.X); - p->y = FLOAT2FIXED(tempvec.Y); - p->z = FLOAT2FIXED(tempvec.Z); + p->Vel = tempvec * drift / 16.; + p->Pos = tempvec + pos; pos += spiral_step; - deg += TAngle(r_rail_spiralsparsity * 14); + deg += double(r_rail_spiralsparsity * 14); if (color1 == -1) { @@ -825,11 +790,9 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, DVector3 postmp = pos + diff; p->size = 2; - p->x = FLOAT2FIXED(postmp.X); - p->y = FLOAT2FIXED(postmp.Y); - p->z = FLOAT2FIXED(postmp.Z); + p->Pos = postmp; if (color1 != -1) - p->accz -= FRACUNIT/4096; + p->Acc.Z -= 1./4096; pos += trail_step; p->bright = fullbright; @@ -874,11 +837,9 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, if (rnd & 4) diff.Z = clamp(diff.Z + ((rnd & 32) ? 1 : -1), -maxdiff, maxdiff); } - DVector3 postmp = pos + diff; - - AActor *thing = Spawn (spawnclass, FLOAT2FIXED(postmp.X), FLOAT2FIXED(postmp.Y), FLOAT2FIXED(postmp.Z), ALLOW_REPLACE); + AActor *thing = Spawn (spawnclass, pos + diff, ALLOW_REPLACE); if (thing) - thing->angle = angle; + thing->Angles.Yaw = angle; pos += trail_step; } } @@ -898,15 +859,13 @@ void P_DisconnectEffect (AActor *actor) if (!p) break; - - fixed_t xo = ((M_Random() - 128) << 9) * (actor->radius >> FRACBITS); - fixed_t yo = ((M_Random() - 128) << 9) * (actor->radius >> FRACBITS); - fixed_t zo = (M_Random() << 8) * (actor->height >> FRACBITS); - fixedvec3 pos = actor->Vec3Offset(xo, yo, zo); - p->x = pos.x; - p->y = pos.y; - p->z = pos.z; - p->accz -= FRACUNIT/4096; + double xo = (M_Random() - 128)*actor->radius / 128; + double yo = (M_Random() - 128)*actor->radius / 128; + double zo = M_Random()*actor->Height / 256; + + DVector3 pos = actor->Vec3Offset(xo, yo, zo); + p->Pos = pos; + p->Acc.Z -= 1./4096; p->color = M_Random() < 128 ? maroon1 : maroon2; p->size = 4; } diff --git a/src/p_effect.h b/src/p_effect.h index 3990fa80c..fad9012d0 100644 --- a/src/p_effect.h +++ b/src/p_effect.h @@ -52,15 +52,16 @@ struct subsector_t; // [RH] Particle details + struct particle_t { - fixed_t x,y,z; - fixedvec3 vel; - fixed_t accx,accy,accz; + DVector3 Pos; + DVector3 Vel; + DVector3 Acc; BYTE ttl; BYTE trans; WORD size; - BYTE bright:1; + BYTE bright; BYTE fade; int color; WORD tnext; @@ -83,13 +84,13 @@ particle_t *JitterParticle (int ttl); particle_t *JitterParticle (int ttl, double drift); void P_ThinkParticles (void); -void P_SpawnParticle(fixed_t x, fixed_t y, fixed_t z, fixed_t vx, fixed_t vy, fixed_t vz, PalEntry color, bool fullbright, BYTE startalpha, BYTE lifetime, WORD size, int fadestep, fixed_t accelx, fixed_t accely, fixed_t accelz); +void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, bool fullbright, double startalpha, int lifetime, WORD size, double fadestep); void P_InitEffects (void); void P_RunEffects (void); void P_RunEffect (AActor *actor, int effects); -void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, int color1, int color2, double maxdiff = 0, int flags = 0, PClassActor *spawnclass = NULL, angle_t angle = 0, int duration = 35, double sparsity = 1.0, double drift = 1.0, int SpiralOffset = 270); -void P_DrawSplash (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int kind); -void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int updown, int kind); +void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, int color1, int color2, double maxdiff = 0, int flags = 0, PClassActor *spawnclass = NULL, DAngle angle = 0., int duration = 35, double sparsity = 1.0, double drift = 1.0, int SpiralOffset = 270); +void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind); +void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, int kind); void P_DisconnectEffect (AActor *actor); diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index addaf12ea..19b916956 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -52,6 +52,7 @@ #include "teaminfo.h" #include "p_spec.h" #include "p_checkposition.h" +#include "math/cmath.h" #include "gi.h" @@ -98,8 +99,9 @@ dirtype_t diags[4] = DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST }; -fixed_t xspeed[8] = {FRACUNIT,46341,0,-46341,-FRACUNIT,-46341,0,46341}; -fixed_t yspeed[8] = {0,46341,FRACUNIT,46341,0,-46341,-FRACUNIT,-46341}; +#define SQRTHALF 0.7071075439453125 +double xspeed[8] = {1,SQRTHALF,0,-SQRTHALF,-1,-SQRTHALF,0,SQRTHALF}; +double yspeed[8] = {0,SQRTHALF,1,SQRTHALF,0,-SQRTHALF,-1,-SQRTHALF}; void P_RandomChaseDir (AActor *actor); @@ -122,7 +124,7 @@ void P_RandomChaseDir (AActor *actor); // sound blocking lines cut off traversal. //---------------------------------------------------------------------------- -void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soundblocks, AActor *emitter, fixed_t maxdist) +void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soundblocks, AActor *emitter, double maxdist) { int i; line_t* check; @@ -144,7 +146,7 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun for (actor = sec->thinglist; actor != NULL; actor = actor->snext) { if (actor != soundtarget && (!splash || !(actor->flags4 & MF4_NOSPLASHALERT)) && - (!maxdist || (actor->AproxDistance(emitter) <= maxdist))) + (!maxdist || (actor->Distance2D(emitter) <= maxdist))) { actor->LastHeard = soundtarget; } @@ -160,18 +162,12 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun // I wish there was a better method to do this than randomly looking through the portal at a few places... if (checkabove) { - sector_t *upper = - P_PointInSector(check->v1->x + check->dx / 2 + sec->SkyBoxes[sector_t::ceiling]->scaleX, - check->v1->y + check->dy / 2 + sec->SkyBoxes[sector_t::ceiling]->scaleY); - + sector_t *upper = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->SkyBoxes[sector_t::ceiling]->Scale); P_RecursiveSound(upper, soundtarget, splash, soundblocks, emitter, maxdist); } if (checkbelow) { - sector_t *lower = - P_PointInSector(check->v1->x + check->dx / 2 + sec->SkyBoxes[sector_t::floor]->scaleX, - check->v1->y + check->dy / 2 + sec->SkyBoxes[sector_t::floor]->scaleY); - + sector_t *lower = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->SkyBoxes[sector_t::floor]->Scale); P_RecursiveSound(lower, soundtarget, splash, soundblocks, emitter, maxdist); } FLinePortal *port = check->getPortal(); @@ -199,18 +195,18 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun other = check->sidedef[0]->sector; // check for closed door - if ((sec->floorplane.ZatPoint (check->v1->x, check->v1->y) >= - other->ceilingplane.ZatPoint (check->v1->x, check->v1->y) && - sec->floorplane.ZatPoint (check->v2->x, check->v2->y) >= - other->ceilingplane.ZatPoint (check->v2->x, check->v2->y)) - || (other->floorplane.ZatPoint (check->v1->x, check->v1->y) >= - sec->ceilingplane.ZatPoint (check->v1->x, check->v1->y) && - other->floorplane.ZatPoint (check->v2->x, check->v2->y) >= - sec->ceilingplane.ZatPoint (check->v2->x, check->v2->y)) - || (other->floorplane.ZatPoint (check->v1->x, check->v1->y) >= - other->ceilingplane.ZatPoint (check->v1->x, check->v1->y) && - other->floorplane.ZatPoint (check->v2->x, check->v2->y) >= - other->ceilingplane.ZatPoint (check->v2->x, check->v2->y))) + if ((sec->floorplane.ZatPoint (check->v1->fPos()) >= + other->ceilingplane.ZatPoint (check->v1->fPos()) && + sec->floorplane.ZatPoint (check->v2->fPos()) >= + other->ceilingplane.ZatPoint (check->v2->fPos())) + || (other->floorplane.ZatPoint (check->v1->fPos()) >= + sec->ceilingplane.ZatPoint (check->v1->fPos()) && + other->floorplane.ZatPoint (check->v2->fPos()) >= + sec->ceilingplane.ZatPoint (check->v2->fPos())) + || (other->floorplane.ZatPoint (check->v1->fPos()) >= + other->ceilingplane.ZatPoint (check->v1->fPos()) && + other->floorplane.ZatPoint (check->v2->fPos()) >= + other->ceilingplane.ZatPoint (check->v2->fPos()))) { continue; } @@ -238,7 +234,7 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun // //---------------------------------------------------------------------------- -void P_NoiseAlert (AActor *target, AActor *emitter, bool splash, fixed_t maxdist) +void P_NoiseAlert (AActor *target, AActor *emitter, bool splash, double maxdist) { if (emitter == NULL) return; @@ -263,12 +259,12 @@ bool AActor::CheckMeleeRange () { AActor *pl = target; - fixed_t dist; + double dist; if (!pl) return false; - dist = AproxDistance (pl); + dist = Distance2D (pl); if (dist >= meleerange + pl->radius) return false; @@ -305,15 +301,16 @@ bool AActor::CheckMeleeRange () bool P_CheckMeleeRange2 (AActor *actor) { AActor *mo; - fixed_t dist; + double dist; + if (!actor->target) { return false; } mo = actor->target; - dist = mo->AproxDistance (actor); - if (dist >= MELEERANGE*2 || dist < MELEERANGE-20*FRACUNIT + mo->radius) + dist = mo->Distance2D (actor); + if (dist >= 128 || dist < actor->meleerange + mo->radius) { return false; } @@ -346,7 +343,7 @@ bool P_CheckMeleeRange2 (AActor *actor) //============================================================================= bool P_CheckMissileRange (AActor *actor) { - fixed_t dist; + double dist; if (!P_CheckSight (actor, actor->target, SF_SEEPASTBLOCKEVERYTHING)) return false; @@ -385,15 +382,15 @@ bool P_CheckMissileRange (AActor *actor) // OPTIMIZE: get this from a global checksight // [RH] What? - dist = actor->AproxDistance (actor->target) - 64*FRACUNIT; + dist = actor->Distance2D (actor->target) - 64; if (actor->MeleeState == NULL) - dist -= 128*FRACUNIT; // no melee attack, so fire more + dist -= 128; // no melee attack, so fire more return actor->SuggestMissileAttack (dist); } -bool AActor::SuggestMissileAttack (fixed_t dist) +bool AActor::SuggestMissileAttack (double dist) { // new version encapsulates the different behavior in flags instead of virtual functions // The advantage is that this allows inheriting the missile attack attributes from the @@ -405,11 +402,11 @@ bool AActor::SuggestMissileAttack (fixed_t dist) if (MeleeState != NULL && dist < meleethreshold) return false; // From the Revenant: close enough for fist attack - if (flags4 & MF4_MISSILEMORE) dist >>= 1; - if (flags4 & MF4_MISSILEEVENMORE) dist >>= 3; + if (flags4 & MF4_MISSILEMORE) dist *= 0.5; + if (flags4 & MF4_MISSILEEVENMORE) dist *= 0.125; - int mmc = FixedMul(MinMissileChance, G_SkillProperty(SKILLP_Aggressiveness)); - return pr_checkmissilerange() >= MIN (dist >> FRACBITS, mmc); + int mmc = int(MinMissileChance * G_SkillProperty(SKILLP_Aggressiveness)); + return pr_checkmissilerange() >= MIN (int(dist), mmc); } //============================================================================= @@ -429,9 +426,9 @@ bool P_HitFriend(AActor * self) if (self->flags&MF_FRIENDLY && self->target != NULL) { - angle_t angle = self->AngleTo(self->target); - fixed_t dist = self->AproxDistance (self->target); - P_AimLineAttack (self, angle, dist, &t, 0, true); + DAngle angle = self->AngleTo(self->target); + double dist = self->Distance2D(self->target); + P_AimLineAttack (self, angle, dist, &t, 0., true); if (t.linetarget != NULL && t.linetarget != self->target) { return self->IsFriend (t.linetarget); @@ -449,11 +446,11 @@ bool P_HitFriend(AActor * self) bool P_Move (AActor *actor) { - fixed_t tryx, tryy, deltax, deltay, origx, origy; + double tryx, tryy, deltax, deltay, origx, origy; bool try_ok; - int speed = actor->Speed; - int movefactor = ORIG_FRICTION_FACTOR; - int friction = ORIG_FRICTION; + double speed = actor->Speed; + double movefactor = ORIG_FRICTION_FACTOR; + double friction = ORIG_FRICTION; int dropoff = 0; if (actor->flags2 & MF2_BLASTED) @@ -486,7 +483,7 @@ bool P_Move (AActor *actor) if ((actor->flags6 & MF6_JUMPDOWN) && target && !(target->IsFriend(actor)) && - actor->AproxDistance(target) < FRACUNIT*144 && + actor->Distance2D(target) < 144 && pr_dropoff() < 235) { dropoff = 2; @@ -501,40 +498,39 @@ bool P_Move (AActor *actor) if (friction < ORIG_FRICTION) { // sludge - speed = ((ORIG_FRICTION_FACTOR - (ORIG_FRICTION_FACTOR-movefactor)/2) - * speed) / ORIG_FRICTION_FACTOR; + speed = speed * ((ORIG_FRICTION_FACTOR - (ORIG_FRICTION_FACTOR-movefactor)/2)) / ORIG_FRICTION_FACTOR; if (speed == 0) { // always give the monster a little bit of speed - speed = ksgn(actor->Speed); + speed = actor->Speed; } } } - tryx = (origx = actor->X()) + (deltax = FixedMul (speed, xspeed[actor->movedir])); - tryy = (origy = actor->Y()) + (deltay = FixedMul (speed, yspeed[actor->movedir])); + tryx = (origx = actor->X()) + (deltax = (speed * xspeed[actor->movedir])); + tryy = (origy = actor->Y()) + (deltay = (speed * yspeed[actor->movedir])); // Like P_XYMovement this should do multiple moves if the step size is too large - fixed_t maxmove = actor->radius - FRACUNIT; + double maxmove = actor->radius - 1; int steps = 1; if (maxmove > 0) { - const fixed_t xspeed = abs (deltax); - const fixed_t yspeed = abs (deltay); + const double xspeed = fabs (deltax); + const double yspeed = fabs (deltay); if (xspeed > yspeed) { if (xspeed > maxmove) { - steps = 1 + xspeed / maxmove; + steps = 1 + int(xspeed / maxmove); } } else { if (yspeed > maxmove) { - steps = 1 + yspeed / maxmove; + steps = 1 + int(yspeed / maxmove); } } } @@ -545,12 +541,12 @@ bool P_Move (AActor *actor) try_ok = true; for(int i=1; i < steps; i++) { - try_ok = P_TryMove(actor, origx + Scale(deltax, i, steps), origy + Scale(deltay, i, steps), dropoff, NULL, tm); + try_ok = P_TryMove(actor, DVector2(origx + deltax * i / steps, origy + deltay * i / steps), dropoff, NULL, tm); if (!try_ok) break; } // killough 3/15/98: don't jump over dropoffs: - if (try_ok) try_ok = P_TryMove (actor, tryx, tryy, dropoff, NULL, tm); + if (try_ok) try_ok = P_TryMove (actor, DVector2(tryx, tryy), dropoff, NULL, tm); // [GrafZahl] Interpolating monster movement as it is done here just looks bad // so make it switchable @@ -562,9 +558,9 @@ bool P_Move (AActor *actor) if (try_ok && friction > ORIG_FRICTION) { actor->SetOrigin(origx, origy, actor->Z(), false); - movefactor *= FRACUNIT / ORIG_FRICTION_FACTOR / 4; - actor->vel.x += FixedMul (deltax, movefactor); - actor->vel.y += FixedMul (deltay, movefactor); + movefactor *= 1.f / ORIG_FRICTION_FACTOR / 4; + actor->Vel.X += deltax * movefactor; + actor->Vel.Y += deltay * movefactor; } // [RH] If a walking monster is no longer on the floor, move it down @@ -572,11 +568,11 @@ bool P_Move (AActor *actor) // actually walking down a step. if (try_ok && !((actor->flags & MF_NOGRAVITY) || (actor->flags6 & MF6_CANJUMP)) - && actor->Z() > actor->floorz && !(actor->flags2 & MF2_ONMOBJ)) + && actor->Z() > actor->floorz && !(actor->flags2 & MF2_ONMOBJ)) { if (actor->Z() <= actor->floorz + actor->MaxStepHeight) { - fixed_t savedz = actor->Z(); + double savedz = actor->Z(); actor->SetZ(actor->floorz); // Make sure that there isn't some other actor between us and // the floor we could get stuck in. The old code did not do this. @@ -600,7 +596,7 @@ bool P_Move (AActor *actor) { if (((actor->flags6 & MF6_CANJUMP)||(actor->flags & MF_FLOAT)) && tm.floatok) { // must adjust height - fixed_t savedz = actor->Z(); + double savedz = actor->Z(); if (actor->Z() < tm.floorz) actor->AddZ(actor->FloatSpeed); @@ -702,7 +698,7 @@ bool P_TryWalk (AActor *actor) // //============================================================================= -void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) +void P_DoNewChaseDir (AActor *actor, double deltax, double deltay) { dirtype_t d[2]; int tdir; @@ -713,19 +709,19 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) olddir = (dirtype_t)actor->movedir; turnaround = opposite[olddir]; - if (deltax>10*FRACUNIT) - d[0]= DI_EAST; - else if (deltax<-10*FRACUNIT) - d[0]= DI_WEST; + if (deltax > 10) + d[0] = DI_EAST; + else if (deltax < -10) + d[0] = DI_WEST; else - d[0]=DI_NODIR; + d[0] = DI_NODIR; - if (deltay<-10*FRACUNIT) - d[1]= DI_SOUTH; - else if (deltay>10*FRACUNIT) - d[1]= DI_NORTH; + if (deltay < -10) + d[1] = DI_SOUTH; + else if (deltay>10) + d[1] = DI_NORTH; else - d[1]=DI_NODIR; + d[1] = DI_NODIR; // try direct route if (d[0] != DI_NODIR && d[1] != DI_NODIR) @@ -742,7 +738,7 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) // try other directions if (!(actor->flags5 & MF5_AVOIDINGDROPOFF)) { - if ((pr_newchasedir() > 200 || abs(deltay) > abs(deltax))) + if ((pr_newchasedir() > 200 || fabs(deltay) > fabs(deltax))) { swapvalues (d[0], d[1]); } @@ -846,7 +842,7 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) void P_NewChaseDir(AActor * actor) { - fixedvec2 delta; + DVector2 delta; actor->strafecount = 0; @@ -863,8 +859,7 @@ void P_NewChaseDir(AActor * actor) if ((actor->target->player != NULL && (actor->target->player->cheats & CF_FRIGHTENING)) || (actor->flags4 & MF4_FRIGHTENED)) { - delta.x = -delta.x; - delta.y = -delta.y; + delta = -delta; } } } @@ -886,42 +881,39 @@ void P_NewChaseDir(AActor * actor) FBlockLinesIterator it(box); line_t *line; - fixed_t deltax = 0; - fixed_t deltay = 0; + double deltax = 0; + double deltay = 0; while ((line = it.Next())) { - if (line->backsector && // Ignore one-sided linedefs - box.Right() > line->bbox[BOXLEFT] && - box.Left() < line->bbox[BOXRIGHT] && - box.Top() > line->bbox[BOXBOTTOM] && // Linedef must be contacted - box.Bottom() < line->bbox[BOXTOP] && + if (line->backsector && // Ignore one-sided linedefs + box.inRange(line) && box.BoxOnLineSide(line) == -1) { - fixed_t front = line->frontsector->floorplane.ZatPoint(actor->PosRelative(line)); - fixed_t back = line->backsector->floorplane.ZatPoint(actor->PosRelative(line)); - angle_t angle; + double front = line->frontsector->floorplane.ZatPoint(actor->PosRelative(line)); + double back = line->backsector->floorplane.ZatPoint(actor->PosRelative(line)); + DAngle angle; // The monster must contact one of the two floors, // and the other must be a tall dropoff. if (back == actor->Z() && front < actor->Z() - actor->MaxDropOffHeight) { - angle = R_PointToAngle2(0,0,line->dx,line->dy); // front side dropoff + angle = line->Delta().Angle(); // front side dropoff } else if (front == actor->Z() && back < actor->Z() - actor->MaxDropOffHeight) { - angle = R_PointToAngle2(line->dx,line->dy,0,0); // back side dropoff + angle = line->Delta().Angle() + 180.; // back side dropoff } else continue; // Move away from dropoff at a standard speed. // Multiple contacted linedefs are cumulative (e.g. hanging over corner) - deltax -= finesine[angle >> ANGLETOFINESHIFT]*32; - deltay += finecosine[angle >> ANGLETOFINESHIFT]*32; + deltax -= 32 * angle.Sin(); + deltay += 32 * angle.Cos(); } } - if (deltax || deltay) + if (deltax != 0 || deltay != 0) { // [Graf Zahl] I have changed P_TryMove to only apply this logic when // being called from here. AVOIDINGDROPOFF activates the code that @@ -948,7 +940,7 @@ void P_NewChaseDir(AActor * actor) // MBF code for friends. Cannot be done in ZDoom but left here as a reminder for later implementation. if (actor->flags & target->flags & MF_FRIEND && - distfriend << FRACBITS > dist && + distfriend > dist && !P_IsOnLift(target) && !P_IsUnderDamage(actor)) deltax = -deltax, deltay = -deltay; else @@ -963,7 +955,7 @@ void P_NewChaseDir(AActor * actor) if (actor->flags3 & MF3_AVOIDMELEE) { bool ismeleeattacker = false; - fixed_t dist = actor->AproxDistance(target); + double dist = actor->Distance2D(target); if (target->player == NULL) { ismeleeattacker = (target->MissileState == NULL && dist < (target->meleerange + target->radius)*2); @@ -972,17 +964,17 @@ void P_NewChaseDir(AActor * actor) { // melee range of player weapon is a parameter of the action function and cannot be checked here. // Add a new weapon property? - ismeleeattacker = (target->player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON && dist < MELEERANGE*3); + ismeleeattacker = ((target->player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON) && dist < 192); } if (ismeleeattacker) { actor->strafecount = pr_enemystrafe() & 15; - delta.x = -delta.x, delta.y = -delta.y; + delta = -delta; } } } - P_DoNewChaseDir(actor, delta.x, delta.y); + P_DoNewChaseDir(actor, delta.X, delta.Y); // If strafing, set movecount to strafecount so that old Doom // logic still works the same, except in the strafing part @@ -1014,7 +1006,7 @@ void P_RandomChaseDir (AActor *actor) if (actor->flags & MF_FRIENDLY) { AActor *player; - fixedvec2 delta; + DVector2 delta; dirtype_t d[3]; if (actor->FriendPlayer != 0) @@ -1038,16 +1030,16 @@ void P_RandomChaseDir (AActor *actor) { delta = actor->Vec2To(player); - if (delta.x>128*FRACUNIT) + if (delta.X>128) d[1]= DI_EAST; - else if (delta.x<-128*FRACUNIT) + else if (delta.X<-128) d[1]= DI_WEST; else d[1]=DI_NODIR; - if (delta.y<-128*FRACUNIT) + if (delta.Y<-128) d[2]= DI_SOUTH; - else if (delta.y>128*FRACUNIT) + else if (delta.Y>128) d[2]= DI_NORTH; else d[2]=DI_NODIR; @@ -1055,13 +1047,13 @@ void P_RandomChaseDir (AActor *actor) // try direct route if (d[1] != DI_NODIR && d[2] != DI_NODIR) { - actor->movedir = diags[((delta.y<0)<<1) + (delta.x>0)]; + actor->movedir = diags[((delta.Y<0)<<1) + (delta.X>0)]; if (actor->movedir != turnaround && P_TryWalk(actor)) return; } // try other directions - if (pr_newchasedir() > 200 || abs(delta.y) > abs(delta.x)) + if (pr_newchasedir() > 200 || fabs(delta.Y) > fabs(delta.X)) { swapvalues (d[1], d[2]); } @@ -1164,23 +1156,23 @@ void P_RandomChaseDir (AActor *actor) bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams *params) { - fixed_t maxdist; - fixed_t mindist; - angle_t fov; + double maxdist; + double mindist; + DAngle fov; if (params != NULL) { - maxdist = params->maxdist; - mindist = params->mindist; - fov = params->fov; + maxdist = params->maxDist; + mindist = params->minDist; + fov = params->Fov; } else { mindist = maxdist = 0; - fov = allaround ? 0 : ANGLE_180; + fov = allaround ? 0. : 180.; } - fixed_t dist = lookee->AproxDistance (other); + double dist = lookee->Distance2D (other); if (maxdist && dist > maxdist) return false; // [KS] too far @@ -1188,15 +1180,15 @@ bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams if (mindist && dist < mindist) return false; // [KS] too close - if (fov && fov < ANGLE_MAX) + if (fov != 0) { - angle_t an = lookee->AngleTo(other) - lookee->angle; + DAngle an = absangle(lookee->AngleTo(other), lookee->Angles.Yaw); - if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) + if (an > (fov / 2)) { // if real close, react anyway // [KS] but respect minimum distance rules - if (mindist || dist > MELEERANGE) + if (mindist || dist > lookee->meleerange + lookee->radius) return false; // outside of fov } } @@ -1211,7 +1203,7 @@ bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams // //--------------------------------------------------------------------------- -#define MONS_LOOK_RANGE (20*64*FRACUNIT) +#define MONS_LOOK_RANGE (20*64) #define MONS_LOOK_LIMIT 64 bool P_LookForMonsters (AActor *actor) @@ -1231,7 +1223,7 @@ bool P_LookForMonsters (AActor *actor) { // Not a valid monster continue; } - if (mo->AproxDistance (actor) > MONS_LOOK_RANGE) + if (mo->Distance2D (actor) > MONS_LOOK_RANGE) { // Out of range continue; } @@ -1731,8 +1723,7 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) || player->mo->flags3 & MF3_GHOST) { - if ((player->mo->AproxDistance (actor) > 2*MELEERANGE) - && P_AproxDistance (player->mo->vel.x, player->mo->vel.y) < 5*FRACUNIT) + if (player->mo->Distance2D (actor) > 128 && player->mo->Vel.XY().LengthSquared() < 5*5) { // Player is sneaking - can't detect continue; } @@ -1886,15 +1877,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx) { PARAM_ACTION_PROLOGUE; PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (minseedist) { minseedist = 0; } - PARAM_FIXED_OPT (maxseedist) { maxseedist = 0; } - PARAM_FIXED_OPT (maxheardist) { maxheardist = 0; } - PARAM_FLOAT_OPT (fov_f) { fov_f = 0; } + PARAM_FLOAT_OPT (minseedist) { minseedist = 0; } + PARAM_FLOAT_OPT (maxseedist) { maxseedist = 0; } + PARAM_FLOAT_OPT (maxheardist) { maxheardist = 0; } + PARAM_ANGLE_OPT (fov) { fov = 0.; } PARAM_STATE_OPT (seestate) { seestate = NULL; } AActor *targ = NULL; // Shuts up gcc - fixed_t dist; - angle_t fov = (fov_f == 0) ? ANGLE_180 : FLOAT2ANGLE(fov_f); + double dist; + if (fov == 0) fov = 180.; FLookExParams params = { fov, minseedist, maxseedist, maxheardist, flags, seestate }; if (self->flags5 & MF5_INCONVERSATION) @@ -1934,7 +1925,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx) } else { - dist = self->AproxDistance (targ); + dist = self->Distance2D (targ); // [KS] If the target is too far away, don't respond to the sound. if (maxheardist && dist > maxheardist) @@ -2005,7 +1996,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx) { if (self->flags & MF_AMBUSH) { - dist = self->AproxDistance (self->target); + dist = self->Distance2D (self->target); if (P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING) && (!minseedist || dist > minseedist) && (!maxseedist || dist < maxseedist)) @@ -2134,15 +2125,15 @@ void A_Wander(AActor *self, int flags) // turn towards movement direction if not there yet if (!(flags & CHF_NODIRECTIONTURN) && (self->movedir < DI_NODIR)) { - self->angle &= (angle_t)(7 << 29); - int delta = self->angle - (self->movedir << 29); - if (delta > 0) + self->Angles.Yaw = floor(self->Angles.Yaw.Degrees / 45) * 45.; + DAngle delta = deltaangle(self->Angles.Yaw, (self->movedir * 45)); + if (delta < 0) { - self->angle -= ANG90 / 2; + self->Angles.Yaw -= 45; } - else if (delta < 0) + else if (delta > 0) { - self->angle += ANG90 / 2; + self->Angles.Yaw += 45; } } @@ -2223,11 +2214,10 @@ nosee: // enhancements. // //============================================================================= -#define CLASS_BOSS_STRAFE_RANGE 64*10*FRACUNIT +#define CLASS_BOSS_STRAFE_RANGE 64*10 void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove, int flags) { - int delta; if (actor->flags5 & MF5_INCONVERSATION) return; @@ -2289,15 +2279,15 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele } else if (!(flags & CHF_NODIRECTIONTURN) && actor->movedir < 8) { - actor->angle &= (angle_t)(7<<29); - delta = actor->angle - (actor->movedir << 29); - if (delta > 0) + actor->Angles.Yaw = floor(actor->Angles.Yaw.Degrees / 45) * 45.; + DAngle delta = deltaangle(actor->Angles.Yaw, (actor->movedir * 45)); + if (delta < 0) { - actor->angle -= ANG90/2; + actor->Angles.Yaw -= 45; } - else if (delta < 0) + else if (delta > 0) { - actor->angle += ANG90/2; + actor->Angles.Yaw += 45; } } @@ -2413,7 +2403,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele spec->args[1], spec->args[2], spec->args[3], spec->args[4]); } - angle_t lastgoalang = actor->goal->angle; + DAngle lastgoalang = actor->goal->Angles.Yaw; int delay; AActor * newgoal = iterator.Next (); if (newgoal != NULL && actor->goal == actor->target) @@ -2425,7 +2415,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele { delay = 0; actor->reactiontime = actor->GetDefault()->reactiontime; - actor->angle = lastgoalang; // Look in direction of last goal + actor->Angles.Yaw = lastgoalang; // Look in direction of last goal } if (actor->target == actor->goal) actor->target = NULL; actor->flags |= MF_JUSTATTACKED; @@ -2455,18 +2445,16 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele else { actor->FastChaseStrafeCount = 0; - actor->vel.x = 0; - actor->vel.y = 0; - fixed_t dist = actor->AproxDistance (actor->target); + actor->Vel.X = actor->Vel.Y = 0; + double dist = actor->Distance2D (actor->target); if (dist < CLASS_BOSS_STRAFE_RANGE) { if (pr_chase() < 100) { - angle_t ang = actor->AngleTo(actor->target); - if (pr_chase() < 128) ang += ANGLE_90; - else ang -= ANGLE_90; - actor->vel.x = 13 * finecosine[ang>>ANGLETOFINESHIFT]; - actor->vel.y = 13 * finesine[ang>>ANGLETOFINESHIFT]; + DAngle ang = actor->AngleTo(actor->target); + if (pr_chase() < 128) ang += 90.; + else ang -= 90.; + actor->VelFromAngle(ang, 13.); actor->FastChaseStrafeCount = 3; // strafe time } } @@ -2547,8 +2535,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele if ((!fastchase || !actor->FastChaseStrafeCount) && !dontmove) { // CANTLEAVEFLOORPIC handling was completely missing in the non-serpent functions. - fixed_t oldX = actor->X(); - fixed_t oldY = actor->Y(); + DVector2 old = actor->Pos(); int oldgroup = actor->PrevPortalGroup; FTextureID oldFloor = actor->floorpic; @@ -2561,12 +2548,12 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele // (copied from A_SerpentChase - it applies to everything with CANTLEAVEFLOORPIC!) if (actor->flags2&MF2_CANTLEAVEFLOORPIC && actor->floorpic != oldFloor ) { - if (P_TryMove(actor, oldX, oldY, false)) + if (P_TryMove(actor, old, false)) { if (nomonsterinterpolation) { - actor->PrevX = oldX; - actor->PrevY = oldY; + actor->Prev.X = old.X; + actor->Prev.Y = old.Y; actor->PrevPortalGroup = oldgroup; } } @@ -2600,14 +2587,14 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) if (self->movedir != DI_NODIR) { - const fixed_t absSpeed = abs (self->Speed); - fixedvec2 viletry = self->Vec2Offset( - FixedMul (absSpeed, xspeed[self->movedir]), - FixedMul (absSpeed, yspeed[self->movedir]), true); + const double absSpeed = fabs (self->Speed); + DVector2 viletry = self->Vec2Offset( + absSpeed * xspeed[self->movedir], + absSpeed * yspeed[self->movedir], true); FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); - FMultiBlockThingsIterator it(check, viletry.x, viletry.y, self->Z() - 64* FRACUNIT, self->Top() + 64 * FRACUNIT, 32 * FRACUNIT, false, NULL); + FMultiBlockThingsIterator it(check, viletry.X, viletry.Y, self->Z() - 64, self->Top() + 64, 32., false, NULL); FMultiBlockThingsIterator::CheckResult cres; while (it.Next(&cres)) { @@ -2616,10 +2603,10 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) if (raisestate != NULL) { // use the current actor's radius instead of the Arch Vile's default. - fixed_t maxdist = corpsehit->GetDefault()->radius + self->radius; + double maxdist = corpsehit->GetDefault()->radius + self->radius; - if (abs(corpsehit->Pos().x - cres.position.x) > maxdist || - abs(corpsehit->Pos().y - cres.position.y) > maxdist) + if (fabs(corpsehit->X() - cres.Position.X) > maxdist || + fabs(corpsehit->Y() - cres.Position.Y) > maxdist) continue; // not actually touching // Let's check if there are floors in between the archvile and its target @@ -2638,30 +2625,30 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) (vilesec != corpsec && corpsec->e->XFloor.ffloors.Size()) ? corpsec : NULL; if (testsec) { - fixed_t zdist1, zdist2; + double zdist1, zdist2; if (P_Find3DFloor(testsec, corpsehit->Pos(), false, true, zdist1) != P_Find3DFloor(testsec, self->Pos(), false, true, zdist2)) { // Not on same floor - if (vilesec == corpsec || abs(zdist1 - self->Z()) > self->height) + if (vilesec == corpsec || fabs(zdist1 - self->Z()) > self->Height) continue; } } } - corpsehit->vel.x = corpsehit->vel.y = 0; + corpsehit->Vel.X = corpsehit->Vel.Y = 0; // [RH] Check against real height and radius - fixed_t oldheight = corpsehit->height; - fixed_t oldradius = corpsehit->radius; + double oldheight = corpsehit->Height; + double oldradius = corpsehit->radius; ActorFlags oldflags = corpsehit->flags; corpsehit->flags |= MF_SOLID; - corpsehit->height = corpsehit->GetDefault()->height; + corpsehit->Height = corpsehit->GetDefault()->Height; bool check = P_CheckPosition(corpsehit, corpsehit->Pos()); corpsehit->flags = oldflags; corpsehit->radius = oldradius; - corpsehit->height = oldheight; + corpsehit->Height = oldheight; if (!check) continue; // got one! @@ -2703,15 +2690,15 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) } if (ib_compatflags & BCOMPATF_VILEGHOSTS) { - corpsehit->height <<= 2; + corpsehit->Height *= 4; // [GZ] This was a commented-out feature, so let's make use of it, // but only for ghost monsters so that they are visibly different. - if (corpsehit->height == 0) + if (corpsehit->Height == 0) { // Make raised corpses look ghostly - if (corpsehit->alpha > TRANSLUC50) + if (corpsehit->Alpha > 0.5) { - corpsehit->alpha /= 2; + corpsehit->Alpha /= 2; } // This will only work if the render style is changed as well. if (corpsehit->RenderStyle == LegacyRenderStyles[STYLE_Normal]) @@ -2722,7 +2709,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) } else { - corpsehit->height = info->height; // [RH] Use real mobj height + corpsehit->Height = info->Height; // [RH] Use real mobj height corpsehit->radius = info->radius; // [RH] Use real radius } @@ -2819,7 +2806,7 @@ enum FAF_Flags FAF_TOP = 4, FAF_NODISTFACTOR = 8, // deprecated }; -void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags, fixed_t z_add) +void A_Face(AActor *self, AActor *other, DAngle max_turn, DAngle max_pitch, DAngle ang_offset, DAngle pitch_offset, int flags, double z_add) { if (!other) return; @@ -2832,99 +2819,86 @@ void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, a self->flags &= ~MF_AMBUSH; - angle_t other_angle = self->AngleTo(other); + DAngle other_angle = self->AngleTo(other); + DAngle delta = -deltaangle(self->Angles.Yaw, other_angle); // 0 means no limit. Also, if we turn in a single step anyways, no need to go through the algorithms. // It also means that there is no need to check for going past the other. - if (max_turn && (max_turn < absangle(self->angle - other_angle))) + if (max_turn != 0 && (max_turn < fabs(delta))) { - if (self->angle > other_angle) + if (delta > 0) { - if (self->angle - other_angle < ANGLE_180) - { - self->angle -= max_turn + ang_offset; - } - else - { - self->angle += max_turn + ang_offset; - } + self->Angles.Yaw -= max_turn + ang_offset; } else { - if (other_angle - self->angle < ANGLE_180) - { - self->angle += max_turn + ang_offset; - } - else - { - self->angle -= max_turn + ang_offset; - } + self->Angles.Yaw += max_turn + ang_offset; } } else { - self->angle = other_angle + ang_offset; + self->Angles.Yaw = other_angle + ang_offset; } // [DH] Now set pitch. In order to maintain compatibility, this can be // disabled and is so by default. - if (max_pitch <= ANGLE_180) + if (max_pitch <= 180.) { - fixedvec2 pos = self->Vec2To(other); - DVector2 dist(pos.x, pos.y); + DVector2 dist = self->Vec2To(other); // Positioning ala missile spawning, 32 units above foot level - fixed_t source_z = self->Z() + 32*FRACUNIT + self->GetBobOffset(); - fixed_t target_z = other->Z() + 32*FRACUNIT + other->GetBobOffset(); + double source_z = self->Z() + 32 + self->GetBobOffset(); + double target_z = other->Z() + 32 + other->GetBobOffset(); // If the target z is above the target's head, reposition to the middle of // its body. if (target_z >= other->Top()) { - target_z = other->Z() + (other->height / 2); + target_z = other->Center(); } - //Note there is no +32*FRACUNIT on purpose. This is for customization sake. + //Note there is no +32 on purpose. This is for customization sake. //If one doesn't want this behavior, just don't use FAF_BOTTOM. if (flags & FAF_BOTTOM) target_z = other->Z() + other->GetBobOffset(); if (flags & FAF_MIDDLE) - target_z = other->Z() + (other->height / 2) + other->GetBobOffset(); + target_z = other->Center() + other->GetBobOffset(); if (flags & FAF_TOP) - target_z = other->Z() + (other->height) + other->GetBobOffset(); + target_z = other->Top() + other->GetBobOffset(); target_z += z_add; double dist_z = target_z - source_z; - double ddist = sqrt(dist.X*dist.X + dist.Y*dist.Y + dist_z*dist_z); - int other_pitch = (int)RAD2ANGLE(asin(dist_z / ddist)); + double ddist = g_sqrt(dist.X*dist.X + dist.Y*dist.Y + dist_z*dist_z); + + DAngle other_pitch = DAngle::ToDegrees(g_asin(dist_z / ddist)).Normalized180(); if (max_pitch != 0) { - if (self->pitch > other_pitch) + if (self->Angles.Pitch > other_pitch) { - max_pitch = MIN(max_pitch, unsigned(self->pitch - other_pitch)); - self->pitch -= max_pitch; + max_pitch = MIN(max_pitch, (self->Angles.Pitch - other_pitch).Normalized360()); + self->Angles.Pitch -= max_pitch; } else { - max_pitch = MIN(max_pitch, unsigned(other_pitch - self->pitch)); - self->pitch += max_pitch; + max_pitch = MIN(max_pitch, (other_pitch - self->Angles.Pitch).Normalized360()); + self->Angles.Pitch += max_pitch; } } else { - self->pitch = other_pitch; + self->Angles.Pitch = other_pitch; } - self->pitch += pitch_offset; + self->Angles.Pitch += pitch_offset; } // This will never work well if the turn angle is limited. - if (max_turn == 0 && (self->angle == other_angle) && other->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE) ) + if (max_turn == 0 && (self->Angles.Yaw == other_angle) && other->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE) ) { - self->angle += pr_facetarget.Random2() << 21; + self->Angles.Yaw += pr_facetarget.Random2() * (45 / 256.); } } @@ -2936,12 +2910,12 @@ void A_FaceTarget(AActor *self) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTarget) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(max_turn) { max_turn = 0; } - PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270; } - PARAM_ANGLE_OPT(ang_offset) { ang_offset = 0; } - PARAM_ANGLE_OPT(pitch_offset) { pitch_offset = 0; } + PARAM_ANGLE_OPT(max_turn) { max_turn = 0.; } + PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270.; } + PARAM_ANGLE_OPT(ang_offset) { ang_offset = 0.; } + PARAM_ANGLE_OPT(pitch_offset) { pitch_offset = 0.; } PARAM_INT_OPT(flags) { flags = 0; } - PARAM_FIXED_OPT(z_add) { z_add = 0; } + PARAM_FLOAT_OPT(z_add) { z_add = 0; } A_Face(self, self->target, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add); return 0; @@ -2950,12 +2924,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTarget) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMaster) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(max_turn) { max_turn = 0; } - PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270; } - PARAM_ANGLE_OPT(ang_offset) { ang_offset = 0; } - PARAM_ANGLE_OPT(pitch_offset) { pitch_offset = 0; } - PARAM_INT_OPT(flags) { flags = 0; } - PARAM_FIXED_OPT(z_add) { z_add = 0; } + PARAM_ANGLE_OPT(max_turn) { max_turn = 0.; } + PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270.; } + PARAM_ANGLE_OPT(ang_offset) { ang_offset = 0.; } + PARAM_ANGLE_OPT(pitch_offset) { pitch_offset = 0.; } + PARAM_INT_OPT(flags) { flags = 0; } + PARAM_FLOAT_OPT(z_add) { z_add = 0; } A_Face(self, self->master, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add); return 0; @@ -2964,12 +2938,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMaster) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTracer) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(max_turn) { max_turn = 0; } - PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270; } - PARAM_ANGLE_OPT(ang_offset) { ang_offset = 0; } - PARAM_ANGLE_OPT(pitch_offset) { pitch_offset = 0; } - PARAM_INT_OPT(flags) { flags = 0; } - PARAM_FIXED_OPT(z_add) { z_add = 0; } + PARAM_ANGLE_OPT(max_turn) { max_turn = 0.; } + PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270.; } + PARAM_ANGLE_OPT(ang_offset) { ang_offset = 0.; } + PARAM_ANGLE_OPT(pitch_offset) { pitch_offset = 0.; } + PARAM_INT_OPT(flags) { flags = 0; } + PARAM_FLOAT_OPT(z_add) { z_add = 0; } A_Face(self, self->tracer, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add); return 0; @@ -2989,7 +2963,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail) if (!self->target) return 0; - fixed_t saved_pitch = self->pitch; + DAngle saved_pitch = self->Angles.Pitch; FTranslatedLineTarget t; // [RH] Andy Baker's stealth monsters @@ -3000,28 +2974,31 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail) self->flags &= ~MF_AMBUSH; - self->angle = self->AngleTo(self->target); + self->Angles.Yaw = self->AngleTo(self->target); - self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &t, ANGLE_1*60, 0, self->target); + self->Angles.Pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE, &t, 60., 0, self->target); if (t.linetarget == NULL) { // We probably won't hit the target, but aim at it anyway so we don't look stupid. - fixedvec2 pos = self->Vec2To(self->target); - DVector2 xydiff(pos.x, pos.y); - double zdiff = (self->target->Z() + (self->target->height>>1)) - (self->Z() + (self->height>>1) - self->floorclip); - self->pitch = int(atan2(zdiff, xydiff.Length()) * ANGLE_180 / -M_PI); + DVector2 xydiff = self->Vec2To(self->target); + double zdiff = self->target->Center() - self->Center() - self->Floorclip; + self->Angles.Pitch = -VecToAngle(xydiff.Length(), zdiff); } // Let the aim trail behind the player - self->angle = self->AngleTo(self->target, -self->target->vel.x * 3, -self->target->vel.y * 3); + self->Angles.Yaw = self->AngleTo(self->target, -self->target->Vel.X * 3, -self->target->Vel.Y * 3); if (self->target->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE)) { - self->angle += pr_railface.Random2() << 21; + self->Angles.Yaw += pr_railface.Random2() * 45./256; } - P_RailAttack (self, self->GetMissileDamage (0, 1), 0); - self->pitch = saved_pitch; + FRailParams p; + + p.source = self; + p.damage = self->GetMissileDamage(0, 1); + P_RailAttack (&p); + self->Angles.Pitch = saved_pitch; return 0; } @@ -3107,11 +3084,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_ActiveAndUnblock) void ModifyDropAmount(AInventory *inv, int dropamount) { int flagmask = IF_IGNORESKILL; - fixed_t dropammofactor = G_SkillProperty(SKILLP_DropAmmoFactor); + double dropammofactor = G_SkillProperty(SKILLP_DropAmmoFactor); // Default drop amount is half of regular amount * regular ammo multiplication if (dropammofactor == -1) { - dropammofactor = FRACUNIT/2; + dropammofactor = 0.5; flagmask = 0; } @@ -3119,7 +3096,7 @@ void ModifyDropAmount(AInventory *inv, int dropamount) { if (flagmask != 0 && inv->IsKindOf(RUNTIME_CLASS(AAmmo))) { - inv->Amount = FixedMul(dropamount, dropammofactor); + inv->Amount = int(dropamount * dropammofactor); inv->ItemFlags |= IF_IGNORESKILL; } else @@ -3133,7 +3110,7 @@ void ModifyDropAmount(AInventory *inv, int dropamount) int amount = static_cast(inv->GetClass())->DropAmount; if (amount <= 0) { - amount = MAX(1, FixedMul(inv->Amount, dropammofactor)); + amount = MAX(1, int(inv->Amount * dropammofactor)); } inv->Amount = amount; inv->ItemFlags |= flagmask; @@ -3146,8 +3123,8 @@ void ModifyDropAmount(AInventory *inv, int dropamount) else if (inv->IsKindOf (RUNTIME_CLASS(AWeapon))) { // The same goes for ammo from a weapon. - static_cast(inv)->AmmoGive1 = FixedMul(static_cast(inv)->AmmoGive1, dropammofactor); - static_cast(inv)->AmmoGive2 = FixedMul(static_cast(inv)->AmmoGive2, dropammofactor); + static_cast(inv)->AmmoGive1 = int(static_cast(inv)->AmmoGive1 * dropammofactor); + static_cast(inv)->AmmoGive2 = int(static_cast(inv)->AmmoGive2 * dropammofactor); inv->ItemFlags |= flagmask; } else if (inv->IsKindOf (RUNTIME_CLASS(ADehackedPickup))) @@ -3170,9 +3147,8 @@ AInventory *P_DropItem (AActor *source, PClassActor *type, int dropamount, int c if (type != NULL && pr_dropitem() <= chance) { AActor *mo; - fixed_t spawnz; + double spawnz = 0; - spawnz = source->Z(); if (!(i_compatflags & COMPATF_NOTOSSDROPS)) { int style = sv_dropstyle; @@ -3182,14 +3158,14 @@ AInventory *P_DropItem (AActor *source, PClassActor *type, int dropamount, int c } if (style == 2) { - spawnz += 24*FRACUNIT; + spawnz = 24; } else { - spawnz += source->height / 2; + spawnz = source->Height / 2; } } - mo = Spawn(type, source->X(), source->Y(), spawnz, ALLOW_REPLACE); + mo = Spawn(type, source->PosPlusZ(spawnz), ALLOW_REPLACE); if (mo != NULL) { mo->flags |= MF_DROPPED; @@ -3230,14 +3206,14 @@ void P_TossItem (AActor *item) if (style==2) { - item->vel.x += pr_dropitem.Random2(7) << FRACBITS; - item->vel.y += pr_dropitem.Random2(7) << FRACBITS; + item->Vel.X += pr_dropitem.Random2(7); + item->Vel.Y += pr_dropitem.Random2(7); } else { - item->vel.x = pr_dropitem.Random2() << 8; - item->vel.y = pr_dropitem.Random2() << 8; - item->vel.z = FRACUNIT*5 + (pr_dropitem() << 10); + item->Vel.X += pr_dropitem.Random2() / 256.; + item->Vel.Y += pr_dropitem.Random2() / 256.; + item->Vel.Z = 5. + pr_dropitem() / 64.; } } @@ -3309,7 +3285,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Detonate) PARAM_ACTION_PROLOGUE; int damage = self->GetMissileDamage(0, 1); P_RadiusAttack (self, self->target, damage, damage, self->DamageType, RADF_HURTSOURCE); - P_CheckSplash(self, damage<floorclip < actor->height) + if (actor->Floorclip < actor->Height) { - actor->floorclip += speed; + actor->Floorclip += speed; return false; } return true; @@ -3504,17 +3480,17 @@ bool A_SinkMobj (AActor *actor, fixed_t speed) // Raise a mobj incrementally from the floor to // -bool A_RaiseMobj (AActor *actor, fixed_t speed) +bool A_RaiseMobj (AActor *actor, double speed) { bool done = true; // Raise a mobj from the ground - if (actor->floorclip > 0) + if (actor->Floorclip > 0) { - actor->floorclip -= speed; - if (actor->floorclip <= 0) + actor->Floorclip -= speed; + if (actor->Floorclip <= 0) { - actor->floorclip = 0; + actor->Floorclip = 0; done = true; } else diff --git a/src/p_enemy.h b/src/p_enemy.h index 7535f13a3..9e6b03b72 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -24,7 +24,7 @@ enum dirtype_t NUMDIRS }; -extern fixed_t xspeed[8], yspeed[8]; +extern double xspeed[8], yspeed[8]; enum LO_Flags { @@ -38,18 +38,19 @@ enum LO_Flags struct FLookExParams { - angle_t fov; - fixed_t mindist; - fixed_t maxdist; - fixed_t maxheardist; + DAngle Fov; + double minDist; + double maxDist; + double maxHeardist; int flags; FState *seestate; }; void P_DaggerAlert (AActor *target, AActor *emitter); -void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soundblocks, AActor *emitter=NULL, fixed_t maxdist=0); +void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soundblocks, AActor *emitter=NULL, double maxdist=0); bool P_HitFriend (AActor *self); -void P_NoiseAlert (AActor *target, AActor *emmiter, bool splash=false, fixed_t maxdist=0); +void P_NoiseAlert (AActor *target, AActor *emmiter, bool splash=false, double maxdist=0); + bool P_CheckMeleeRange2 (AActor *actor); bool P_Move (AActor *actor); bool P_TryWalk (AActor *actor); @@ -57,7 +58,7 @@ void P_NewChaseDir (AActor *actor); AInventory *P_DropItem (AActor *source, PClassActor *type, int special, int chance); void P_TossItem (AActor *item); bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params); -void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdist); +void A_Weave(AActor *self, int xyspeed, int zspeed, double xydist, double zdist); void A_Unblock(AActor *self, bool drop); DECLARE_ACTION(A_Look) @@ -73,16 +74,16 @@ void A_BossDeath(AActor *self); void A_Wander(AActor *self, int flags = 0); void A_Chase(VMFrameStack *stack, AActor *self); void A_FaceTarget(AActor *actor); -void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0, fixed_t z_add = 0); +void A_Face(AActor *self, AActor *other, DAngle max_turn = 0., DAngle max_pitch = 270., DAngle ang_offset = 0., DAngle pitch_offset = 0., int flags = 0, double z_add = 0); -bool A_RaiseMobj (AActor *, fixed_t speed); -bool A_SinkMobj (AActor *, fixed_t speed); +bool A_RaiseMobj (AActor *, double speed); +bool A_SinkMobj (AActor *, double speed); bool CheckBossDeath (AActor *); int P_Massacre (); bool P_CheckMissileRange (AActor *actor); -#define SKULLSPEED (20*FRACUNIT) -void A_SkullAttack(AActor *self, fixed_t speed); +#define SKULLSPEED (20.) +void A_SkullAttack(AActor *self, double speed); #endif //__P_ENEMY_H__ diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 593328c93..9ad68c3b1 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -280,14 +280,14 @@ DFloor::DFloor (sector_t *sec) //========================================================================== bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, - fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower) + double speed, double height, int crush, int change, bool hexencrush, bool hereticlower) { int secnum; bool rtn; sector_t* sec; DFloor* floor; - fixed_t ceilingheight; - fixed_t newheight; + double ceilingheight; + double newheight; vertex_t *spot, *spot2; rtn = false; @@ -312,7 +312,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, floor->m_Hexencrush = hexencrush; floor->m_Speed = speed; floor->m_ResetCount = 0; // [RH] - floor->m_OrgDist = sec->floorplane.d; // [RH] + floor->m_OrgDist = sec->floorplane.fD(); // [RH] switch (floortype) { @@ -322,7 +322,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, floor->m_FloorDestDist = sec->floorplane.PointToDist (spot, newheight); // [RH] DOOM's turboLower type did this. I've just extended it // to be applicable to all LowerToHighest types. - if (hereticlower || floor->m_FloorDestDist != sec->floorplane.d) + if (hereticlower || floor->m_FloorDestDist != sec->floorplane.fD()) floor->m_FloorDestDist = sec->floorplane.PointToDist (spot, newheight+height); break; @@ -358,7 +358,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, case DFloor::floorMoveToValue: sec->FindHighestFloorPoint (&spot); floor->m_FloorDestDist = sec->floorplane.PointToDist (spot, height); - floor->m_Direction = (floor->m_FloorDestDist > sec->floorplane.d) ? -1 : 1; + floor->m_Direction = (floor->m_FloorDestDist > sec->floorplane.fD()) ? -1 : 1; break; case DFloor::floorRaiseAndCrushDoom: @@ -366,12 +366,12 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, floor->m_Direction = 1; newheight = sec->FindLowestCeilingSurrounding (&spot); if (floortype == DFloor::floorRaiseAndCrushDoom) - newheight -= 8 * FRACUNIT; + newheight -= 8; ceilingheight = sec->FindLowestCeilingPoint (&spot2); floor->m_FloorDestDist = sec->floorplane.PointToDist (spot, newheight); if (sec->floorplane.ZatPointDist (spot2, floor->m_FloorDestDist) > ceilingheight) floor->m_FloorDestDist = sec->floorplane.PointToDist (spot2, - floortype == DFloor::floorRaiseAndCrushDoom ? ceilingheight - 8*FRACUNIT : ceilingheight); + floortype == DFloor::floorRaiseAndCrushDoom ? ceilingheight - 8 : ceilingheight); break; case DFloor::floorRaiseToHighest: @@ -394,7 +394,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, case DFloor::floorRaiseAndCrush: floor->m_Direction = 1; - newheight = sec->FindLowestCeilingPoint (&spot) - 8*FRACUNIT; + newheight = sec->FindLowestCeilingPoint (&spot) - 8; floor->m_FloorDestDist = sec->floorplane.PointToDist (spot, newheight); break; @@ -475,9 +475,9 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, // Do not interpolate instant movement floors. bool silent = false; - if ((floor->m_Direction>0 && floor->m_FloorDestDist>sec->floorplane.d) || // moving up but going down - (floor->m_Direction<0 && floor->m_FloorDestDistfloorplane.d) || // moving down but going up - (floor->m_Speed >= abs(sec->floorplane.d - floor->m_FloorDestDist))) // moving in one step + if ((floor->m_Direction>0 && floor->m_FloorDestDist>sec->floorplane.fD()) || // moving up but going down + (floor->m_Direction<0 && floor->m_FloorDestDistfloorplane.fD()) || // moving down but going up + (floor->m_Speed >= fabs(sec->floorplane.fD() - floor->m_FloorDestDist))) // moving in one step { floor->StopInterpolation(true); @@ -560,13 +560,13 @@ bool EV_FloorCrushStop (int tag) //========================================================================== bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, - fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, + double stairsize, double speed, int delay, int reset, int igntxt, int usespecials) { int secnum = -1; int osecnum; //jff 3/4/98 save old loop index - int height; - fixed_t stairstep; + double height; + double stairstep; int i; int newsecnum = -1; FTextureID texture; @@ -583,7 +583,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, if (speed == 0) return false; - persteptime = FixedDiv (stairsize, speed) >> FRACBITS; + persteptime = int(stairsize / speed); // check if a manual trigger, if so do just the sector on the backside FSectorTagIterator itr(tag, line); @@ -609,13 +609,13 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, stairstep = stairsize * floor->m_Direction; floor->m_Type = DFloor::buildStair; //jff 3/31/98 do not leave uninited floor->m_ResetCount = reset; // [RH] Tics until reset (0 if never) - floor->m_OrgDist = sec->floorplane.d; // [RH] Height to reset to + floor->m_OrgDist = sec->floorplane.fD(); // [RH] Height to reset to // [RH] Set up delay values floor->m_Delay = delay; floor->m_PauseTime = 0; floor->m_StepTime = floor->m_PerStepTime = persteptime; - floor->m_Crush = (!(usespecials & DFloor::stairUseSpecials) && speed == 4*FRACUNIT) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field + floor->m_Crush = (!(usespecials & DFloor::stairUseSpecials) && speed == 4) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field floor->m_Hexencrush = false; floor->m_Speed = speed; @@ -710,7 +710,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, floor = new DFloor (sec); floor->StartFloorSound (); floor->m_Direction = (type == DFloor::buildUp) ? 1 : -1; - floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, height); + floor->m_FloorDestDist = sec->floorplane.PointToDist (DVector2(0, 0), height); // [RH] Set up delay values floor->m_Delay = delay; floor->m_PauseTime = 0; @@ -719,8 +719,8 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, if (usespecials & DFloor::stairSync) { // [RH] - fixed_t rise = height - sec->CenterFloor(); - floor->m_Speed = Scale (speed, rise, stairstep); + double rise = height - sec->CenterFloor(); + floor->m_Speed = speed * rise / stairstep; } else { @@ -728,10 +728,10 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, } floor->m_Type = DFloor::buildStair; //jff 3/31/98 do not leave uninited //jff 2/27/98 fix uninitialized crush field - floor->m_Crush = (!(usespecials & DFloor::stairUseSpecials) && speed == 4*FRACUNIT) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field + floor->m_Crush = (!(usespecials & DFloor::stairUseSpecials) && speed == 4) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field floor->m_Hexencrush = false; floor->m_ResetCount = reset; // [RH] Tics until reset (0 if never) - floor->m_OrgDist = sec->floorplane.d; // [RH] Height to reset to + floor->m_OrgDist = sec->floorplane.fD(); // [RH] Height to reset to } } while (ok); // [RH] make sure the first sector doesn't point to a previous one, otherwise @@ -747,7 +747,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, // //========================================================================== -bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed) +bool EV_DoDonut (int tag, line_t *line, double pillarspeed, double slimespeed) { sector_t* s1; sector_t* s2; @@ -757,7 +757,7 @@ bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed) int i; DFloor* floor; vertex_t* spot; - fixed_t height; + double height; rtn = false; @@ -900,10 +900,10 @@ void DElevator::Tick () { EResult res; - fixed_t oldfloor, oldceiling; + double oldfloor, oldceiling; - oldfloor = m_Sector->floorplane.d; - oldceiling = m_Sector->ceilingplane.d; + oldfloor = m_Sector->floorplane.fD(); + oldceiling = m_Sector->ceilingplane.fD(); if (m_Direction < 0) // moving down { @@ -966,14 +966,14 @@ void DElevator::StartFloorSound () //========================================================================== bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, - fixed_t speed, fixed_t height, int tag) + double speed, double height, int tag) { int secnum; bool rtn; sector_t* sec; DElevator* elevator; - fixed_t floorheight, ceilingheight; - fixed_t newheight; + double floorheight, ceilingheight; + double newheight; vertex_t* spot; if (!line && (elevtype == DElevator::elevateCurrent)) @@ -1010,7 +1010,7 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, elevator->m_Direction = -1; newheight = sec->FindNextLowestFloor (&spot); elevator->m_FloorDestDist = sec->floorplane.PointToDist (spot, newheight); - newheight += sec->ceilingplane.ZatPoint (spot) - sec->floorplane.ZatPoint (spot); + newheight += sec->ceilingplane.ZatPoint(spot) - sec->floorplane.ZatPoint(spot); elevator->m_CeilingDestDist = sec->ceilingplane.PointToDist (spot, newheight); break; @@ -1019,7 +1019,7 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, elevator->m_Direction = 1; newheight = sec->FindNextHighestFloor (&spot); elevator->m_FloorDestDist = sec->floorplane.PointToDist (spot, newheight); - newheight += sec->ceilingplane.ZatPoint (spot) - sec->floorplane.ZatPoint (spot); + newheight += sec->ceilingplane.ZatPoint(spot) - sec->floorplane.ZatPoint(spot); elevator->m_CeilingDestDist = sec->ceilingplane.PointToDist (spot, newheight); break; @@ -1027,11 +1027,11 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, case DElevator::elevateCurrent: newheight = line->frontsector->floorplane.ZatPoint (line->v1); elevator->m_FloorDestDist = sec->floorplane.PointToDist (line->v1, newheight); - newheight += sec->ceilingplane.ZatPoint (line->v1) - sec->floorplane.ZatPoint (line->v1); + newheight += sec->ceilingplane.ZatPoint(line->v1) - sec->floorplane.ZatPoint(line->v1); elevator->m_CeilingDestDist = sec->ceilingplane.PointToDist (line->v1, newheight); elevator->m_Direction = - elevator->m_FloorDestDist > sec->floorplane.d ? -1 : 1; + elevator->m_FloorDestDist > sec->floorplane.fD() ? -1 : 1; break; // [RH] elevate up by a specific amount @@ -1178,7 +1178,7 @@ void DWaggleBase::DoWaggle (bool ceiling) { secplane_t *plane; int pos; - fixed_t dist; + double dist; if (ceiling) { @@ -1204,9 +1204,9 @@ void DWaggleBase::DoWaggle (bool ceiling) case WGLSTATE_REDUCE: if ((m_Scale -= m_ScaleDelta) <= 0) { // Remove - dist = FixedMul (m_OriginalDist - plane->d, plane->ic); + dist = (m_OriginalDist - plane->fD()) / plane->fC(); m_Sector->ChangePlaneTexZ(pos, -plane->HeightDiff (m_OriginalDist)); - plane->d = m_OriginalDist; + plane->setD(m_OriginalDist); P_ChangeSector (m_Sector, true, dist, ceiling, false); if (ceiling) { @@ -1233,11 +1233,8 @@ void DWaggleBase::DoWaggle (bool ceiling) } m_Accumulator += m_AccDelta; - - fixed_t mag = finesine[(m_Accumulator>>9)&8191]*8; - - dist = plane->d; - plane->d = m_OriginalDist + plane->PointToDist (0, 0, FixedMul (mag, m_Scale)); + dist = plane->fD(); + plane->setD(m_OriginalDist + plane->PointToDist (DVector2(0, 0), BobSin(m_Accumulator) *m_Scale)); m_Sector->ChangePlaneTexZ(pos, plane->HeightDiff (dist)); dist = plane->HeightDiff (dist); @@ -1322,19 +1319,18 @@ bool EV_StartWaggle (int tag, line_t *line, int height, int speed, int offset, if (ceiling) { waggle = new DCeilingWaggle (sector); - waggle->m_OriginalDist = sector->ceilingplane.d; + waggle->m_OriginalDist = sector->ceilingplane.fD(); } else { waggle = new DFloorWaggle (sector); - waggle->m_OriginalDist = sector->floorplane.d; + waggle->m_OriginalDist = sector->floorplane.fD(); } - waggle->m_Accumulator = offset*FRACUNIT; - waggle->m_AccDelta = speed << (FRACBITS-6); + waggle->m_Accumulator = offset; + waggle->m_AccDelta = speed / 64.; waggle->m_Scale = 0; - waggle->m_TargetScale = height << (FRACBITS-6); - waggle->m_ScaleDelta = waggle->m_TargetScale - /(TICRATE+((3*TICRATE)*height)/255); + waggle->m_TargetScale = height / 64.; + waggle->m_ScaleDelta = waggle->m_TargetScale / (TICRATE + ((3 * TICRATE)*height) / 255); waggle->m_Ticker = timer ? timer*TICRATE : -1; waggle->m_State = WGLSTATE_EXPAND; } diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index ed4b1d345..becd1f3be 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -81,7 +81,7 @@ static void CreateCachedNodes(MapData *map); // fixed 32 bit gl_vert format v2.0+ (glBsp 1.91) struct mapglvertex_t { - fixed_t x,y; + SDWORD x,y; }; struct gl3_mapsubsector_t @@ -129,10 +129,10 @@ struct gl5_mapnode_t static int CheckForMissingSegs() { - float *added_seglen = new float[numsides]; + double *added_seglen = new double[numsides]; int missing = 0; - memset(added_seglen, 0, sizeof(float)*numsides); + memset(added_seglen, 0, sizeof(double)*numsides); for(int i=0;isidedef!=NULL) { // check all the segs and calculate the length they occupy on their sidedef - DVector2 vec1(seg->v2->x - seg->v1->x, seg->v2->y - seg->v1->y); - added_seglen[seg->sidedef - sides] += float(vec1.Length()); + DVector2 vec1(seg->v2->fX() - seg->v1->fX(), seg->v2->fY() - seg->v1->fY()); + added_seglen[seg->sidedef - sides] += vec1.Length(); } } for(int i=0;ilinedef; - - DVector2 lvec(line->dx, line->dy); - float linelen = float(lvec.Length()); - - missing += (added_seglen[i] < linelen - FRACUNIT); + double linelen = sides[i].linedef->Delta().Length(); + missing += (added_seglen[i] < linelen - 1.); } delete [] added_seglen; @@ -268,8 +263,7 @@ static bool LoadGLVertexes(FileReader * lump) for (i = firstglvertex; i < numvertexes; i++) { - vertexes[i].x = LittleLong(mgl->x); - vertexes[i].y = LittleLong(mgl->y); + vertexes[i].set(LittleLong(mgl->x), LittleLong(mgl->y)); mgl++; } delete[] gldata; @@ -1102,8 +1096,8 @@ static void CreateCachedNodes(MapData *map) WriteLong(ZNodes, numvertexes); for(int i=0;iflags |= SSECF_DEGENERATE; for(j=2; jnumlines; j++) { - if (!PointOnLine(seg[j].v1->x, seg[j].v1->y, seg->v1->x, seg->v1->y, seg->v2->x-seg->v1->x, seg->v2->y-seg->v1->y)) + if (!PointOnLine(seg[j].v1->fixX(), seg[j].v1->fixY(), seg->v1->fixX(), seg->v1->fixY(), seg->v2->fixX() -seg->v1->fixX(), seg->v2->fixY() -seg->v1->fixY())) { // Not on the same line ss->flags &= ~SSECF_DEGENERATE; diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 648b9f46c..c2d5afd81 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -84,11 +84,11 @@ FName MeansOfDeath; // void P_TouchSpecialThing (AActor *special, AActor *toucher) { - fixed_t delta = special->Z() - toucher->Z(); + double delta = special->Z() - toucher->Z(); // The pickup is at or above the toucher's feet OR // The pickup is below the toucher. - if (delta > toucher->height || delta < MIN(-32*FRACUNIT, -special->height)) + if (delta > toucher->Height || delta < MIN(-32., -special->Height)) { // out of reach return; } @@ -392,7 +392,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) flags6 |= MF6_KILLED; // [RH] Allow the death height to be overridden using metadata. - fixed_t metaheight = -1; + double metaheight = -1; if (DamageType == NAME_Fire) { metaheight = GetClass()->BurnHeight; @@ -403,11 +403,11 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) } if (metaheight < 0) { - height >>= 2; + Height *= 0.25; } else { - height = MAX (metaheight, 0); + Height = MAX (metaheight, 0); } // [RH] If the thing has a special, execute and remove it @@ -926,11 +926,11 @@ static inline bool isFakePain(AActor *target, AActor *inflictor, int damage) // Returns the amount of damage actually inflicted upon the target, or -1 if // the damage was cancelled. -int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, angle_t angle) +int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, DAngle angle) { - unsigned ang; + DAngle ang; player_t *player = NULL; - fixed_t thrust; + double thrust; int temp; int painchance = 0; FState * woundstate = NULL; @@ -973,7 +973,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, { target->tics = 1; target->flags6 |= MF6_SHATTERING; - target->vel.x = target->vel.y = target->vel.z = 0; + target->Vel.Zero(); } return -1; } @@ -1023,12 +1023,12 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // [RH] Andy Baker's Stealth monsters if (target->flags & MF_STEALTH) { - target->alpha = OPAQUE; + target->Alpha = 1.; target->visdir = -1; } if (target->flags & MF_SKULLFLY) { - target->vel.x = target->vel.y = target->vel.z = 0; + target->Vel.Zero(); } player = target->player; @@ -1045,7 +1045,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (player && damage > 1) { // Take half damage in trainer mode - damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor)); + damage = int(damage * G_SkillProperty(SKILLP_DamageFactor)); } // Special damage types if (inflictor) @@ -1075,7 +1075,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (damage > 0 && source != NULL) { - damage = FixedMul(damage, source->DamageMultiply); + damage = int(damage * source->DamageMultiply); // Handle active damage modifiers (e.g. PowerDamage) if (damage > 0 && source->Inventory != NULL) @@ -1090,11 +1090,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, } if (damage > 0 && !(flags & DMG_NO_FACTOR)) { - damage = FixedMul(damage, target->DamageFactor); - if (damage > 0) - { - damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, mod, target->GetClass()->DamageFactors); - } + damage = target->ApplyDamageFactor(mod, damage); } if (damage >= 0) @@ -1159,58 +1155,49 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // If the origin and target are in exactly the same spot, choose a random direction. // (Most likely cause is from telefragging somebody during spawning because they // haven't moved from their spawn spot at all.) - ang = pr_kickbackdir.GenRand32(); + ang = pr_kickbackdir.GenRand_Real2() * 360.; } else { ang = origin->AngleTo(target); } - // Calculate this as float to avoid overflows so that the - // clamping that had to be done here can be removed. - double fltthrust; - - fltthrust = mod == NAME_MDK ? 10 : 32; + thrust = mod == NAME_MDK ? 10 : 32; if (target->Mass > 0) { - fltthrust = clamp((damage * 0.125 * kickback) / target->Mass, 0., fltthrust); + thrust = clamp((damage * 0.125 * kickback) / target->Mass, 0., thrust); } - thrust = FLOAT2FIXED(fltthrust); - // Don't apply ultra-small damage thrust - if (thrust < FRACUNIT/100) thrust = 0; + if (thrust < 0.01) thrust = 0; // make fall forwards sometimes if ((damage < 40) && (damage > target->health) - && (target->Z() - origin->Z() > 64*FRACUNIT) + && (target->Z() - origin->Z() > 64) && (pr_damagemobj()&1) // [RH] But only if not too fast and not flying - && thrust < 10*FRACUNIT + && thrust < 10 && !(target->flags & MF_NOGRAVITY) && (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL)) ) { - ang += ANG180; + ang += 180.; thrust *= 4; } - ang >>= ANGLETOFINESHIFT; if (source && source->player && (flags & DMG_INFLICTOR_IS_PUFF) && source->player->ReadyWeapon != NULL && (source->player->ReadyWeapon->WeaponFlags & WIF_STAFF2_KICKBACK)) { // Staff power level 2 - target->vel.x += FixedMul (10*FRACUNIT, finecosine[ang]); - target->vel.y += FixedMul (10*FRACUNIT, finesine[ang]); + target->Thrust(ang, 10); if (!(target->flags & MF_NOGRAVITY)) { - target->vel.z += 5*FRACUNIT; + target->Vel.Z += 5.; } } else { - target->vel.x += FixedMul (thrust, finecosine[ang]); - target->vel.y += FixedMul (thrust, finesine[ang]); + target->Thrust(ang, thrust); } } } @@ -1223,7 +1210,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, //Use the original damage to check for telefrag amount. Don't let the now-amplified damagetypes do it. if (rawdamage < TELEFRAG_DAMAGE || (target->flags7 & MF7_LAXTELEFRAGDMG)) { // Still allow telefragging :-( - damage = (int)((float)damage * level.teamdamage); + damage = (int)(damage * level.teamdamage); if (damage < 0) { return damage; @@ -1674,7 +1661,7 @@ bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poi } if (source != NULL && source->player != player && player->mo->IsTeammate (source)) { - poison = (int)((float)poison * level.teamdamage); + poison = (int)(poison * level.teamdamage); } if (poison > 0) { @@ -1723,18 +1710,15 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, return; } // Take half damage in trainer mode - damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor)); + damage = int(damage * G_SkillProperty(SKILLP_DamageFactor)); // Handle passive damage modifiers (e.g. PowerProtection) if (target->Inventory != NULL) { target->Inventory->ModifyDamage(damage, player->poisontype, damage, true); } // Modify with damage factors - damage = FixedMul(damage, target->DamageFactor); - if (damage > 0) - { - damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, player->poisontype, target->GetClass()->DamageFactors); - } + damage = target->ApplyDamageFactor(player->poisontype, damage); + if (damage <= 0) { // Damage was reduced to 0, so don't bother further. return; diff --git a/src/p_lights.cpp b/src/p_lights.cpp index c9e85b800..bd2535c81 100644 --- a/src/p_lights.cpp +++ b/src/p_lights.cpp @@ -474,9 +474,9 @@ void EV_LightTurnOn (int tag, int bright) // //----------------------------------------------------------------------------- -void EV_LightTurnOnPartway (int tag, fixed_t frac) +void EV_LightTurnOnPartway (int tag, double frac) { - frac = clamp (frac, 0, FRACUNIT); + frac = clamp(frac, 0., 1.); // Search all sectors for ones with same tag as activating line int secnum; @@ -500,7 +500,7 @@ void EV_LightTurnOnPartway (int tag, fixed_t frac) } } } - sector->SetLightLevel(DMulScale16 (frac, bright, FRACUNIT-frac, min)); + sector->SetLightLevel(int(frac * bright + (1 - frac) * min)); } } diff --git a/src/p_linkedsectors.cpp b/src/p_linkedsectors.cpp index 9c67b6279..9a451460c 100644 --- a/src/p_linkedsectors.cpp +++ b/src/p_linkedsectors.cpp @@ -93,7 +93,7 @@ bool sector_t::IsLinked(sector_t *other, bool ceiling) const // //============================================================================ -static bool MoveCeiling(sector_t *sector, int crush, fixed_t move) +static bool MoveCeiling(sector_t *sector, int crush, double move) { sector->ceilingplane.ChangeHeight (move); sector->ChangePlaneTexZ(sector_t::ceiling, move); @@ -101,14 +101,13 @@ static bool MoveCeiling(sector_t *sector, int crush, fixed_t move) if (P_ChangeSector(sector, crush, move, 1, true)) return false; // Don't let the ceiling go below the floor - if ((sector->ceilingplane.a | sector->ceilingplane.b | - sector->floorplane.a | sector->floorplane.b) == 0 && - sector->GetPlaneTexZ(sector_t::floor) > sector->GetPlaneTexZ(sector_t::ceiling)) return false; + if (!sector->ceilingplane.isSlope() && !sector->floorplane.isSlope() && + sector->GetPlaneTexZF(sector_t::floor) > sector->GetPlaneTexZF(sector_t::ceiling)) return false; return true; } -static bool MoveFloor(sector_t *sector, int crush, fixed_t move) +static bool MoveFloor(sector_t *sector, int crush, double move) { sector->floorplane.ChangeHeight (move); sector->ChangePlaneTexZ(sector_t::floor, move); @@ -116,9 +115,8 @@ static bool MoveFloor(sector_t *sector, int crush, fixed_t move) if (P_ChangeSector(sector, crush, move, 0, true)) return false; // Don't let the floor go above the ceiling - if ((sector->ceilingplane.a | sector->ceilingplane.b | - sector->floorplane.a | sector->floorplane.b) == 0 && - sector->GetPlaneTexZ(sector_t::floor) > sector->GetPlaneTexZ(sector_t::ceiling)) return false; + if (!sector->ceilingplane.isSlope() && !sector->floorplane.isSlope() && + sector->GetPlaneTexZF(sector_t::floor) > sector->GetPlaneTexZF(sector_t::ceiling)) return false; return true; } @@ -133,7 +131,7 @@ static bool MoveFloor(sector_t *sector, int crush, fixed_t move) // //============================================================================ -bool P_MoveLinkedSectors(sector_t *sector, int crush, fixed_t move, bool ceiling) +bool P_MoveLinkedSectors(sector_t *sector, int crush, double move, bool ceiling) { extsector_t::linked::plane &scrollplane = ceiling? sector->e->Linked.Ceiling : sector->e->Linked.Floor; bool ok = true; diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 849295c2c..2d6670b56 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -79,10 +79,10 @@ static const BYTE ChangeMap[8] = { 0, 1, 5, 3, 7, 2, 6, 0 }; #define FUNC(a) static int a (line_t *ln, AActor *it, bool backSide, \ int arg0, int arg1, int arg2, int arg3, int arg4) -#define SPEED(a) ((a)*(FRACUNIT/8)) +#define SPEED(a) ((a) / 8.) #define TICS(a) (((a)*TICRATE)/35) #define OCTICS(a) (((a)*TICRATE)/8) -#define BYTEANGLE(a) ((angle_t)((a)<<24)) +#define BYTEANGLE(a) ((a) * (360./256.)) #define CRUSH(a) ((a) > 0? (a) : -1) #define CHANGE(a) (((a) >= 0 && (a)<=7)? ChangeMap[a]:0) @@ -158,19 +158,19 @@ FUNC(LS_Polyobj_RotateRight) FUNC(LS_Polyobj_Move) // Polyobj_Move (po, speed, angle, distance) { - return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * FRACUNIT, false); + return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3, false); } FUNC(LS_Polyobj_MoveTimes8) // Polyobj_MoveTimes8 (po, speed, angle, distance) { - return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * FRACUNIT * 8, false); + return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * 8, false); } FUNC(LS_Polyobj_MoveTo) // Polyobj_MoveTo (po, speed, x, y) { - return EV_MovePolyTo (ln, arg0, SPEED(arg1), arg2 << FRACBITS, arg3 << FRACBITS, false); + return EV_MovePolyTo (ln, arg0, SPEED(arg1), DVector2(arg2, arg3), false); } FUNC(LS_Polyobj_MoveToSpot) @@ -179,7 +179,7 @@ FUNC(LS_Polyobj_MoveToSpot) FActorIterator iterator (arg2); AActor *spot = iterator.Next(); if (spot == NULL) return false; - return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->X(), spot->Y(), false); + return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->Pos(), false); } FUNC(LS_Polyobj_DoorSwing) @@ -191,7 +191,7 @@ FUNC(LS_Polyobj_DoorSwing) FUNC(LS_Polyobj_DoorSlide) // Polyobj_DoorSlide (po, speed, angle, distance, delay) { - return EV_OpenPolyDoor (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg4, arg3*FRACUNIT, PODOOR_SLIDE); + return EV_OpenPolyDoor (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg4, arg3, PODOOR_SLIDE); } FUNC(LS_Polyobj_OR_RotateLeft) @@ -209,19 +209,19 @@ FUNC(LS_Polyobj_OR_RotateRight) FUNC(LS_Polyobj_OR_Move) // Polyobj_OR_Move (po, speed, angle, distance) { - return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * FRACUNIT, true); + return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3, true); } FUNC(LS_Polyobj_OR_MoveTimes8) // Polyobj_OR_MoveTimes8 (po, speed, angle, distance) { - return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * FRACUNIT * 8, true); + return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * 8, true); } FUNC(LS_Polyobj_OR_MoveTo) // Polyobj_OR_MoveTo (po, speed, x, y) { - return EV_MovePolyTo (ln, arg0, SPEED(arg1), arg2 << FRACBITS, arg3 << FRACBITS, true); + return EV_MovePolyTo (ln, arg0, SPEED(arg1), DVector2(arg2, arg3), true); } FUNC(LS_Polyobj_OR_MoveToSpot) @@ -230,7 +230,7 @@ FUNC(LS_Polyobj_OR_MoveToSpot) FActorIterator iterator (arg2); AActor *spot = iterator.Next(); if (spot == NULL) return false; - return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->X(), spot->Y(), true); + return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->Pos(), true); } FUNC(LS_Polyobj_Stop) @@ -325,7 +325,7 @@ FUNC(LS_Generic_Door) FUNC(LS_Floor_LowerByValue) // Floor_LowerByValue (tag, speed, height, change) { - return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, -1, CHANGE(arg3), false); + return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), arg2, -1, CHANGE(arg3), false); } FUNC(LS_Floor_LowerToLowest) @@ -337,7 +337,7 @@ FUNC(LS_Floor_LowerToLowest) FUNC(LS_Floor_LowerToHighest) // Floor_LowerToHighest (tag, speed, adjust, hereticlower) { - return EV_DoFloor (DFloor::floorLowerToHighest, ln, arg0, SPEED(arg1), (arg2-128)*FRACUNIT, -1, 0, false, arg3==1); + return EV_DoFloor (DFloor::floorLowerToHighest, ln, arg0, SPEED(arg1), (arg2-128), -1, 0, false, arg3==1); } FUNC(LS_Floor_LowerToHighestEE) @@ -355,7 +355,7 @@ FUNC(LS_Floor_LowerToNearest) FUNC(LS_Floor_RaiseByValue) // Floor_RaiseByValue (tag, speed, height, change, crush) { - return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, CRUSH(arg4), CHANGE(arg3), true); + return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), arg2, CRUSH(arg4), CHANGE(arg3), true); } FUNC(LS_Floor_RaiseToHighest) @@ -374,7 +374,7 @@ FUNC(LS_Floor_RaiseToLowest) // Floor_RaiseToLowest (tag, change, crush) { // This is merely done for completeness as it's a rather pointless addition. - return EV_DoFloor (DFloor::floorRaiseToLowest, ln, arg0, 2*FRACUNIT, 0, CRUSH(arg3), CHANGE(arg2), true); + return EV_DoFloor (DFloor::floorRaiseToLowest, ln, arg0, 2., 0, CRUSH(arg3), CHANGE(arg2), true); } FUNC(LS_Floor_RaiseAndCrush) @@ -392,13 +392,13 @@ FUNC(LS_Floor_RaiseAndCrushDoom) FUNC(LS_Floor_RaiseByValueTimes8) // FLoor_RaiseByValueTimes8 (tag, speed, height, change, crush) { - return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, CRUSH(arg4), CHANGE(arg3), true); + return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), arg2*8, CRUSH(arg4), CHANGE(arg3), true); } FUNC(LS_Floor_LowerByValueTimes8) // Floor_LowerByValueTimes8 (tag, speed, height, change) { - return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, -1, CHANGE(arg3), false); + return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), arg2*8, -1, CHANGE(arg3), false); } FUNC(LS_Floor_CrushStop) @@ -410,13 +410,13 @@ FUNC(LS_Floor_CrushStop) FUNC(LS_Floor_LowerInstant) // Floor_LowerInstant (tag, unused, height, change) { - return EV_DoFloor (DFloor::floorLowerInstant, ln, arg0, 0, arg2*FRACUNIT*8, -1, CHANGE(arg3), false); + return EV_DoFloor (DFloor::floorLowerInstant, ln, arg0, 0., arg2*8, -1, CHANGE(arg3), false); } FUNC(LS_Floor_RaiseInstant) // Floor_RaiseInstant (tag, unused, height, change, crush) { - return EV_DoFloor (DFloor::floorRaiseInstant, ln, arg0, 0, arg2*FRACUNIT*8, CRUSH(arg4), CHANGE(arg3), true); + return EV_DoFloor (DFloor::floorRaiseInstant, ln, arg0, 0., arg2*8, CRUSH(arg4), CHANGE(arg3), true); } FUNC(LS_Floor_ToCeilingInstant) @@ -429,14 +429,14 @@ FUNC(LS_Floor_MoveToValueTimes8) // Floor_MoveToValueTimes8 (tag, speed, height, negative, change) { return EV_DoFloor (DFloor::floorMoveToValue, ln, arg0, SPEED(arg1), - arg2*FRACUNIT*8*(arg3?-1:1), -1, CHANGE(arg4), false); + arg2*8*(arg3?-1:1), -1, CHANGE(arg4), false); } FUNC(LS_Floor_MoveToValue) // Floor_MoveToValue (tag, speed, height, negative, change) { return EV_DoFloor (DFloor::floorMoveToValue, ln, arg0, SPEED(arg1), - arg2*FRACUNIT*(arg3?-1:1), -1, CHANGE(arg4), false); + arg2*(arg3?-1:1), -1, CHANGE(arg4), false); } FUNC(LS_Floor_RaiseToLowestCeiling) @@ -472,13 +472,13 @@ FUNC(LS_Floor_RaiseToCeiling) FUNC(LS_Floor_RaiseByValueTxTy) // Floor_RaiseByValueTxTy (tag, speed, height) { - return EV_DoFloor (DFloor::floorRaiseAndChange, ln, arg0, SPEED(arg1), arg2*FRACUNIT, -1, 0, false); + return EV_DoFloor (DFloor::floorRaiseAndChange, ln, arg0, SPEED(arg1), arg2, -1, 0, false); } FUNC(LS_Floor_LowerToLowestTxTy) // Floor_LowerToLowestTxTy (tag, speed) { - return EV_DoFloor (DFloor::floorLowerAndChange, ln, arg0, SPEED(arg1), arg2*FRACUNIT, -1, 0, false); + return EV_DoFloor (DFloor::floorLowerAndChange, ln, arg0, SPEED(arg1), arg2, -1, 0, false); } FUNC(LS_Floor_Waggle) @@ -543,7 +543,7 @@ FUNC(LS_Generic_Floor) } } - return EV_DoFloor (type, ln, arg0, SPEED(arg1), arg2*FRACUNIT, + return EV_DoFloor (type, ln, arg0, SPEED(arg1), arg2, (arg4 & 16) ? 20 : -1, arg4 & 7, false); } @@ -552,56 +552,56 @@ FUNC(LS_Stairs_BuildDown) // Stair_BuildDown (tag, speed, height, delay, reset) { return EV_BuildStairs (arg0, DFloor::buildDown, ln, - arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, DFloor::stairUseSpecials); + arg2, SPEED(arg1), TICS(arg3), arg4, 0, DFloor::stairUseSpecials); } FUNC(LS_Stairs_BuildUp) // Stairs_BuildUp (tag, speed, height, delay, reset) { return EV_BuildStairs (arg0, DFloor::buildUp, ln, - arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, DFloor::stairUseSpecials); + arg2, SPEED(arg1), TICS(arg3), arg4, 0, DFloor::stairUseSpecials); } FUNC(LS_Stairs_BuildDownSync) // Stairs_BuildDownSync (tag, speed, height, reset) { return EV_BuildStairs (arg0, DFloor::buildDown, ln, - arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, DFloor::stairUseSpecials|DFloor::stairSync); + arg2, SPEED(arg1), 0, arg3, 0, DFloor::stairUseSpecials|DFloor::stairSync); } FUNC(LS_Stairs_BuildUpSync) // Stairs_BuildUpSync (tag, speed, height, reset) { return EV_BuildStairs (arg0, DFloor::buildUp, ln, - arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, DFloor::stairUseSpecials|DFloor::stairSync); + arg2, SPEED(arg1), 0, arg3, 0, DFloor::stairUseSpecials|DFloor::stairSync); } FUNC(LS_Stairs_BuildUpDoom) // Stairs_BuildUpDoom (tag, speed, height, delay, reset) { return EV_BuildStairs (arg0, DFloor::buildUp, ln, - arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, 0); + arg2, SPEED(arg1), TICS(arg3), arg4, 0, 0); } FUNC(LS_Stairs_BuildDownDoom) // Stair_BuildDownDoom (tag, speed, height, delay, reset) { return EV_BuildStairs (arg0, DFloor::buildDown, ln, - arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, 0); + arg2, SPEED(arg1), TICS(arg3), arg4, 0, 0); } FUNC(LS_Stairs_BuildDownDoomSync) // Stairs_BuildDownDoomSync (tag, speed, height, reset) { return EV_BuildStairs (arg0, DFloor::buildDown, ln, - arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, DFloor::stairSync); + arg2, SPEED(arg1), 0, arg3, 0, DFloor::stairSync); } FUNC(LS_Stairs_BuildUpDoomSync) // Stairs_BuildUpDoomSync (tag, speed, height, reset) { return EV_BuildStairs (arg0, DFloor::buildUp, ln, - arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, DFloor::stairSync); + arg2, SPEED(arg1), 0, arg3, 0, DFloor::stairSync); } @@ -610,7 +610,7 @@ FUNC(LS_Generic_Stairs) { DFloor::EStair type = (arg3 & 1) ? DFloor::buildUp : DFloor::buildDown; bool res = EV_BuildStairs (arg0, type, ln, - arg2 * FRACUNIT, SPEED(arg1), 0, arg4, arg3 & 2, 0); + arg2, SPEED(arg1), 0, arg4, arg3 & 2, 0); if (res && ln && (ln->flags & ML_REPEAT_SPECIAL) && ln->special == Generic_Stairs) // Toggle direction of next activation of repeatable stairs @@ -622,61 +622,61 @@ FUNC(LS_Generic_Stairs) FUNC(LS_Pillar_Build) // Pillar_Build (tag, speed, height) { - return EV_DoPillar (DPillar::pillarBuild, ln, arg0, SPEED(arg1), arg2*FRACUNIT, 0, -1, false); + return EV_DoPillar (DPillar::pillarBuild, ln, arg0, SPEED(arg1), arg2, 0, -1, false); } FUNC(LS_Pillar_BuildAndCrush) // Pillar_BuildAndCrush (tag, speed, height, crush, crushtype) { - return EV_DoPillar (DPillar::pillarBuild, ln, arg0, SPEED(arg1), arg2*FRACUNIT, 0, arg3, CRUSHTYPE(arg4)); + return EV_DoPillar (DPillar::pillarBuild, ln, arg0, SPEED(arg1), arg2, 0, arg3, CRUSHTYPE(arg4)); } FUNC(LS_Pillar_Open) // Pillar_Open (tag, speed, f_height, c_height) { - return EV_DoPillar (DPillar::pillarOpen, ln, arg0, SPEED(arg1), arg2*FRACUNIT, arg3*FRACUNIT, -1, false); + return EV_DoPillar (DPillar::pillarOpen, ln, arg0, SPEED(arg1), arg2, arg3, -1, false); } FUNC(LS_Ceiling_LowerByValue) // Ceiling_LowerByValue (tag, speed, height, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, CRUSH(arg4), 0, CHANGE(arg3)); + return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2, CRUSH(arg4), 0, CHANGE(arg3)); } FUNC(LS_Ceiling_RaiseByValue) // Ceiling_RaiseByValue (tag, speed, height, change) { - return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, CRUSH(arg4), 0, CHANGE(arg3)); + return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2, CRUSH(arg4), 0, CHANGE(arg3)); } FUNC(LS_Ceiling_LowerByValueTimes8) // Ceiling_LowerByValueTimes8 (tag, speed, height, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3)); + return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*8, -1, 0, CHANGE(arg3)); } FUNC(LS_Ceiling_RaiseByValueTimes8) // Ceiling_RaiseByValueTimes8 (tag, speed, height, change) { - return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3)); + return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*8, -1, 0, CHANGE(arg3)); } FUNC(LS_Ceiling_CrushAndRaise) // Ceiling_CrushAndRaise (tag, speed, crush, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg1)/2, 8*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg3, false)); + return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg1)/2, 8, arg2, 0, 0, CRUSHTYPE(arg3, false)); } FUNC(LS_Ceiling_LowerAndCrush) // Ceiling_LowerAndCrush (tag, speed, crush, crushtype) { - return EV_DoCeiling (DCeiling::ceilLowerAndCrush, ln, arg0, SPEED(arg1), SPEED(arg1), 8*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg3, arg1 == 8)); + return EV_DoCeiling (DCeiling::ceilLowerAndCrush, ln, arg0, SPEED(arg1), SPEED(arg1), 8, arg2, 0, 0, CRUSHTYPE(arg3, arg1 == 8)); } FUNC(LS_Ceiling_LowerAndCrushDist) // Ceiling_LowerAndCrush (tag, speed, crush, dist, crushtype) { - return EV_DoCeiling (DCeiling::ceilLowerAndCrush, ln, arg0, SPEED(arg1), SPEED(arg1), arg3*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg4, arg1 == 8)); + return EV_DoCeiling (DCeiling::ceilLowerAndCrush, ln, arg0, SPEED(arg1), SPEED(arg1), arg3, arg2, 0, 0, CRUSHTYPE(arg4, arg1 == 8)); } FUNC(LS_Ceiling_CrushStop) @@ -688,21 +688,21 @@ FUNC(LS_Ceiling_CrushStop) FUNC(LS_Ceiling_CrushRaiseAndStay) // Ceiling_CrushRaiseAndStay (tag, speed, crush, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushRaiseAndStay, ln, arg0, SPEED(arg1), SPEED(arg1)/2, 8*FRACUNIT, arg2, 0, 0, CRUSHTYPE(arg3, false)); + return EV_DoCeiling (DCeiling::ceilCrushRaiseAndStay, ln, arg0, SPEED(arg1), SPEED(arg1)/2, 8, arg2, 0, 0, CRUSHTYPE(arg3, false)); } FUNC(LS_Ceiling_MoveToValueTimes8) // Ceiling_MoveToValueTimes8 (tag, speed, height, negative, change) { return EV_DoCeiling (DCeiling::ceilMoveToValue, ln, arg0, SPEED(arg1), 0, - arg2*FRACUNIT*8*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4)); + arg2*8*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4)); } FUNC(LS_Ceiling_MoveToValue) // Ceiling_MoveToValue (tag, speed, height, negative, change) { return EV_DoCeiling (DCeiling::ceilMoveToValue, ln, arg0, SPEED(arg1), 0, - arg2*FRACUNIT*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4)); + arg2*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4)); } FUNC(LS_Ceiling_LowerToHighestFloor) @@ -714,13 +714,13 @@ FUNC(LS_Ceiling_LowerToHighestFloor) FUNC(LS_Ceiling_LowerInstant) // Ceiling_LowerInstant (tag, unused, height, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, CRUSH(arg4), 0, CHANGE(arg3)); + return EV_DoCeiling (DCeiling::ceilLowerInstant, ln, arg0, 0, 0, arg2*8, CRUSH(arg4), 0, CHANGE(arg3)); } FUNC(LS_Ceiling_RaiseInstant) // Ceiling_RaiseInstant (tag, unused, height, change) { - return EV_DoCeiling (DCeiling::ceilRaiseInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3)); + return EV_DoCeiling (DCeiling::ceilRaiseInstant, ln, arg0, 0, 0, arg2*8, -1, 0, CHANGE(arg3)); } FUNC(LS_Ceiling_CrushRaiseAndStayA) @@ -744,7 +744,7 @@ FUNC(LS_Ceiling_CrushAndRaiseA) FUNC(LS_Ceiling_CrushAndRaiseDist) // Ceiling_CrushAndRaiseDist (tag, dist, speed, damage, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 0, 0, CRUSHTYPE(arg4, arg2 == 8)); + return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1, arg3, 0, 0, CRUSHTYPE(arg4, arg2 == 8)); } FUNC(LS_Ceiling_CrushAndRaiseSilentA) @@ -756,7 +756,7 @@ FUNC(LS_Ceiling_CrushAndRaiseSilentA) FUNC(LS_Ceiling_CrushAndRaiseSilentDist) // Ceiling_CrushAndRaiseSilentDist (tag, dist, upspeed, damage, crushtype) { - return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 1, 0, CRUSHTYPE(arg4, arg2 == 8)); + return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg2), SPEED(arg2), arg1, arg3, 1, 0, CRUSHTYPE(arg4, arg2 == 8)); } FUNC(LS_Ceiling_RaiseToNearest) @@ -804,13 +804,13 @@ FUNC(LS_Ceiling_LowerToNearest) FUNC(LS_Ceiling_ToHighestInstant) // Ceiling_ToHighestInstant (tag, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerToHighest, ln, arg0, FRACUNIT*2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1)); + return EV_DoCeiling (DCeiling::ceilLowerToHighest, ln, arg0, 2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1)); } FUNC(LS_Ceiling_ToFloorInstant) // Ceiling_ToFloorInstant (tag, change, crush) { - return EV_DoCeiling (DCeiling::ceilRaiseToFloor, ln, arg0, FRACUNIT*2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1)); + return EV_DoCeiling (DCeiling::ceilRaiseToFloor, ln, arg0, 2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1)); } FUNC(LS_Ceiling_LowerToFloor) @@ -852,7 +852,7 @@ FUNC(LS_Generic_Ceiling) } } - return EV_DoCeiling (type, ln, arg0, SPEED(arg1), SPEED(arg1), arg2*FRACUNIT, + return EV_DoCeiling (type, ln, arg0, SPEED(arg1), SPEED(arg1), arg2, (arg4 & 16) ? 20 : -1, 0, arg4 & 7); } @@ -907,13 +907,13 @@ FUNC(LS_Plat_DownWaitUpStayLip) FUNC(LS_Plat_DownByValue) // Plat_DownByValue (tag, speed, delay, height) { - return EV_DoPlat (arg0, ln, DPlat::platDownByValue, FRACUNIT*arg3*8, SPEED(arg1), TICS(arg2), 0, 0); + return EV_DoPlat (arg0, ln, DPlat::platDownByValue, arg3*8, SPEED(arg1), TICS(arg2), 0, 0); } FUNC(LS_Plat_UpByValue) // Plat_UpByValue (tag, speed, delay, height) { - return EV_DoPlat (arg0, ln, DPlat::platUpByValue, FRACUNIT*arg3*8, SPEED(arg1), TICS(arg2), 0, 0); + return EV_DoPlat (arg0, ln, DPlat::platUpByValue, arg3*8, SPEED(arg1), TICS(arg2), 0, 0); } FUNC(LS_Plat_UpWaitDownStay) @@ -953,7 +953,7 @@ FUNC(LS_Plat_RaiseAndStayTx0) FUNC(LS_Plat_UpByValueStayTx) // Plat_UpByValueStayTx (tag, speed, height) { - return EV_DoPlat (arg0, ln, DPlat::platUpByValueStay, FRACUNIT*arg2*8, SPEED(arg1), 0, 0, 2); + return EV_DoPlat (arg0, ln, DPlat::platUpByValueStay, arg2*8, SPEED(arg1), 0, 0, 2); } FUNC(LS_Plat_ToggleCeiling) @@ -986,7 +986,7 @@ FUNC(LS_Generic_Lift) break; } - return EV_DoPlat (arg0, ln, type, arg4*8*FRACUNIT, SPEED(arg1), OCTICS(arg2), 0, 0); + return EV_DoPlat (arg0, ln, type, arg4*8, SPEED(arg1), OCTICS(arg2), 0, 0); } FUNC(LS_Exit_Normal) @@ -1112,7 +1112,16 @@ FUNC(LS_Teleport_Line) return EV_SilentLineTeleport (ln, backSide, it, arg1, arg2); } -static void ThrustThingHelper (AActor *it, angle_t angle, int force, INTBOOL nolimit); +static void ThrustThingHelper(AActor *it, DAngle angle, double force, INTBOOL nolimit) +{ + it->VelFromAngle(angle, force); + if (!nolimit) + { + it->Vel.X = clamp(it->Vel.X, -MAXMOVE, MAXMOVE); + it->Vel.Y = clamp(it->Vel.Y, -MAXMOVE, MAXMOVE); + } +} + FUNC(LS_ThrustThing) // ThrustThing (angle, force, nolimit, tid) { @@ -1137,23 +1146,11 @@ FUNC(LS_ThrustThing) return false; } -static void ThrustThingHelper (AActor *it, angle_t angle, int force, INTBOOL nolimit) -{ - angle >>= ANGLETOFINESHIFT; - it->vel.x += force * finecosine[angle]; - it->vel.y += force * finesine[angle]; - if (!nolimit) - { - it->vel.x = clamp (it->vel.x, -MAXMOVE, MAXMOVE); - it->vel.y = clamp (it->vel.y, -MAXMOVE, MAXMOVE); - } -} - FUNC(LS_ThrustThingZ) // [BC] // ThrustThingZ (tid, zthrust, down/up, set) { AActor *victim; - fixed_t thrust = arg1*FRACUNIT/4; + double thrust = arg1/4.; // [BC] Up is default if (arg2) @@ -1166,18 +1163,18 @@ FUNC(LS_ThrustThingZ) // [BC] while ( (victim = iterator.Next ()) ) { if (!arg3) - victim->vel.z = thrust; + victim->Vel.Z = thrust; else - victim->vel.z += thrust; + victim->Vel.Z += thrust; } return true; } else if (it) { if (!arg3) - it->vel.z = thrust; + it->Vel.Z = thrust; else - it->vel.z += thrust; + it->Vel.Z += thrust; return true; } return false; @@ -1471,15 +1468,15 @@ FUNC(LS_Thing_Damage) FUNC(LS_Thing_Projectile) // Thing_Projectile (tid, type, angle, speed, vspeed) { - return P_Thing_Projectile (arg0, it, arg1, NULL, BYTEANGLE(arg2), arg3<<(FRACBITS-3), - arg4<<(FRACBITS-3), 0, NULL, 0, 0, false); + return P_Thing_Projectile (arg0, it, arg1, NULL, BYTEANGLE(arg2), SPEED(arg3), + SPEED(arg4), 0, NULL, 0, 0, false); } FUNC(LS_Thing_ProjectileGravity) // Thing_ProjectileGravity (tid, type, angle, speed, vspeed) { - return P_Thing_Projectile (arg0, it, arg1, NULL, BYTEANGLE(arg2), arg3<<(FRACBITS-3), - arg4<<(FRACBITS-3), 0, NULL, 1, 0, false); + return P_Thing_Projectile (arg0, it, arg1, NULL, BYTEANGLE(arg2), SPEED(arg3), + SPEED(arg4), 0, NULL, 1, 0, false); } FUNC(LS_Thing_Hate) @@ -1648,13 +1645,13 @@ FUNC(LS_Thing_Hate) FUNC(LS_Thing_ProjectileAimed) // Thing_ProjectileAimed (tid, type, speed, target, newtid) { - return P_Thing_Projectile (arg0, it, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, false); + return P_Thing_Projectile (arg0, it, arg1, NULL, 0., SPEED(arg2), 0, arg3, it, 0, arg4, false); } FUNC(LS_Thing_ProjectileIntercept) // Thing_ProjectileIntercept (tid, type, speed, target, newtid) { - return P_Thing_Projectile (arg0, it, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, true); + return P_Thing_Projectile (arg0, it, arg1, NULL, 0., SPEED(arg2), 0, arg3, it, 0, arg4, true); } // [BC] added newtid for next two @@ -1673,7 +1670,7 @@ FUNC(LS_Thing_SpawnNoFog) FUNC(LS_Thing_SpawnFacing) // Thing_SpawnFacing (tid, type, nofog, newtid) { - return P_Thing_Spawn (arg0, it, arg1, ANGLE_MAX, arg2 ? false : true, arg3); + return P_Thing_Spawn (arg0, it, arg1, 1000000., arg2 ? false : true, arg3); } FUNC(LS_Thing_Raise) @@ -1708,8 +1705,8 @@ FUNC(LS_Thing_Stop) { if (it != NULL) { - it->vel.x = it->vel.y = it->vel.z = 0; - if (it->player != NULL) it->player->vel.x = it->player->vel.y = 0; + it->Vel.Zero(); + if (it->player != NULL) it->player->Vel.Zero(); ok = true; } } @@ -1719,8 +1716,8 @@ FUNC(LS_Thing_Stop) while ( (target = iterator.Next ()) ) { - target->vel.x = target->vel.y = target->vel.z = 0; - if (target->player != NULL) target->player->vel.x = target->player->vel.y = 0; + target->Vel.Zero(); + if (target->player != NULL) target->player->Vel.Zero(); ok = true; } } @@ -1944,13 +1941,13 @@ FUNC(LS_FS_Execute) FUNC(LS_FloorAndCeiling_LowerByValue) // FloorAndCeiling_LowerByValue (tag, speed, height) { - return EV_DoElevator (ln, DElevator::elevateLower, SPEED(arg1), arg2*FRACUNIT, arg0); + return EV_DoElevator (ln, DElevator::elevateLower, SPEED(arg1), arg2, arg0); } FUNC(LS_FloorAndCeiling_RaiseByValue) // FloorAndCeiling_RaiseByValue (tag, speed, height) { - return EV_DoElevator (ln, DElevator::elevateRaise, SPEED(arg1), arg2*FRACUNIT, arg0); + return EV_DoElevator (ln, DElevator::elevateRaise, SPEED(arg1), arg2, arg0); } FUNC(LS_FloorAndCeiling_LowerRaise) @@ -2185,7 +2182,7 @@ FUNC(LS_Sector_SetTranslucent) FSectorTagIterator itr(arg0); while ((secnum = itr.Next()) >= 0) { - sectors[secnum].SetAlpha(arg1, Scale(arg2, OPAQUE, 255)); + sectors[secnum].SetAlpha(arg1, clamp(arg2, 0, 255) / 255.); sectors[secnum].ChangeFlags(arg1, ~PLANEF_ADDITIVE, arg3? PLANEF_ADDITIVE:0); } return true; @@ -2207,8 +2204,8 @@ FUNC(LS_Sector_SetLink) return false; } -void SetWallScroller(int id, int sidechoice, fixed_t dx, fixed_t dy, EScrollPos Where); -void SetScroller(int tag, EScroll type, fixed_t dx, fixed_t dy); +void SetWallScroller(int id, int sidechoice, double dx, double dy, EScrollPos Where); +void SetScroller(int tag, EScroll type, double dx, double dy); FUNC(LS_Scroll_Texture_Both) @@ -2217,8 +2214,8 @@ FUNC(LS_Scroll_Texture_Both) if (arg0 == 0) return false; - fixed_t dx = (arg1 - arg2) * (FRACUNIT/64); - fixed_t dy = (arg4 - arg3) * (FRACUNIT/64); + double dx = (arg1 - arg2) / 64.; + double dy = (arg4 - arg3) / 64.; int sidechoice; if (arg0 < 0) @@ -2242,7 +2239,7 @@ FUNC(LS_Scroll_Wall) if (arg0 == 0) return false; - SetWallScroller (arg0, !!arg3, arg1, arg2, EScrollPos(arg4)); + SetWallScroller (arg0, !!arg3, arg1 / 65536., arg2 / 65536., EScrollPos(arg4)); return true; } @@ -2253,8 +2250,8 @@ FUNC(LS_Scroll_Wall) FUNC(LS_Scroll_Floor) // Scroll_Floor (tag, x-move, y-move, s/c) { - fixed_t dx = arg1 * FRACUNIT/32; - fixed_t dy = arg2 * FRACUNIT/32; + double dx = arg1 / 32.; + double dy = arg2 / 32.; if (arg3 == 0 || arg3 == 2) { @@ -2278,8 +2275,8 @@ FUNC(LS_Scroll_Floor) FUNC(LS_Scroll_Ceiling) // Scroll_Ceiling (tag, x-move, y-move, 0) { - fixed_t dx = arg1 * FRACUNIT/32; - fixed_t dy = arg2 * FRACUNIT/32; + double dx = arg1 / 32.; + double dy = arg2 / 32.; SetScroller (arg0, EScroll::sc_ceiling, -dx, dy); return true; @@ -2332,11 +2329,11 @@ FUNC(LS_Sector_SetDamage) FUNC(LS_Sector_SetGravity) // Sector_SetGravity (tag, intpart, fracpart) { - float gravity; + double gravity; if (arg2 > 99) arg2 = 99; - gravity = (float)arg1 + (float)arg2 * 0.01f; + gravity = (double)arg1 + (double)arg2 * 0.01; FSectorTagIterator itr(arg0); int secnum; @@ -2374,8 +2371,8 @@ FUNC(LS_Sector_SetFade) FUNC(LS_Sector_SetCeilingPanning) // Sector_SetCeilingPanning (tag, x-int, x-frac, y-int, y-frac) { - fixed_t xofs = arg1 * FRACUNIT + arg2 * (FRACUNIT/100); - fixed_t yofs = arg3 * FRACUNIT + arg4 * (FRACUNIT/100); + double xofs = arg1 + arg2 / 100.; + double yofs = arg3 + arg4 / 100.; FSectorTagIterator itr(arg0); int secnum; @@ -2390,8 +2387,8 @@ FUNC(LS_Sector_SetCeilingPanning) FUNC(LS_Sector_SetFloorPanning) // Sector_SetFloorPanning (tag, x-int, x-frac, y-int, y-frac) { - fixed_t xofs = arg1 * FRACUNIT + arg2 * (FRACUNIT/100); - fixed_t yofs = arg3 * FRACUNIT + arg4 * (FRACUNIT/100); + double xofs = arg1 + arg2 / 100.; + double yofs = arg3 + arg4 / 100.; FSectorTagIterator itr(arg0); int secnum; @@ -2406,13 +2403,13 @@ FUNC(LS_Sector_SetFloorPanning) FUNC(LS_Sector_SetFloorScale) // Sector_SetFloorScale (tag, x-int, x-frac, y-int, y-frac) { - fixed_t xscale = arg1 * FRACUNIT + arg2 * (FRACUNIT/100); - fixed_t yscale = arg3 * FRACUNIT + arg4 * (FRACUNIT/100); + double xscale = arg1 + arg2 / 100.; + double yscale = arg3 + arg4 / 100.; if (xscale) - xscale = FixedDiv (FRACUNIT, xscale); + xscale = 1. / xscale; if (yscale) - yscale = FixedDiv (FRACUNIT, yscale); + yscale = 1. / yscale; FSectorTagIterator itr(arg0); int secnum; @@ -2429,13 +2426,13 @@ FUNC(LS_Sector_SetFloorScale) FUNC(LS_Sector_SetCeilingScale) // Sector_SetCeilingScale (tag, x-int, x-frac, y-int, y-frac) { - fixed_t xscale = arg1 * FRACUNIT + arg2 * (FRACUNIT/100); - fixed_t yscale = arg3 * FRACUNIT + arg4 * (FRACUNIT/100); + double xscale = arg1 + arg2 / 100.; + double yscale = arg3 + arg4 / 100.; if (xscale) - xscale = FixedDiv (FRACUNIT, xscale); + xscale = 1. / xscale; if (yscale) - yscale = FixedDiv (FRACUNIT, yscale); + yscale = 1. / yscale; FSectorTagIterator itr(arg0); int secnum; @@ -2452,19 +2449,21 @@ FUNC(LS_Sector_SetCeilingScale) FUNC(LS_Sector_SetFloorScale2) // Sector_SetFloorScale2 (tag, x-factor, y-factor) { - if (arg1) - arg1 = FixedDiv (FRACUNIT, arg1); - if (arg2) - arg2 = FixedDiv (FRACUNIT, arg2); + double xscale = arg1 / 65536., yscale = arg2 / 65536.; + + if (xscale) + xscale = 1. / xscale; + if (yscale) + yscale = 1. / yscale; FSectorTagIterator itr(arg0); int secnum; while ((secnum = itr.Next()) >= 0) { if (arg1) - sectors[secnum].SetXScale(sector_t::floor, arg1); + sectors[secnum].SetXScale(sector_t::floor, xscale); if (arg2) - sectors[secnum].SetYScale(sector_t::floor, arg2); + sectors[secnum].SetYScale(sector_t::floor, yscale); } return true; } @@ -2472,19 +2471,21 @@ FUNC(LS_Sector_SetFloorScale2) FUNC(LS_Sector_SetCeilingScale2) // Sector_SetFloorScale2 (tag, x-factor, y-factor) { - if (arg1) - arg1 = FixedDiv (FRACUNIT, arg1); - if (arg2) - arg2 = FixedDiv (FRACUNIT, arg2); + double xscale = arg1 / 65536., yscale = arg2 / 65536.; + + if (xscale) + xscale = 1. / xscale; + if (yscale) + yscale = 1. / yscale; FSectorTagIterator itr(arg0); int secnum; while ((secnum = itr.Next()) >= 0) { if (arg1) - sectors[secnum].SetXScale(sector_t::ceiling, arg1); + sectors[secnum].SetXScale(sector_t::ceiling, xscale); if (arg2) - sectors[secnum].SetYScale(sector_t::ceiling, arg2); + sectors[secnum].SetYScale(sector_t::ceiling, yscale); } return true; } @@ -2492,8 +2493,8 @@ FUNC(LS_Sector_SetCeilingScale2) FUNC(LS_Sector_SetRotation) // Sector_SetRotation (tag, floor-angle, ceiling-angle) { - angle_t ceiling = arg2 * ANGLE_1; - angle_t floor = arg1 * ANGLE_1; + DAngle ceiling = (double)arg2; + DAngle floor = (double)arg1; FSectorTagIterator itr(arg0); int secnum; @@ -2536,7 +2537,9 @@ FUNC(LS_Line_AlignFloor) FUNC(LS_Line_SetTextureOffset) // Line_SetTextureOffset (id, x, y, side, flags) { - const fixed_t NO_CHANGE = 32767< 1) return false; @@ -2554,15 +2557,15 @@ FUNC(LS_Line_SetTextureOffset) // set if (arg1 != NO_CHANGE) { - if (arg4&1) side->SetTextureXOffset(side_t::top, arg1); - if (arg4&2) side->SetTextureXOffset(side_t::mid, arg1); - if (arg4&4) side->SetTextureXOffset(side_t::bottom, arg1); + if (arg4&1) side->SetTextureXOffset(side_t::top, farg1); + if (arg4&2) side->SetTextureXOffset(side_t::mid, farg1); + if (arg4&4) side->SetTextureXOffset(side_t::bottom, farg1); } if (arg2 != NO_CHANGE) { - if (arg4&1) side->SetTextureYOffset(side_t::top, arg2); - if (arg4&2) side->SetTextureYOffset(side_t::mid, arg2); - if (arg4&4) side->SetTextureYOffset(side_t::bottom, arg2); + if (arg4&1) side->SetTextureYOffset(side_t::top, farg2); + if (arg4&2) side->SetTextureYOffset(side_t::mid, farg2); + if (arg4&4) side->SetTextureYOffset(side_t::bottom, farg2); } } else @@ -2570,15 +2573,15 @@ FUNC(LS_Line_SetTextureOffset) // add if (arg1 != NO_CHANGE) { - if (arg4&1) side->AddTextureXOffset(side_t::top, arg1); - if (arg4&2) side->AddTextureXOffset(side_t::mid, arg1); - if (arg4&4) side->AddTextureXOffset(side_t::bottom, arg1); + if (arg4&1) side->AddTextureXOffset(side_t::top, farg1); + if (arg4&2) side->AddTextureXOffset(side_t::mid, farg1); + if (arg4&4) side->AddTextureXOffset(side_t::bottom, farg1); } if (arg2 != NO_CHANGE) { - if (arg4&1) side->AddTextureYOffset(side_t::top, arg2); - if (arg4&2) side->AddTextureYOffset(side_t::mid, arg2); - if (arg4&4) side->AddTextureYOffset(side_t::bottom, arg2); + if (arg4&1) side->AddTextureYOffset(side_t::top, farg2); + if (arg4&2) side->AddTextureYOffset(side_t::mid, farg2); + if (arg4&4) side->AddTextureYOffset(side_t::bottom, farg2); } } } @@ -2589,7 +2592,9 @@ FUNC(LS_Line_SetTextureOffset) FUNC(LS_Line_SetTextureScale) // Line_SetTextureScale (id, x, y, side, flags) { - const fixed_t NO_CHANGE = 32767< 1) return false; @@ -2606,15 +2611,15 @@ FUNC(LS_Line_SetTextureScale) // set if (arg1 != NO_CHANGE) { - if (arg4&1) side->SetTextureXScale(side_t::top, arg1); - if (arg4&2) side->SetTextureXScale(side_t::mid, arg1); - if (arg4&4) side->SetTextureXScale(side_t::bottom, arg1); + if (arg4&1) side->SetTextureXScale(side_t::top, farg1); + if (arg4&2) side->SetTextureXScale(side_t::mid, farg1); + if (arg4&4) side->SetTextureXScale(side_t::bottom, farg1); } if (arg2 != NO_CHANGE) { - if (arg4&1) side->SetTextureYScale(side_t::top, arg2); - if (arg4&2) side->SetTextureYScale(side_t::mid, arg2); - if (arg4&4) side->SetTextureYScale(side_t::bottom, arg2); + if (arg4&1) side->SetTextureYScale(side_t::top, farg2); + if (arg4&2) side->SetTextureYScale(side_t::mid, farg2); + if (arg4&4) side->SetTextureYScale(side_t::bottom, farg2); } } else @@ -2622,15 +2627,15 @@ FUNC(LS_Line_SetTextureScale) // add if (arg1 != NO_CHANGE) { - if (arg4&1) side->MultiplyTextureXScale(side_t::top, arg1); - if (arg4&2) side->MultiplyTextureXScale(side_t::mid, arg1); - if (arg4&4) side->MultiplyTextureXScale(side_t::bottom, arg1); + if (arg4&1) side->MultiplyTextureXScale(side_t::top, farg1); + if (arg4&2) side->MultiplyTextureXScale(side_t::mid, farg1); + if (arg4&4) side->MultiplyTextureXScale(side_t::bottom, farg1); } if (arg2 != NO_CHANGE) { - if (arg4&1) side->MultiplyTextureYScale(side_t::top, arg2); - if (arg4&2) side->MultiplyTextureYScale(side_t::mid, arg2); - if (arg4&4) side->MultiplyTextureYScale(side_t::bottom, arg2); + if (arg4&1) side->MultiplyTextureYScale(side_t::top, farg2); + if (arg4&2) side->MultiplyTextureYScale(side_t::mid, farg2); + if (arg4&4) side->MultiplyTextureYScale(side_t::bottom, farg2); } } } @@ -2967,7 +2972,7 @@ FUNC(LS_TranslucentLine) int linenum; while ((linenum = itr.Next()) >= 0) { - lines[linenum].Alpha = Scale(clamp(arg1, 0, 255), FRACUNIT, 255); + lines[linenum].Alpha = Scale(clamp(arg1, 0, 255), OPAQUE, 255); if (arg2 == 0) { lines[linenum].flags &= ~ML_ADDTRANS; @@ -3083,7 +3088,7 @@ FUNC(LS_ForceField) if (it != NULL) { P_DamageMobj (it, NULL, NULL, 16, NAME_None); - P_ThrustMobj (it, it->angle + ANGLE_180, 0x7D000); + it->Thrust(it->Angles.Yaw + 180, 7.8125); } return true; } @@ -3136,29 +3141,28 @@ FUNC(LS_GlassBreak) { if (!arg0) { // Break some glass - fixed_t x, y; AActor *glass; - angle_t an; - int speed; - x = ln->v1->x + ln->dx/2; - y = ln->v1->y + ln->dy/2; + DVector2 linemid((ln->v1->fX() + ln->v2->fX()) / 2, (ln->v1->fY() + ln->v2->fY()) / 2); + + // remove dependence on sector size and always spawn 2 map units in front of the line. + DVector2 normal(ln->Delta().Y, -ln->Delta().X); + linemid += normal.Unit() * 2; + /* old code: x += (ln->frontsector->centerspot.x - x) / 5; y += (ln->frontsector->centerspot.y - y) / 5; + */ for (int i = 0; i < 7; ++i) { - glass = Spawn("GlassJunk", x, y, ONFLOORZ, ALLOW_REPLACE); + glass = Spawn("GlassJunk", DVector3(linemid, ONFLOORZ), ALLOW_REPLACE); - glass->AddZ(24 * FRACUNIT); + glass->AddZ(24.); glass->SetState (glass->SpawnState + (pr_glass() % glass->health)); - an = pr_glass() << (32-8); - glass->angle = an; - an >>= ANGLETOFINESHIFT; - speed = pr_glass() & 3; - glass->vel.x = finecosine[an] * speed; - glass->vel.y = finesine[an] * speed; - glass->vel.z = (pr_glass() & 7) << FRACBITS; + + glass->Angles.Yaw = pr_glass() * (360 / 256.); + glass->VelFromAngle(pr_glass() & 3); + glass->Vel.Z = (pr_glass() & 7); // [RH] Let the shards stick around longer than they did in Strife. glass->tics += pr_glass(); } diff --git a/src/p_local.h b/src/p_local.h index 8acfe2d34..0dd0dca68 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -23,14 +23,17 @@ #ifndef __P_LOCAL__ #define __P_LOCAL__ +#include #include "doomtype.h" #include "tables.h" +#include "vectors.h" + +const double NO_VALUE = FLT_MAX; class player_t; class AActor; struct FPlayerStart; class PClassActor; -struct fixedvec3; class APlayerPawn; struct line_t; struct sector_t; @@ -41,57 +44,28 @@ struct FTranslatedLineTarget; #include -#define STEEPSLOPE 46342 // [RH] Minimum floorplane.c value for walking +#define STEEPSLOPE (46342/65536.) // [RH] Minimum floorplane.c value for walking #define BONUSADD 6 // mapblocks are used to check movement // against lines and things #define MAPBLOCKUNITS 128 -#define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT) -#define MAPBLOCKSHIFT (FRACBITS+7) -#define MAPBMASK (MAPBLOCKSIZE-1) -#define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS) // Inspired by Maes extern int bmapnegx; extern int bmapnegy; -inline int GetSafeBlockX(int blockx) -{ - blockx >>= MAPBLOCKSHIFT; - return (blockx <= bmapnegx) ? blockx & 0x1FF : blockx; -} -inline int GetSafeBlockX(long long blockx) -{ - blockx >>= MAPBLOCKSHIFT; - return int((blockx <= bmapnegx) ? blockx & 0x1FF : blockx); -} - -inline int GetSafeBlockY(int blocky) -{ - blocky >>= MAPBLOCKSHIFT; - return (blocky <= bmapnegy) ? blocky & 0x1FF: blocky; -} -inline int GetSafeBlockY(long long blocky) -{ - blocky >>= MAPBLOCKSHIFT; - return int((blocky <= bmapnegy) ? blocky & 0x1FF: blocky); -} - -// MAXRADIUS is for precalculated sector block boxes -// the spider demon is larger, -// but we do not have any moving sectors nearby -#define MAXRADIUS 0/*32*FRACUNIT*/ - //#define GRAVITY FRACUNIT -#define MAXMOVE (30*FRACUNIT) +#define MAXMOVE (30.) -#define TALKRANGE (128*FRACUNIT) -#define USERANGE (64*FRACUNIT) -#define MELEERANGE (64*FRACUNIT) -#define MISSILERANGE (32*64*FRACUNIT) -#define PLAYERMISSILERANGE (8192*FRACUNIT) // [RH] New MISSILERANGE for players +#define TALKRANGE (128.) +#define USERANGE (64.) + +#define MELEERANGE (64.) +#define SAWRANGE (64.+(1./65536.)) // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) +#define MISSILERANGE (32*64.) +#define PLAYERMISSILERANGE (8192.) // [RH] New MISSILERANGE for players // follow a player exlusively for 3 seconds // No longer used. @@ -119,18 +93,13 @@ void P_PredictionLerpReset(); // P_MOBJ // -#define ONFLOORZ FIXED_MIN -#define ONCEILINGZ FIXED_MAX -#define FLOATRANDZ (FIXED_MAX-1) - #define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player #define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags=0); -void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); -int P_FaceMobj (AActor *source, AActor *target, angle_t *delta); -bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise = false, bool usecurspeed=false); +int P_FaceMobj (AActor *source, AActor *target, DAngle *delta); +bool P_SeekerMissile (AActor *actor, double thresh, double turnMax, bool precise = false, bool usecurspeed=false); enum EPuffFlags { @@ -141,42 +110,32 @@ enum EPuffFlags PF_NORANDOMZ = 16 }; -AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t hitdir, angle_t particledir, int updown, int flags = 0, AActor *vict = NULL); -inline AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const fixedvec3 &pos, angle_t hitdir, angle_t particledir, int updown, int flags = 0, AActor *vict = NULL) -{ - return P_SpawnPuff(source, pufftype, pos.x, pos.y, pos.z, hitdir, particledir, updown, flags, vict); -} -void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator); -inline void P_SpawnBlood(const fixedvec3 &pos, angle_t dir, int damage, AActor *originator) -{ - P_SpawnBlood(pos.x, pos.y, pos.z, dir, damage, originator); -} -void P_BloodSplatter (fixedvec3 pos, AActor *originator); -void P_BloodSplatter2 (fixedvec3 pos, AActor *originator); +AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const DVector3 &pos, DAngle hitdir, DAngle particledir, int updown, int flags = 0, AActor *vict = NULL); +void P_SpawnBlood (const DVector3 &pos, DAngle angle, int damage, AActor *originator); +void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle); +void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle); void P_RipperBlood (AActor *mo, AActor *bleeder); int P_GetThingFloorType (AActor *thing); void P_ExplodeMissile (AActor *missile, line_t *explodeline, AActor *target); AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassActor *type); AActor *P_SpawnMissile (AActor* source, AActor* dest, PClassActor *type, AActor* owner = NULL); -AActor *P_SpawnMissileZ (AActor* source, fixed_t z, AActor* dest, PClassActor *type); -AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, AActor *source, AActor *dest, PClassActor *type, bool checkspawn = true, AActor *owner = NULL); -inline AActor *P_SpawnMissileXYZ(const fixedvec3 &pos, AActor *source, AActor *dest, PClassActor *type, bool checkspawn = true, AActor *owner = NULL) -{ - return P_SpawnMissileXYZ(pos.x, pos.y, pos.z, source, dest, type, checkspawn, owner); -} -AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, angle_t angle, fixed_t vz); -AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type, angle_t angle, fixed_t vz, fixed_t speed); -AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, PClassActor *type, angle_t angle, fixed_t vz); -AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, PClassActor *type, angle_t angle, fixed_t vz, fixed_t speed, AActor *owner=NULL, bool checkspawn = true); -AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassActor *type); +AActor *P_SpawnMissileZ(AActor* source, double z, AActor* dest, PClassActor *type); +AActor *P_SpawnMissileXYZ(DVector3 pos, AActor *source, AActor *dest, PClassActor *type, bool checkspawn = true, AActor *owner = NULL); +AActor *P_SpawnMissileAngle(AActor *source, PClassActor *type, DAngle angle, double vz); +AActor *P_SpawnMissileAngleZ(AActor *source, double z, PClassActor *type, DAngle angle, double vz); +AActor *P_SpawnMissileAngleZSpeed(AActor *source, double z, PClassActor *type, DAngle angle, double vz, double speed, AActor *owner = NULL, bool checkspawn = true); +AActor *P_SpawnMissileZAimed(AActor *source, double z, AActor *dest, PClassActor *type); + AActor *P_SpawnPlayerMissile (AActor* source, PClassActor *type); -AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, angle_t angle); -AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, PClassActor *type, angle_t angle, +AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, DAngle angle); + +AActor *P_SpawnPlayerMissile (AActor *source, double x, double y, double z, PClassActor *type, DAngle angle, FTranslatedLineTarget *pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false, bool noautoaim = false, int aimflags = 0); -void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight=false); + +void P_CheckFakeFloorTriggers(AActor *mo, double oldz, bool oldz_has_viewheight = false); AActor *P_SpawnSubMissile (AActor *source, PClassActor *type, AActor *target); // Strife uses it @@ -187,20 +146,21 @@ AActor *P_SpawnSubMissile (AActor *source, PClassActor *type, AActor *target); / extern FClassMap SpawnableThings; extern FClassMap StrifeTypes; -bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid); -bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, angle_t angle, - fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid, +bool P_Thing_Spawn (int tid, AActor *source, int type, DAngle angle, bool fog, int newtid); +bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, DAngle angle, + double speed, double vspeed, int dest, AActor *forcedest, int gravity, int newtid, bool leadTarget); -bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog); + +bool P_MoveThing(AActor *source, const DVector3 &pos, bool fog); bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog); int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type); -void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob); +void P_Thing_SetVelocity(AActor *actor, const DVector3 &vec, bool add, bool setbob); void P_RemoveThing(AActor * actor); bool P_Thing_Raise(AActor *thing, AActor *raiser); bool P_Thing_CanRaise(AActor *thing); PClassActor *P_GetSpawnableType(int spawnnum); void InitSpawnablesFromMapinfo(); -int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset, fixed_t radiusoffset, angle_t pitch); +int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch); enum WARPF { @@ -244,8 +204,8 @@ extern msecnode_t *sector_list; // phares 3/16/98 struct spechit_t { line_t *line; - fixedvec2 oldrefpos; - fixedvec2 refpos; + DVector2 Oldrefpos; + DVector2 Refpos; }; extern TArray spechit; @@ -254,25 +214,20 @@ extern TArray portalhit; bool P_TestMobjLocation (AActor *mobj); bool P_TestMobjZ (AActor *mobj, bool quick=true, AActor **pOnmobj = NULL); -bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bool actorsonly=false); -bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, bool actorsonly=false); -inline bool P_CheckPosition(AActor *thing, const fixedvec3 &pos, bool actorsonly = false) -{ - return P_CheckPosition(thing, pos.x, pos.y, actorsonly); -} +bool P_CheckPosition(AActor *thing, const DVector2 &pos, bool actorsonly = false); +bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, bool actorsonly = false); AActor *P_CheckOnmobj (AActor *thing); void P_FakeZMovement (AActor *mo); -bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false); -bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor = NULL); -bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y); +bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false); +bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor = NULL); + +bool P_CheckMove(AActor *thing, const DVector2 &pos); void P_ApplyTorque(AActor *mo); -bool P_TeleportMove (AActor* thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag, bool modifyactor = true); // [RH] Added z and telefrag parameters -inline bool P_TeleportMove(AActor* thing, const fixedvec3 &pos, bool telefrag, bool modifyactor = true) -{ - return P_TeleportMove(thing, pos.x, pos.y, pos.z, telefrag, modifyactor); -} + +bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modifyactor = true); // [RH] Added z and telefrag parameters + void P_PlayerStartStomp (AActor *actor, bool mononly=false); // [RH] Stomp on things for a newly spawned player -void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps); +void P_SlideMove (AActor* mo, const DVector2 &pos, int numsteps); bool P_BounceWall (AActor *mo); bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop); bool P_CheckSight (AActor *t1, AActor *t2, int flags=0); @@ -304,9 +259,9 @@ enum }; void P_FindFloorCeiling (AActor *actor, int flags=0); -bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset); +bool P_ChangeSector (sector_t* sector, int crunch, double amt, int floorOrCeil, bool isreset); -fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, FTranslatedLineTarget *pLineTarget = NULL, fixed_t 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); enum // P_AimLineAttack flags { @@ -325,25 +280,40 @@ enum // P_LineAttack flags LAF_NOIMPACTDECAL = 4 }; -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); -void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); -inline void P_TraceBleed(int damage, const fixedvec3 &pos, AActor *target, angle_t angle, int pitch) -{ - P_TraceBleed(damage, pos.x, pos.y, pos.z, target, angle, pitch); -} -void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch); +AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); +AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); + +void P_TraceBleed(int damage, const DVector3 &pos, AActor *target, DAngle angle, DAngle pitch); +void P_TraceBleed(int damage, AActor *target, DAngle angle, DAngle pitch); + void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version void P_TraceBleed(int damage, FTranslatedLineTarget *t, AActor *puff); // hitscan version void P_TraceBleed (int damage, AActor *target); // random direction version bool P_HitFloor (AActor *thing); -bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true, bool force = false); -inline bool P_HitWater(AActor *thing, sector_t *sec, const fixedvec3 &pos, bool checkabove = false, bool alert = true, bool force = false) +bool P_HitWater (AActor *thing, sector_t *sec, const DVector3 &pos, bool checkabove = false, bool alert = true, bool force = false); +void P_CheckSplash(AActor *self, double distance); + +struct FRailParams { - return P_HitWater(thing, sec, pos.x, pos.y, pos.z, checkabove, alert, force); -} -void P_CheckSplash(AActor *self, fixed_t distance); -void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z = 0, int color1 = 0, int color2 = 0, double maxdiff = 0, int flags = 0, PClassActor *puff = NULL, angle_t angleoffset = 0, angle_t pitchoffset = 0, fixed_t distance = 8192*FRACUNIT, int duration = 0, double sparsity = 1.0, double drift = 1.0, PClassActor *spawnclass = NULL, int SpiralOffset = 270); // [RH] Shoot a railgun + AActor *source = nullptr; + int damage = 0; + double offset_xy = 0; + double offset_z = 0; + int color1 = 0, color2 = 0; + double maxdiff = 0; + int flags = 0; + PClassActor *puff = nullptr; + DAngle angleoffset = 0.; + DAngle pitchoffset = 0.; + double distance = 8192; + int duration = 0; + double sparsity = 1.0; + double drift = 1.0; + PClassActor *spawnclass = nullptr; + int SpiralOffset = 270; +}; // [RH] Shoot a railgun + +void P_RailAttack(FRailParams *params); enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags { @@ -355,11 +325,12 @@ enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags }; -bool P_CheckMissileSpawn (AActor *missile, fixed_t maxdist); +bool P_CheckMissileSpawn(AActor *missile, double maxdist); + void P_PlaySpawnSound(AActor *missile, AActor *spawner); // [RH] Position the chasecam -void P_AimCamera (AActor *t1, fixed_t &x, fixed_t &y, fixed_t &z, sector_t *&sec, bool &unlinked); +void P_AimCamera (AActor *t1, DVector3 &, sector_t *&sec, bool &unlinked); // [RH] Means of death enum @@ -375,13 +346,13 @@ void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, void P_DelSector_List(); void P_DelSeclist(msecnode_t *); // phares 3/16/98 msecnode_t* P_DelSecnode(msecnode_t *); -void P_CreateSecNodeList(AActor*,fixed_t,fixed_t); // phares 3/14/98 -int P_GetMoveFactor(const AActor *mo, int *frictionp); // phares 3/6/98 -int P_GetFriction(const AActor *mo, int *frictionfactor); +void P_CreateSecNodeList(AActor*); // phares 3/14/98 +double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98 +double P_GetFriction(const AActor *mo, double *frictionfactor); bool Check_Sides(AActor *, int, int); // phares // [RH] -const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove); +const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move); // // P_SETUP @@ -394,7 +365,7 @@ extern BYTE* rejectmatrix; // for fast sight rejection // P_INTER // void P_TouchSpecialThing (AActor *special, AActor *toucher); -int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0, angle_t angle = 0); +int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0, DAngle angle = 0.); void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type); bool P_GiveBody (AActor *actor, int num, int max=0); bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison); diff --git a/src/p_map.cpp b/src/p_map.cpp index ac06b3fb2..26c08af26 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -31,6 +31,7 @@ #include "m_random.h" #include "i_system.h" #include "c_dispatch.h" +#include "math/cmath.h" #include "doomdef.h" #include "p_local.h" @@ -63,7 +64,7 @@ CVAR(Bool, cl_bloodsplats, true, CVAR_ARCHIVE) CVAR(Int, sv_smartaim, 0, CVAR_ARCHIVE | CVAR_SERVERINFO) CVAR(Bool, cl_doautoaim, false, CVAR_ARCHIVE) -static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 * posforwindowcheck = NULL); +static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, DVector2 * posforwindowcheck = NULL); static void SpawnShootDecal(AActor *t1, const FTraceResults &trace); static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff); @@ -80,77 +81,6 @@ TArray portalhit; // Temporary holder for thing_sectorlist threads msecnode_t* sector_list = NULL; // phares 3/16/98 - -//========================================================================== -// -// GetCoefficientClosestPointInLine24 -// -// Formula: (dotProduct(ldv1 - tm, ld) << 24) / dotProduct(ld, ld) -// with: ldv1 = (ld->v1->x, ld->v1->y), tm = (tm.x, tm.y) -// and ld = (ld->dx, ld->dy) -// Returns truncated to range [0, 1 << 24]. -// -//========================================================================== - -static inline fixed_t GetCoefficientClosestPointInLine24(line_t *ld, fixedvec2 pos) -{ -#ifndef USE_FLOAT - // [EP] Use 64 bit integers in order to keep the exact result of the - // multiplication, because in the case the vertexes have both the - // distance coordinates equal to the map limit (32767 units, which is - // 2147418112 in fixed_t notation), the product result would occupy - // 62 bits and the sum of two products would occupy 63 bits - // in the worst case. If instead the vertexes are very close (1 in - // fixed_t notation, which is 1.52587890625e-05 in float notation), the - // product and the sum can be 1 in the worst case, which is very tiny. - - SQWORD r_num = ((SQWORD(pos.x - ld->v1->x)*ld->dx) + - (SQWORD(pos.y - ld->v1->y)*ld->dy)); - - // The denominator is always positive. Use this to avoid useless - // calculations. - SQWORD r_den = (SQWORD(ld->dx)*ld->dx + SQWORD(ld->dy)*ld->dy); - - if (r_num <= 0) { - // [EP] The numerator is less or equal to zero, hence the closest - // point on the line is the first vertex. Truncate the result to 0. - return 0; - } - - if (r_num >= r_den) { - // [EP] The division is greater or equal to 1, hence the closest - // point on the line is the second vertex. Truncate the result to - // 1 << 24. - return (1 << 24); - } - - // [EP] Deal with the limited bits. The original formula is: - // r = (r_num << 24) / r_den, - // but r_num might be big enough to make the shift overflow. - // Since the numerator can't be saved in a 128bit integer, - // the denominator must be right shifted. If the denominator is - // less than (1 << 24), there would be a division by zero. - // Thanks to the fact that in this code path the denominator is greater - // than the numerator, it's possible to avoid this bad situation by - // just checking the last 24 bits of the numerator. - if ((r_num >> (63 - 24)) != 0) { - // [EP] In fact, if the numerator is greater than - // (1 << (63-24)), the denominator must be greater than - // (1 << (63-24)), hence the denominator won't be zero after - // the right shift by 24 places. - return (fixed_t)(r_num / (r_den >> 24)); - } - // [EP] Having the last 24 bits all zero allows left shifting - // the numerator by 24 bits without overflow. - return (fixed_t)((r_num << 24) / r_den); -#else - double dx = ld->dx; - double dy = ld->dy; - return xs_CRoundToInt(((double)(pos.x - ld->v1->x) * dx + (double)(pos.y - ld->v1->y) * dy) / (dx*dx + dy*dy) * 16777216.f); -#endif -} - - //========================================================================== // // FindRefPoint @@ -159,41 +89,30 @@ static inline fixed_t GetCoefficientClosestPointInLine24(line_t *ld, fixedvec2 p // //========================================================================== -static inline fixedvec2 FindRefPoint(line_t *ld, fixedvec2 pos) +static DVector2 FindRefPoint(line_t *ld, const DVector2 &pos) { // If there's any chance of slopes getting in the way we need to get a proper refpoint, otherwise we can save the work. // Slopes can get in here when: // - the actual sector planes are sloped // - there's 3D floors in this sector // - there's a crossable floor portal (for which the dropoff needs to be calculated within P_LineOpening, and the lower sector can easily have slopes) - if ( - (((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | - (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | - (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | - (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) != 0) - || - ld->backsector->e->XFloor.ffloors.Size() != 0 - || - ld->frontsector->e->XFloor.ffloors.Size() != 0 - || + // + // Todo: check if this bootload of checks even helps or if it adds more than it saves + // + if (ld->frontsector->floorplane.isSlope() || + ld->backsector->floorplane.isSlope() || + ld->frontsector->ceilingplane.isSlope() || + ld->backsector->ceilingplane. isSlope() || + ld->backsector->e->XFloor.ffloors.Size() != 0 || + ld->frontsector->e->XFloor.ffloors.Size() != 0 || + !ld->frontsector->PortalBlocksMovement(sector_t::ceiling) || !ld->frontsector->PortalBlocksMovement(sector_t::floor)) { - fixed_t r = GetCoefficientClosestPointInLine24(ld, pos); - if (r <= 0) - { - pos.x = ld->v1->x; - pos.y = ld->v1->y; - } - else if (r >= (1 << 24)) - { - pos.x = ld->v2->x; - pos.y = ld->v2->y; - } - else - { - pos.x = ld->v1->x + MulScale24(r, ld->dx); - pos.y = ld->v1->y + MulScale24(r, ld->dy); - } + + DVector2 v1 = ld->v1->fPos(); + DVector2 d = ld->Delta(); + double r = clamp(((pos.X - v1.X) * d.X + (pos.Y - v1.Y) * d.Y) / (d.X*d.X + d.Y*d.Y), 0., 1.); + return v1 + d*r; } return pos; } @@ -211,13 +130,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines { line_t *ld = cres.line; - if (box.Right() <= ld->bbox[BOXLEFT] - || box.Left() >= ld->bbox[BOXRIGHT] - || box.Top() <= ld->bbox[BOXBOTTOM] - || box.Bottom() >= ld->bbox[BOXTOP]) - return true; - - if (box.BoxOnLineSide(ld) != -1) + if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) return true; // A line has been hit @@ -225,7 +138,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines if (ffcf_verbose) { Printf("Hit line %d at position %f,%f, group %d\n", - int(ld - lines), FIXED2FLOAT(cres.position.x), FIXED2FLOAT(cres.position.y), ld->frontsector->PortalGroup); + int(ld - lines), cres.Position.X, cres.Position.Y, ld->frontsector->PortalGroup); } if (!ld->backsector) @@ -233,10 +146,10 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines return true; } - fixedvec2 refpoint = FindRefPoint(ld, cres.position); + DVector2 refpoint = FindRefPoint(ld, cres.Position); FLineOpening open; - P_LineOpening(open, tmf.thing, ld, refpoint.x, refpoint.y, cres.position.x, cres.position.y, flags); + P_LineOpening(open, tmf.thing, ld, refpoint, &cres.Position, flags); // adjust floor / ceiling heights if (!(flags & FFCF_NOCEILING)) @@ -245,7 +158,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines { tmf.ceilingz = open.top; if (open.topsec != NULL) tmf.ceilingsector = open.topsec; - if (ffcf_verbose) Printf(" Adjust ceilingz to %f\n", FIXED2FLOAT(open.top)); + if (ffcf_verbose) Printf(" Adjust ceilingz to %f\n", open.top); mit.StopUp(); } } @@ -258,7 +171,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines if (open.bottomsec != NULL) tmf.floorsector = open.bottomsec; tmf.touchmidtex = open.touchmidtex; tmf.abovemidtex = open.abovemidtex; - if (ffcf_verbose) Printf(" Adjust floorz to %f\n", FIXED2FLOAT(open.bottom)); + if (ffcf_verbose) Printf(" Adjust floorz to %f\n", open.bottom); if (tmf.floorz > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); } else if (open.bottom == tmf.floorz) @@ -267,10 +180,10 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines tmf.abovemidtex |= open.abovemidtex; } - if (open.lowfloor < tmf.dropoffz && open.lowfloor > FIXED_MIN) + if (open.lowfloor < tmf.dropoffz && open.lowfloor > LINEOPEN_MIN) { tmf.dropoffz = open.lowfloor; - if (ffcf_verbose) Printf(" Adjust dropoffz to %f\n", FIXED2FLOAT(open.bottom)); + if (ffcf_verbose) Printf(" Adjust dropoffz to %f\n", open.bottom); if (tmf.floorz > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); } } @@ -287,11 +200,11 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) { - sector_t *sec = (!(flags & FFCF_SAMESECTOR) || tmf.thing->Sector == NULL)? P_PointInSector(tmf.x, tmf.y) : tmf.sector; + sector_t *sec = (!(flags & FFCF_SAMESECTOR) || tmf.thing->Sector == NULL)? P_PointInSector(tmf.pos) : tmf.sector; F3DFloor *ffc, *fff; - tmf.ceilingz = sec->NextHighestCeilingAt(tmf.x, tmf.y, tmf.z, tmf.z + tmf.thing->height, flags, &tmf.ceilingsector, &ffc); - tmf.floorz = tmf.dropoffz = sec->NextLowestFloorAt(tmf.x, tmf.y, tmf.z, flags, tmf.thing->MaxStepHeight, &tmf.floorsector, &fff); + tmf.ceilingz = sec->NextHighestCeilingAt(tmf.pos.X, tmf.pos.Y, tmf.pos.Z, tmf.pos.Z + tmf.thing->Height, flags, &tmf.ceilingsector, &ffc); + tmf.floorz = tmf.dropoffz = sec->NextLowestFloorAt(tmf.pos.X, tmf.pos.Y, tmf.pos.Z, flags, tmf.thing->MaxStepHeight, &tmf.floorsector, &fff); if (fff) { @@ -319,9 +232,7 @@ void P_FindFloorCeiling(AActor *actor, int flags) FCheckPosition tmf; tmf.thing = actor; - tmf.x = actor->X(); - tmf.y = actor->Y(); - tmf.z = actor->Z(); + tmf.pos = actor->Pos(); if (flags & FFCF_ONLYSPAWNPOS) { @@ -342,7 +253,7 @@ void P_FindFloorCeiling(AActor *actor, int flags) actor->floorsector = tmf.floorsector; actor->ceilingpic = tmf.ceilingpic; actor->ceilingsector = tmf.ceilingsector; - if (ffcf_verbose) Printf("Starting with ceilingz = %f, floorz = %f\n", FIXED2FLOAT(tmf.ceilingz), FIXED2FLOAT(tmf.floorz)); + if (ffcf_verbose) Printf("Starting with ceilingz = %f, floorz = %f\n", tmf.ceilingz, tmf.floorz); tmf.touchmidtex = false; tmf.abovemidtex = false; @@ -408,7 +319,7 @@ CCMD(ffcf) // //========================================================================== -bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag, bool modifyactor) +bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modifyactor) { FCheckPosition tmf; sector_t *oldsec = thing->Sector; @@ -419,9 +330,7 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra // The base floor/ceiling is from the subsector that contains the point. // Any contacted lines the step closer together will adjust them. tmf.thing = thing; - tmf.x = x; - tmf.y = y; - tmf.z = z; + tmf.pos = pos; tmf.touchmidtex = false; tmf.abovemidtex = false; P_GetFloorCeilingZ(tmf, 0); @@ -431,12 +340,12 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP); // P_LineOpening requires the thing's z to be the destination z in order to work. - fixed_t savedz = thing->Z(); - thing->SetZ(z); - sector_t *sector = P_PointInSector(x, y); + double savedz = thing->Z(); + thing->SetZ(pos.Z); + sector_t *sector = P_PointInSector(pos); FPortalGroupArray grouplist; - FMultiBlockLinesIterator mit(grouplist, x, y, z, thing->height, thing->radius, sector); + FMultiBlockLinesIterator mit(grouplist, pos.X, pos.Y, pos.Z, thing->Height, thing->radius, sector); FMultiBlockLinesIterator::CheckResult cres; while (mit.Next(&cres)) @@ -447,7 +356,7 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz; - FMultiBlockThingsIterator mit2(grouplist, x, y, z, thing->height, thing->radius, false, sector); + FMultiBlockThingsIterator mit2(grouplist, pos.X, pos.Y, pos.Z, thing->Height, thing->radius, false, sector); FMultiBlockThingsIterator::CheckResult cres2; while (mit2.Next(&cres2)) @@ -461,8 +370,8 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra if (th == thing) continue; - fixed_t blockdist = th->radius + tmf.thing->radius; - if (abs(th->X() - cres2.position.x) >= blockdist || abs(th->Y() - cres2.position.y) >= blockdist) + double blockdist = th->radius + tmf.thing->radius; + if (fabs(th->X() - cres2.Position.X) >= blockdist || fabs(th->Y() - cres2.Position.Y) >= blockdist) continue; if ((th->flags2 | tmf.thing->flags2) & MF2_THRUACTORS) @@ -478,8 +387,8 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra { if (!(th->flags3 & thing->flags3 & MF3_DONTOVERLAP)) { - if (z > th->Top() || // overhead - z + thing->height < th->Z()) // underneath + if (pos.Z > th->Top() || // overhead + pos.Z + thing->Height < th->Z()) // underneath continue; } } @@ -500,7 +409,7 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra if (modifyactor) { // the move is ok, so link the thing into its new position - thing->SetOrigin(x, y, z, false); + thing->SetOrigin(pos, false); thing->floorz = tmf.floorz; thing->ceilingz = tmf.ceilingz; thing->floorsector = tmf.floorsector; @@ -558,8 +467,8 @@ void P_PlayerStartStomp(AActor *actor, bool mononly) if (th == actor || (th->player == actor->player && th->player != NULL)) continue; - fixed_t blockdist = th->radius + actor->radius; - if (abs(th->X() - cres.position.x) >= blockdist || abs(th->Y() - cres.position.y) >= blockdist) + double blockdist = th->radius + actor->radius; + if (fabs(th->X() - cres.Position.X) >= blockdist || fabs(th->Y() - cres.Position.Y) >= blockdist) continue; // only kill monsters and other players @@ -578,26 +487,6 @@ void P_PlayerStartStomp(AActor *actor, bool mononly) } } -//========================================================================== -// -// -// -//========================================================================== - -inline fixed_t secfriction(const sector_t *sec, int plane = sector_t::floor) -{ - if (sec->Flags & SECF_FRICTION) return sec->friction; - fixed_t friction = Terrains[sec->GetTerrain(plane)].Friction; - return friction != 0 ? friction : ORIG_FRICTION; -} - -inline fixed_t secmovefac(const sector_t *sec, int plane = sector_t::floor) -{ - if (sec->Flags & SECF_FRICTION) return sec->movefactor; - fixed_t movefactor = Terrains[sec->GetTerrain(plane)].MoveFactor; - return movefactor != 0 ? movefactor : ORIG_FRICTION_FACTOR; -} - //========================================================================== // // killough 8/28/98: @@ -608,11 +497,13 @@ inline fixed_t secmovefac(const sector_t *sec, int plane = sector_t::floor) // //========================================================================== -int P_GetFriction(const AActor *mo, int *frictionfactor) +double P_GetFriction(const AActor *mo, double *frictionfactor) { - int friction = ORIG_FRICTION; - int movefactor = ORIG_FRICTION_FACTOR; - fixed_t newfriction; + double friction = ORIG_FRICTION; + double movefactor = ORIG_FRICTION_FACTOR; + double newfriction; + double newmf; + const msecnode_t *m; sector_t *sec; @@ -625,29 +516,29 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) friction = FRICTION_FLY; } else if ((!(mo->flags & MF_NOGRAVITY) && mo->waterlevel > 1) || - (mo->waterlevel == 1 && mo->Z() > mo->floorz + 6 * FRACUNIT)) + (mo->waterlevel == 1 && mo->Z() > mo->floorz+ 6)) { - friction = secfriction(mo->Sector); - movefactor = secmovefac(mo->Sector) >> 1; + friction = mo->Sector->GetFriction(sector_t::floor, &movefactor); + movefactor *= 0.5; - // Check 3D floors -- might be the source of the waterlevel - for (unsigned i = 0; i < mo->Sector->e->XFloor.ffloors.Size(); i++) + // Check 3D floors -- might be the source of the waterlevel + for (unsigned i = 0; i < mo->Sector->e->XFloor.ffloors.Size(); i++) + { + F3DFloor *rover = mo->Sector->e->XFloor.ffloors[i]; + if (!(rover->flags & FF_EXISTS)) continue; + if (!(rover->flags & FF_SWIMMABLE)) continue; + + if (mo->Z() > rover->top.plane->ZatPoint(mo) || + mo->Z() < rover->bottom.plane->ZatPoint(mo)) + continue; + + newfriction = rover->model->GetFriction(rover->top.isceiling, &newmf); + if (newfriction < friction || friction == ORIG_FRICTION) { - F3DFloor *rover = mo->Sector->e->XFloor.ffloors[i]; - if (!(rover->flags & FF_EXISTS)) continue; - if (!(rover->flags & FF_SWIMMABLE)) continue; - - if (mo->Z() > rover->top.plane->ZatPoint(mo) || - mo->Z() < rover->bottom.plane->ZatPoint(mo)) - continue; - - newfriction = secfriction(rover->model, rover->top.isceiling); - if (newfriction < friction || friction == ORIG_FRICTION) - { - friction = newfriction; - movefactor = secmovefac(rover->model, rover->top.isceiling) >> 1; - } + friction = newfriction; + movefactor = newmf * 0.5; } + } } else if (var_friction && !(mo->flags & (MF_NOCLIP | MF_NOGRAVITY))) { // When the object is straddling sectors with the same @@ -657,7 +548,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) for (m = mo->touching_sectorlist; m; m = m->m_tnext) { sec = m->m_sector; - fixedvec3 pos = mo->PosRelative(sec); + DVector3 pos = mo->PosRelative(sec); // 3D floors must be checked, too for (unsigned i = 0; i < sec->e->XFloor.ffloors.Size(); i++) @@ -668,7 +559,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) if (rover->flags & FF_SOLID) { // Must be standing on a solid floor - if (mo->Z() != rover->top.plane->ZatPoint(pos)) continue; + if (!mo->isAtZ(rover->top.plane->ZatPoint(pos))) continue; } else if (rover->flags & FF_SWIMMABLE) { @@ -680,11 +571,11 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) else continue; - newfriction = secfriction(rover->model, rover->top.isceiling); + newfriction = rover->model->GetFriction(rover->top.isceiling, &newmf); if (newfriction < friction || friction == ORIG_FRICTION) { friction = newfriction; - movefactor = secmovefac(rover->model, rover->top.isceiling); + movefactor = newmf; } } @@ -693,21 +584,21 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) { continue; } - newfriction = secfriction(sec); + newfriction = sec->GetFriction(sector_t::floor, &newmf); if ((newfriction < friction || friction == ORIG_FRICTION) && (mo->Z() <= sec->floorplane.ZatPoint(pos) || (sec->GetHeightSec() != NULL && mo->Z() <= sec->heightsec->floorplane.ZatPoint(pos)))) { friction = newfriction; - movefactor = secmovefac(sec); + movefactor = newmf; } } } - if (mo->Friction != FRACUNIT) + if (mo->Friction != 1) { - friction = clamp(FixedMul(friction, mo->Friction), 0, FRACUNIT); + friction = clamp((friction * mo->Friction), 0., 1.); movefactor = FrictionToMoveFactor(friction); } @@ -727,9 +618,9 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) // //========================================================================== -int P_GetMoveFactor(const AActor *mo, int *frictionp) +double P_GetMoveFactor(const AActor *mo, double *frictionp) { - int movefactor, friction; + double movefactor, friction; // If the floor is icy or muddy, it's harder to get moving. This is where // the different friction factors are applied to 'trying to move'. In @@ -740,14 +631,14 @@ int P_GetMoveFactor(const AActor *mo, int *frictionp) // phares 3/11/98: you start off slowly, then increase as // you get better footing - int velocity = P_AproxDistance(mo->vel.x, mo->vel.y); + double velocity = mo->VelXYToSpeed(); - if (velocity > MORE_FRICTION_VELOCITY << 2) - movefactor <<= 3; - else if (velocity > MORE_FRICTION_VELOCITY << 1) - movefactor <<= 2; + if (velocity > MORE_FRICTION_VELOCITY * 4) + movefactor *= 8; + else if (velocity > MORE_FRICTION_VELOCITY * 2) + movefactor *= 4; else if (velocity > MORE_FRICTION_VELOCITY) - movefactor <<= 1; + movefactor *= 2; } if (frictionp) @@ -771,14 +662,14 @@ static int LineIsAbove(line_t *line, AActor *actor) { AActor *point = line->frontsector->SkyBoxes[sector_t::floor]; if (point == NULL) return -1; - return point->threshold >= actor->Top(); + return point->specialf1 >= actor->Top(); } static int LineIsBelow(line_t *line, AActor *actor) { AActor *point = line->frontsector->SkyBoxes[sector_t::ceiling]; if (point == NULL) return -1; - return point->threshold <= actor->Z(); + return point->specialf1 <= actor->Z(); } // @@ -800,13 +691,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec line_t *ld = cres.line; bool rail = false; - if (box.Right() <= ld->bbox[BOXLEFT] - || box.Left() >= ld->bbox[BOXRIGHT] - || box.Top() <= ld->bbox[BOXBOTTOM] - || box.Bottom() >= ld->bbox[BOXTOP]) - return true; - - if (box.BoxOnLineSide(ld) != -1) + if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) return true; // A line has been hit @@ -827,8 +712,8 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec { spechit_t spec; spec.line = ld; - spec.refpos = cres.position; - spec.oldrefpos = tm.thing->PosRelative(ld); + spec.Refpos = cres.Position; + spec.Oldrefpos = tm.thing->PosRelative(ld); portalhit.Push(spec); return true; } @@ -877,7 +762,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec if (state == 1) { // the line should not block but we should set the ceilingz to the portal boundary so that we can't float up into that line. - fixed_t portalz = cres.line->frontsector->SkyBoxes[sector_t::floor]->threshold; + double portalz = cres.line->frontsector->SkyBoxes[sector_t::floor]->specialf1; if (portalz < tm.ceilingz) { tm.ceilingz = portalz; @@ -893,7 +778,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec if (state == -1) return true; if (state == 1) { - fixed_t portalz = cres.line->frontsector->SkyBoxes[sector_t::ceiling]->threshold; + double portalz = cres.line->frontsector->SkyBoxes[sector_t::ceiling]->specialf1; if (portalz > tm.floorz) { tm.floorz = portalz; @@ -911,21 +796,21 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec } tm.thing->BlockingLine = ld; // Calculate line side based on the actor's original position, not the new one. - CheckForPushSpecial(ld, P_PointOnLineSide(cres.position.x, cres.position.y, ld), tm.thing); + CheckForPushSpecial(ld, P_PointOnLineSide(cres.Position, ld), tm.thing); return false; } } } - fixedvec2 ref = FindRefPoint(ld, cres.position); + DVector2 ref = FindRefPoint(ld, cres.Position); FLineOpening open; - P_LineOpening(open, tm.thing, ld, ref.x, ref.y, cres.position.x, cres.position.y, cres.portalflags); + P_LineOpening(open, tm.thing, ld, ref, &cres.Position, cres.portalflags); // [RH] Steep sectors count as dropoffs, if the actor touches the boundary between a steep slope and something else if (!(tm.thing->flags & MF_DROPOFF) && !(tm.thing->flags & (MF_NOGRAVITY | MF_NOCLIP))) { - if ((open.frontfloorplane.c < STEEPSLOPE) != (open.backfloorplane.c < STEEPSLOPE)) + if ((open.frontfloorplane.fC() < STEEPSLOPE) != (open.backfloorplane.fC() < STEEPSLOPE)) { // on the boundary of a steep slope return false; @@ -934,9 +819,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec // If the floor planes on both sides match we should recalculate open.bottom at the actual position we are checking // This is to avoid bumpy movement when crossing a linedef with the same slope on both sides. - if (open.frontfloorplane == open.backfloorplane && open.bottom > FIXED_MIN) + if (open.frontfloorplane == open.backfloorplane && open.bottom > LINEOPEN_MIN) { - open.bottom = open.frontfloorplane.ZatPoint(cres.position.x, cres.position.y); + open.bottom = open.frontfloorplane.ZatPoint(cres.Position); } if (rail && @@ -948,9 +833,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec // from either side. How long until somebody reports this as a bug and I'm // forced to say, "It's not a bug. It's a feature?" Ugh. (!(level.flags2 & LEVEL2_RAILINGHACK) || - open.bottom == tm.thing->Sector->floorplane.ZatPoint(ref.x, ref.y))) + open.bottom == tm.thing->Sector->floorplane.ZatPoint(ref))) { - open.bottom += 32 * FRACUNIT; + open.bottom += 32; } // adjust floor / ceiling heights @@ -995,15 +880,15 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec if (ld->special) { spec.line = ld; - spec.refpos = cres.position; - spec.oldrefpos = tm.thing->PosRelative(ld); + spec.Refpos = cres.Position; + spec.Oldrefpos = tm.thing->PosRelative(ld); spechit.Push(spec); } if (ld->isLinePortal()) { spec.line = ld; - spec.refpos = cres.position; - spec.oldrefpos = tm.thing->PosRelative(ld); + spec.Refpos = cres.Position; + spec.Oldrefpos = tm.thing->PosRelative(ld); portalhit.Push(spec); } @@ -1031,19 +916,13 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera // if in another vertical section let's just ignore it. if (cres.portalflags & (FFCF_NOCEILING | FFCF_NOFLOOR)) return false; - if (box.Right() <= cres.line->bbox[BOXLEFT] - || box.Left() >= cres.line->bbox[BOXRIGHT] - || box.Top() <= cres.line->bbox[BOXBOTTOM] - || box.Bottom() >= cres.line->bbox[BOXTOP]) - return false; - - if (box.BoxOnLineSide(cres.line) != -1) + if (!box.inRange(cres.line) || box.BoxOnLineSide(cres.line) != -1) return false; line_t *lp = cres.line->getPortalDestination(); - fixed_t zofs = 0; + double zofs = 0; - P_TranslatePortalXY(cres.line, cres.position.x, cres.position.y); + P_TranslatePortalXY(cres.line, cres.Position.X, cres.Position.Y); P_TranslatePortalZ(cres.line, zofs); // fudge a bit with the portal line so that this gets included in the checks that normally only get run on two-sided lines @@ -1051,7 +930,7 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera if (lp->backsector == NULL) lp->backsector = lp->frontsector; tm.thing->AddZ(zofs); - FBoundingBox pbox(cres.position.x, cres.position.y, tm.thing->radius); + FBoundingBox pbox(cres.Position.X, cres.Position.Y, tm.thing->radius); FBlockLinesIterator it(pbox); bool ret = false; line_t *ld; @@ -1059,22 +938,16 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera // Check all lines at the destination while ((ld = it.Next())) { - if (pbox.Right() <= ld->bbox[BOXLEFT] - || pbox.Left() >= ld->bbox[BOXRIGHT] - || pbox.Top() <= ld->bbox[BOXBOTTOM] - || pbox.Bottom() >= ld->bbox[BOXTOP]) - continue; - - if (pbox.BoxOnLineSide(ld) != -1) + if (!pbox.inRange(ld) || pbox.BoxOnLineSide(ld) != -1) continue; if (ld->backsector == NULL) continue; - fixedvec2 ref = FindRefPoint(ld, cres.position); + DVector2 ref = FindRefPoint(ld, cres.Position); FLineOpening open; - P_LineOpening(open, tm.thing, ld, ref.x, ref.y, cres.position.x, cres.position.y, 0); + P_LineOpening(open, tm.thing, ld, ref, &cres.Position, 0); // adjust floor / ceiling heights if (open.top - zofs < tm.ceilingz) @@ -1208,7 +1081,7 @@ static bool CanAttackHurt(AActor *victim, AActor *shooter) bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::CheckResult &cres, const FBoundingBox &box, FCheckPosition &tm) { AActor *thing = cres.thing; - fixed_t topz; + double topz; bool solid; int damage; @@ -1219,8 +1092,8 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch if (!((thing->flags & (MF_SOLID | MF_SPECIAL | MF_SHOOTABLE)) || thing->flags6 & MF6_TOUCHY)) return true; // can't hit thing - fixed_t blockdist = thing->radius + tm.thing->radius; - if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist) + double blockdist = thing->radius + tm.thing->radius; + if (fabs(thing->X() - cres.Position.X) >= blockdist || fabs(thing->Y() - cres.Position.Y) >= blockdist) return true; if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS) @@ -1261,19 +1134,19 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch if (((tm.FromPMove || tm.thing->player != NULL) && thing->flags&MF_SOLID)) { - fixedvec3 oldpos = tm.thing->PosRelative(thing); + DVector3 oldpos = tm.thing->PosRelative(thing); // Both actors already overlap. To prevent them from remaining stuck allow the move if it // takes them further apart or the move does not change the position (when called from P_ChangeSector.) - if (oldpos.x == thing->X() && oldpos.y == thing->Y()) + if (oldpos.X == thing->X() && oldpos.Y == thing->Y()) { unblocking = true; } - else if (abs(thing->X() - oldpos.x) < (thing->radius + tm.thing->radius) && - abs(thing->Y() - oldpos.y) < (thing->radius + tm.thing->radius)) + else if (fabs(thing->X() - oldpos.X) < (thing->radius + tm.thing->radius) && + fabs(thing->Y() - oldpos.Y) < (thing->radius + tm.thing->radius)) { - fixed_t newdist = thing->AproxDistance(cres.position.x, cres.position.y); - fixed_t olddist = thing->AproxDistance(oldpos.x, oldpos.y); + double newdist = thing->Distance2D(cres.Position.X, cres.Position.Y); + double olddist = thing->Distance2D(oldpos.X, oldpos.Y); if (newdist > olddist) { @@ -1360,9 +1233,8 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch if (!(thing->flags2 & MF2_BOSS) && (thing->flags3 & MF3_ISMONSTER) && !(thing->flags3 & MF3_DONTBLAST)) { // ideally this should take the mass factor into account - thing->vel.x += tm.thing->vel.x; - thing->vel.y += tm.thing->vel.y; - if ((thing->vel.x + thing->vel.y) > 3 * FRACUNIT) + thing->Vel += tm.thing->Vel.XY(); + if ((thing->Vel.X + thing->Vel.Y) > 3.) { int newdam; damage = (tm.thing->Mass / 100) + 1; @@ -1400,7 +1272,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch return true; } - int clipheight; + double clipheight; if (thing->projectilepassheight > 0) { @@ -1412,7 +1284,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch } else { - clipheight = thing->height; + clipheight = thing->Height; } // Check if it went over / under @@ -1498,8 +1370,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch { // Push thing if (thing->lastpush != tm.PushTime) { - thing->vel.x += FixedMul(tm.thing->vel.x, thing->pushfactor); - thing->vel.y += FixedMul(tm.thing->vel.y, thing->pushfactor); + thing->Vel += tm.thing->Vel.XY() * thing->pushfactor; thing->lastpush = tm.PushTime; } } @@ -1529,7 +1400,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch !(tm.thing->flags3 & MF3_BLOODLESSIMPACT) && (pr_checkthing() < 192)) { - P_BloodSplatter(tm.thing->Pos(), thing); + P_BloodSplatter(tm.thing->Pos(), thing, tm.thing->AngleTo(thing)); } if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT)) { @@ -1557,8 +1428,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch { // Push thing if (thing->lastpush != tm.PushTime) { - thing->vel.x += FixedMul(tm.thing->vel.x, thing->pushfactor); - thing->vel.y += FixedMul(tm.thing->vel.y, thing->pushfactor); + thing->Vel += tm.thing->Vel.XY() * thing->pushfactor; thing->lastpush = tm.PushTime; } } @@ -1623,19 +1493,19 @@ MOVEMENT CLIPPING // //========================================================================== -bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bool actorsonly) +bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, bool actorsonly) { sector_t *newsec; AActor *thingblocker; - fixed_t realheight = thing->height; + double realHeight = thing->Height; tm.thing = thing; - tm.x = x; - tm.y = y; - tm.z = thing->Z(); + tm.pos.X = pos.X; + tm.pos.Y = pos.Y; + tm.pos.Z = thing->Z(); - newsec = tm.sector = P_PointInSector(x, y); + newsec = tm.sector = P_PointInSector(pos); tm.ceilingline = thing->BlockingLine = NULL; // Retrieve the base floor / ceiling from the target location. @@ -1647,8 +1517,8 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo else { // With noclip2, we must ignore 3D floors and go right to the uppermost ceiling and lowermost floor. - tm.floorz = tm.dropoffz = newsec->LowestFloorAt(x, y, &tm.floorsector); - tm.ceilingz = newsec->HighestCeilingAt(x, y, &tm.ceilingsector); + tm.floorz = tm.dropoffz = newsec->LowestFloorAt(pos, &tm.floorsector); + tm.ceilingz = newsec->HighestCeilingAt(pos, &tm.ceilingsector); tm.floorpic = tm.floorsector->GetTexture(sector_t::floor); tm.floorterrain = tm.floorsector->GetTerrain(sector_t::floor); tm.ceilingpic = tm.ceilingsector->GetTexture(sector_t::ceiling); @@ -1666,14 +1536,14 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo thingblocker = NULL; if (thing->player) { // [RH] Fake taller height to catch stepping up into things. - thing->height = realheight + thing->MaxStepHeight; + thing->Height = realHeight + thing->MaxStepHeight; } tm.stepthing = NULL; - FBoundingBox box(x, y, thing->radius); + FBoundingBox box(pos.X, pos.Y, thing->radius); FPortalGroupArray pcheck; - FMultiBlockThingsIterator it2(pcheck, x, y, thing->Z(), thing->height, thing->radius, false, newsec); + FMultiBlockThingsIterator it2(pcheck, pos.X, pos.Y, thing->Z(), thing->Height, thing->radius, false, newsec); FMultiBlockThingsIterator::CheckResult tcres; while ((it2.Next(&tcres))) @@ -1688,7 +1558,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo // If this blocks through a restricted line portal, it will always completely block. if (BlockingMobj == NULL || (i_compatflags & COMPATF_NO_PASSMOBJ) || (tcres.portalflags & FFCF_RESTRICTEDPORTAL)) { // Thing slammed into something; don't let it move now. - thing->height = realheight; + thing->Height = realHeight; return false; } else if (!BlockingMobj->player && !(thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY)) && @@ -1707,7 +1577,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo if (thingblocker) { // There is something to step up on. Return this thing as // the blocker so that we don't step up. - thing->height = realheight; + thing->Height = realHeight; return false; } // Nothing is blocking us, but this actor potentially could @@ -1716,7 +1586,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo } else { // Definitely blocking - thing->height = realheight; + thing->Height = realHeight; return false; } } @@ -1736,17 +1606,17 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo validcount++; thing->BlockingMobj = NULL; - thing->height = realheight; + thing->Height = realHeight; if (actorsonly || (thing->flags & MF_NOCLIP)) return (thing->BlockingMobj = thingblocker) == NULL; spechit.Clear(); portalhit.Clear(); - FMultiBlockLinesIterator it(pcheck, x, y, thing->Z(), thing->height, thing->radius, newsec); + FMultiBlockLinesIterator it(pcheck, pos.X, pos.Y, thing->Z(), thing->Height, thing->radius, newsec); FMultiBlockLinesIterator::CheckResult lcres; - fixed_t thingdropoffz = tm.floorz; + double thingdropoffz = tm.floorz; //bool onthing = (thingdropoffz != tmdropoffz); tm.floorz = tm.dropoffz; @@ -1775,7 +1645,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo { return false; } - if (tm.ceilingz - tm.floorz < thing->height) + if (tm.ceilingz - tm.floorz < thing->Height) { return false; } @@ -1791,10 +1661,10 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo return (thing->BlockingMobj = thingblocker) == NULL; } -bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, bool actorsonly) +bool P_CheckPosition(AActor *thing, const DVector2 &pos, bool actorsonly) { FCheckPosition tm; - return P_CheckPosition(thing, x, y, tm, actorsonly); + return P_CheckPosition(thing, pos, tm, actorsonly); } //---------------------------------------------------------------------------- @@ -1812,7 +1682,7 @@ bool P_TestMobjLocation(AActor *mobj) flags = mobj->flags; mobj->flags &= ~MF_PICKUP; - if (P_CheckPosition(mobj, mobj->X(), mobj->Y())) + if (P_CheckPosition(mobj, mobj->Pos())) { // XY is ok, now check Z mobj->flags = flags; if ((mobj->Z() < mobj->floorz) || (mobj->Top() > mobj->ceilingz)) @@ -1835,7 +1705,7 @@ bool P_TestMobjLocation(AActor *mobj) AActor *P_CheckOnmobj(AActor *thing) { - fixed_t oldz; + double oldz; bool good; AActor *onmobj; @@ -1870,8 +1740,8 @@ bool P_TestMobjZ(AActor *actor, bool quick, AActor **pOnmobj) { AActor *thing = cres.thing; - fixed_t blockdist = thing->radius + actor->radius; - if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist) + double blockdist = thing->radius + actor->radius; + if (fabs(thing->X() - cres.Position.X) >= blockdist || fabs(thing->Y() - cres.Position.Y) >= blockdist) { continue; } @@ -1940,13 +1810,13 @@ void P_FakeZMovement(AActor *mo) // // adjust height // - mo->AddZ(mo->vel.z); + mo->AddZ(mo->Vel.Z); if ((mo->flags&MF_FLOAT) && mo->target) { // float down towards target if too close if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT)) { - fixed_t dist = mo->AproxDistance(mo->target); - fixed_t delta = (mo->target->Z() + (mo->height >> 1)) - mo->Z(); + double dist = mo->Distance2D(mo->target); + double delta = mo->target->Center() - mo->Z(); if (delta < 0 && dist < -(delta * 3)) mo->AddZ(-mo->FloatSpeed); else if (delta > 0 && dist < (delta * 3)) @@ -1955,7 +1825,7 @@ void P_FakeZMovement(AActor *mo) } if (mo->player && mo->flags&MF_NOGRAVITY && (mo->Z() > mo->floorz) && !mo->IsNoClip2()) { - mo->AddZ(finesine[(FINEANGLES / 80 * level.maptime)&FINEMASK] / 8); + mo->AddZ(DAngle(4.5 * level.maptime).Sin()); } // @@ -1968,7 +1838,7 @@ void P_FakeZMovement(AActor *mo) if (mo->Top() > mo->ceilingz) { // hit the ceiling - mo->SetZ(mo->ceilingz - mo->height); + mo->SetZ(mo->ceilingz - mo->Height); } } @@ -1978,30 +1848,28 @@ void P_FakeZMovement(AActor *mo) // //=========================================================================== -static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 *posforwindowcheck) +static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, DVector2 *posforwindowcheck) { if (line->special && !(mobj->flags6 & MF6_NOTRIGGER)) { if (posforwindowcheck && !(ib_compatflags & BCOMPATF_NOWINDOWCHECK) && line->backsector != NULL) { // Make sure this line actually blocks us and is not a window // or similar construct we are standing inside of. - fixedvec3 pos = mobj->PosRelative(line); - fixed_t fzt = line->frontsector->ceilingplane.ZatPoint(*posforwindowcheck); - fixed_t fzb = line->frontsector->floorplane.ZatPoint(*posforwindowcheck); - fixed_t bzt = line->backsector->ceilingplane.ZatPoint(*posforwindowcheck); - fixed_t bzb = line->backsector->floorplane.ZatPoint(*posforwindowcheck); + DVector3 pos = mobj->PosRelative(line); + double fzt = line->frontsector->ceilingplane.ZatPoint(*posforwindowcheck); + double fzb = line->frontsector->floorplane.ZatPoint(*posforwindowcheck); + double bzt = line->backsector->ceilingplane.ZatPoint(*posforwindowcheck); + double bzb = line->backsector->floorplane.ZatPoint(*posforwindowcheck); if (fzt >= mobj->Top() && bzt >= mobj->Top() && fzb <= mobj->Z() && bzb <= mobj->Z()) { // we must also check if some 3D floor in the backsector may be blocking - for (unsigned int i = 0; ibacksector->e->XFloor.ffloors.Size(); i++) + for (auto rover : line->backsector->e->XFloor.ffloors) { - F3DFloor* rover = line->backsector->e->XFloor.ffloors[i]; - if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - fixed_t ff_bottom = rover->bottom.plane->ZatPoint(*posforwindowcheck); - fixed_t ff_top = rover->top.plane->ZatPoint(*posforwindowcheck); + double ff_bottom = rover->bottom.plane->ZatPoint(*posforwindowcheck); + double ff_top = rover->top.plane->ZatPoint(*posforwindowcheck); if (ff_bottom < mobj->Top() && ff_top > mobj->Z()) { @@ -2040,15 +1908,14 @@ static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 // //========================================================================== -bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, +bool P_TryMove(AActor *thing, const DVector2 &pos, int dropoff, // killough 3/15/98: allow dropoff as option const secplane_t *onfloor, // [RH] Let P_TryMove keep the thing on the floor FCheckPosition &tm, bool missileCheck) // [GZ] Fired missiles ignore the drop-off test { - fixedvec3 oldpos; sector_t *oldsector; - fixed_t oldz; + double oldz; int side; int oldside; sector_t* oldsec = thing->Sector; // [RH] for sector actions @@ -2058,10 +1925,10 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, oldz = thing->Z(); if (onfloor) { - thing->SetZ(onfloor->ZatPoint(x, y)); + thing->SetZ(onfloor->ZatPoint(pos)); } thing->flags6 |= MF6_INTRYMOVE; - if (!P_CheckPosition(thing, x, y, tm)) + if (!P_CheckPosition(thing, pos, tm)) { AActor *BlockingMobj = thing->BlockingMobj; // Solid wall or thing @@ -2076,8 +1943,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, goto pushline; } else if (BlockingMobj->Top() - thing->Z() > thing->MaxStepHeight - || (BlockingMobj->Sector->ceilingplane.ZatPoint(x, y) - (BlockingMobj->Top()) < thing->height) - || (tm.ceilingz - (BlockingMobj->Top()) < thing->height)) + || (BlockingMobj->Sector->ceilingplane.ZatPoint(pos) - (BlockingMobj->Top()) < thing->Height) + || (tm.ceilingz - (BlockingMobj->Top()) < thing->Height)) { goto pushline; } @@ -2096,7 +1963,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } else if (thing->flags3 & MF3_CEILINGHUGGER) { - thing->SetZ(tm.ceilingz - thing->height); + thing->SetZ(tm.ceilingz - thing->Height); } if (onfloor && tm.floorsector == thing->floorsector) @@ -2105,7 +1972,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } if (!(thing->flags & MF_NOCLIP)) { - if (tm.ceilingz - tm.floorz < thing->height) + if (tm.ceilingz - tm.floorz < thing->Height) { goto pushline; // doesn't fit } @@ -2113,7 +1980,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, tm.floatok = true; if (!(thing->flags & MF_TELEPORT) - && tm.ceilingz - thing->Z() < thing->height + && tm.ceilingz < thing->Top() && !(thing->flags3 & MF3_CEILINGHUGGER) && (!(thing->flags2 & MF2_FLY) || !(thing->flags & MF_NOGRAVITY))) { @@ -2129,12 +1996,12 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // is not blocked. if (thing->Top() > tm.ceilingz) { - thing->vel.z = -8 * FRACUNIT; + thing->Vel.Z = -8; goto pushline; } else if (thing->Z() < tm.floorz && tm.floorz - tm.dropoffz > thing->MaxDropOffHeight) { - thing->vel.z = 8 * FRACUNIT; + thing->Vel.Z = 8; goto pushline; } #endif @@ -2151,7 +2018,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } else if (thing->Z() < tm.floorz) { // [RH] Check to make sure there's nothing in the way for the step up - fixed_t savedz = thing->Z(); + double savedz = thing->Z(); bool good; thing->SetZ(tm.floorz); good = P_TestMobjZ(thing); @@ -2164,7 +2031,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { thing->SetZ(tm.floorz); // If moving down, cancel vertical component of the velocity - if (thing->vel.z < 0) + if (thing->Vel.Z < 0) { // If it's a bouncer, let it bounce off its new floor, too. if (thing->BounceFlags & BOUNCE_Floors) @@ -2173,7 +2040,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } else { - thing->vel.z = 0; + thing->Vel.Z = 0; } } } @@ -2188,7 +2055,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } if (dropoff == 2 && // large jump down (e.g. dogs) - (tm.floorz - tm.dropoffz > 128 * FRACUNIT || thing->target == NULL || thing->target->Z() >tm.dropoffz)) + (tm.floorz - tm.dropoffz > 128. || thing->target == NULL || thing->target->Z() >tm.dropoffz)) { dropoff = false; } @@ -2199,7 +2066,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { if (!(thing->flags5&MF5_AVOIDINGDROPOFF)) { - fixed_t floorz = tm.floorz; + double floorz = tm.floorz; // [RH] If the thing is standing on something, use its current z as the floorz. // This is so that it does not walk off of things onto a drop off. if (thing->flags2 & MF2_ONMOBJ) @@ -2245,8 +2112,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { thing->player->Bot->prev = thing->player->Bot->dest; thing->player->Bot->dest = NULL; - thing->vel.x = 0; - thing->vel.y = 0; + thing->Vel.X = thing->Vel.Y = 0; thing->SetZ(oldz); thing->flags6 &= ~MF6_INTRYMOVE; return false; @@ -2258,14 +2124,14 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // it slopes or the player's eyes are bobbing in and out. bool oldAboveFakeFloor, oldAboveFakeCeiling; - fixed_t viewheight; - - viewheight = thing->player ? thing->player->viewheight : thing->height / 2; - oldAboveFakeFloor = oldAboveFakeCeiling = false; // pacify GCC + double viewheight; + // pacify GCC + viewheight = thing->player ? thing->player->viewheight : thing->Height / 2; + oldAboveFakeFloor = oldAboveFakeCeiling = false; if (oldsec->heightsec) { - fixed_t eyez = oldz + viewheight; + double eyez = oldz + viewheight; oldAboveFakeFloor = eyez > oldsec->heightsec->floorplane.ZatPoint(thing); oldAboveFakeCeiling = eyez > oldsec->heightsec->ceilingplane.ZatPoint(thing); @@ -2274,7 +2140,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // Borrowed from MBF: if (thing->BounceFlags & BOUNCE_MBF && // killough 8/13/98 !(thing->flags & (MF_MISSILE | MF_NOGRAVITY)) && - !thing->IsSentient() && tm.floorz - thing->Z() > 16 * FRACUNIT) + !thing->IsSentient() && tm.floorz - thing->Z() > 16) { // too big a step up for MBF bouncers under gravity thing->flags6 &= ~MF6_INTRYMOVE; return false; @@ -2287,7 +2153,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, while (true) { - fixed_t bestfrac = FIXED_MAX; + double bestfrac = 1.1; spechit_t besthit; int besthitnum; // find the portal nearest to the crossing actor @@ -2299,13 +2165,13 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (ld->frontsector->PortalGroup != thing->Sector->PortalGroup) continue; // must be in the same group to be considered valid. // see if the line was crossed - oldside = P_PointOnLineSide(spec.oldrefpos.x, spec.oldrefpos.y, ld); - side = P_PointOnLineSide(spec.refpos.x, spec.refpos.y, ld); + oldside = P_PointOnLineSide(spec.Oldrefpos, ld); + side = P_PointOnLineSide(spec.Refpos, ld); if (oldside == 0 && side == 1) { - divline_t dl2 = { ld->v1->x, ld->v1->y, ld->dx, ld->dy }; - divline_t dl1 = { spec.oldrefpos.x, spec.oldrefpos.y, spec.refpos.x - spec.oldrefpos.x, spec.refpos.y - spec.oldrefpos.y }; - fixed_t frac = P_InterceptVector(&dl1, &dl2); + divline_t dl2 = { ld->v1->fX(), ld->v1->fY(), ld->Delta().X, ld->Delta().Y }; + divline_t dl1 = { spec.Oldrefpos.X, spec.Oldrefpos.Y, spec.Refpos.X - spec.Oldrefpos.X, spec.Refpos.Y - spec.Oldrefpos.Y }; + double frac = P_InterceptVector(&dl1, &dl2); if (frac < bestfrac) { besthit = spec; @@ -2315,7 +2181,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } } - if (bestfrac < FIXED_MAX) + if (bestfrac < 1.1) { portalhit.Delete(besthitnum); line_t *ld = besthit.line; @@ -2323,24 +2189,23 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (port->mType == PORTT_LINKED) { thing->UnlinkFromWorld(); - thing->SetXY(tm.x + port->mXDisplacement, tm.y + port->mYDisplacement); - thing->PrevX += port->mXDisplacement; - thing->PrevY += port->mYDisplacement; + thing->SetXY(tm.pos + port->mDisplacement); + thing->Prev += port->mDisplacement; thing->LinkToWorld(); P_FindFloorCeiling(thing); portalcrossed = true; } else if (!portalcrossed) { - fixedvec3 pos = { tm.x, tm.y, thing->Z() }; - fixedvec3 oldthingpos = thing->Pos(); - fixedvec2 thingpos = oldthingpos; + DVector3 pos(tm.pos, thing->Z()); + DVector3 oldthingpos = thing->Pos(); + DVector2 thingpos = oldthingpos; - P_TranslatePortalXY(ld, pos.x, pos.y); - P_TranslatePortalXY(ld, thingpos.x, thingpos.y); - P_TranslatePortalZ(ld, pos.z); - thing->SetXYZ(thingpos.x, thingpos.y, pos.z); - if (!P_CheckPosition(thing, pos.x, pos.y, true)) // check if some actor blocks us on the other side. (No line checks, because of the mess that'd create.) + P_TranslatePortalXY(ld, pos.X, pos.Y); + P_TranslatePortalXY(ld, thingpos.X, thingpos.Y); + P_TranslatePortalZ(ld, pos.Z); + thing->SetXYZ(thingpos.X, thingpos.Y, pos.Z); + if (!P_CheckPosition(thing, pos, true)) // check if some actor blocks us on the other side. (No line checks, because of the mess that'd create.) { thing->SetXYZ(oldthingpos); thing->flags6 &= ~MF6_INTRYMOVE; @@ -2348,8 +2213,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } thing->UnlinkFromWorld(); thing->SetXYZ(pos); - P_TranslatePortalVXVY(ld, thing->vel.x, thing->vel.y); - P_TranslatePortalAngle(ld, thing->angle); + P_TranslatePortalVXVY(ld, thing->Vel.X, thing->Vel.Y); + P_TranslatePortalAngle(ld, thing->Angles.Yaw); thing->LinkToWorld(); P_FindFloorCeiling(thing); thing->ClearInterpolation(); @@ -2359,20 +2224,20 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // so that the renderer can properly calculate an interpolated position along the movement path. if (thing == players[consoleplayer].camera) { - divline_t dl1 = { besthit.oldrefpos.x,besthit. oldrefpos.y, besthit.refpos.x - besthit.oldrefpos.x, besthit.refpos.y - besthit.oldrefpos.y }; - fixedvec3a hit = { dl1.x + FixedMul(dl1.dx, bestfrac), dl1.y + FixedMul(dl1.dy, bestfrac), 0, 0 }; + divline_t dl1 = { besthit.Oldrefpos.X,besthit.Oldrefpos.Y, besthit.Refpos.X - besthit.Oldrefpos.X, besthit.Refpos.Y - besthit.Oldrefpos.Y }; + DVector3a hit = { {dl1.x + dl1.dx * bestfrac, dl1.y + dl1.dy * bestfrac, 0.},0. }; R_AddInterpolationPoint(hit); if (port->mType == PORTT_LINKED) { - hit.x += port->mXDisplacement; - hit.y += port->mYDisplacement; + hit.pos.X += port->mDisplacement.X; + hit.pos.Y += port->mDisplacement.Y; } else { - P_TranslatePortalXY(ld, hit.x, hit.y); - P_TranslatePortalZ(ld, hit.z); - players[consoleplayer].viewz += hit.z; // needs to be done here because otherwise the renderer will not catch the change. + P_TranslatePortalXY(ld, hit.pos.X, hit.pos.Y); + P_TranslatePortalZ(ld, hit.pos.Z); + players[consoleplayer].viewz += hit.pos.Z; // needs to be done here because otherwise the renderer will not catch the change. P_TranslatePortalAngle(ld, hit.angle); } R_AddInterpolationPoint(hit); @@ -2380,7 +2245,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (port->mType == PORTT_LINKED) { continue; - } + } } break; } @@ -2392,17 +2257,16 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // the move is ok, so link the thing into its new position thing->UnlinkFromWorld(); - oldpos = thing->Pos(); oldsector = thing->Sector; thing->floorz = tm.floorz; - thing->ceilingz = tm.ceilingz; + thing->ceilingz= tm.ceilingz; thing->dropoffz = tm.dropoffz; // killough 11/98: keep track of dropoffs thing->floorpic = tm.floorpic; thing->floorterrain = tm.floorterrain; thing->floorsector = tm.floorsector; thing->ceilingpic = tm.ceilingpic; thing->ceilingsector = tm.ceilingsector; - thing->SetXY(x, y); + thing->SetXY(pos); thing->LinkToWorld(); } @@ -2416,14 +2280,14 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP))) { spechit_t spec; - fixedvec3 lastpos = thing->Pos(); + DVector2 lastpos = thing->Pos(); while (spechit.Pop(spec)) { line_t *ld = spec.line; // see if the line was crossed - side = P_PointOnLineSide(spec.refpos.x, spec.refpos.y, ld); - oldside = P_PointOnLineSide(spec.oldrefpos.x, spec.oldrefpos.y, ld); + side = P_PointOnLineSide(spec.Refpos, ld); + oldside = P_PointOnLineSide(spec.Oldrefpos, ld); if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER)) { if (thing->player && (thing->player->cheats & CF_PREDICTING)) @@ -2468,8 +2332,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (newsec->heightsec && oldsec->heightsec && newsec->SecActTarget) { const sector_t *hs = newsec->heightsec; - fixed_t eyez = thing->Z() + viewheight; - fixed_t fakez = hs->floorplane.ZatPoint(x, y); + double eyez = thing->Z() + viewheight; + double fakez = hs->floorplane.ZatPoint(pos); if (!oldAboveFakeFloor && eyez > fakez) { // View went above fake floor @@ -2482,7 +2346,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (!(hs->MoreFlags & SECF_FAKEFLOORONLY)) { - fakez = hs->ceilingplane.ZatPoint(x, y); + fakez = hs->ceilingplane.ZatPoint(pos); if (!oldAboveFakeCeiling && eyez > fakez) { // View went above fake ceiling newsec->SecActTarget->TriggerAction(thing, SECSPAC_EyesAboveC); @@ -2522,19 +2386,19 @@ pushline: { // see which lines were pushed spechit_t &spec = spechit[--numSpecHitTemp]; - side = P_PointOnLineSide(spec.refpos.x, spec.refpos.y, spec.line); - CheckForPushSpecial(spec.line, side, thing, &spec.refpos); + side = P_PointOnLineSide(spec.Refpos, spec.line); + CheckForPushSpecial(spec.line, side, thing, &spec.Refpos); } } return false; } -bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, +bool P_TryMove(AActor *thing, const DVector2 &pos, int dropoff, // killough 3/15/98: allow dropoff as option const secplane_t *onfloor) // [RH] Let P_TryMove keep the thing on the floor { FCheckPosition tm; - return P_TryMove(thing, x, y, dropoff, onfloor, tm); + return P_TryMove(thing, pos, dropoff, onfloor, tm); } @@ -2546,12 +2410,12 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // //========================================================================== -bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) +bool P_CheckMove(AActor *thing, const DVector2 &pos) { FCheckPosition tm; - fixed_t newz = thing->Z(); + double newz = thing->Z(); - if (!P_CheckPosition(thing, x, y, tm)) + if (!P_CheckPosition(thing, pos, tm)) { return false; } @@ -2562,18 +2426,18 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) } else if (thing->flags3 & MF3_CEILINGHUGGER) { - newz = tm.ceilingz - thing->height; + newz = tm.ceilingz - thing->Height; } if (!(thing->flags & MF_NOCLIP)) { - if (tm.ceilingz - tm.floorz < thing->height) + if (tm.ceilingz - tm.floorz < thing->Height) { return false; } if (!(thing->flags & MF_TELEPORT) - && tm.ceilingz - newz < thing->height + && tm.ceilingz - newz < thing->Height && !(thing->flags3 & MF3_CEILINGHUGGER) && (!(thing->flags2 & MF2_FLY) || !(thing->flags & MF_NOGRAVITY))) { @@ -2596,7 +2460,7 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) } else if (newz < tm.floorz) { // [RH] Check to make sure there's nothing in the way for the step up - fixed_t savedz = thing->Z(); + double savedz = thing->Z(); thing->SetZ(newz = tm.floorz); bool good = P_TestMobjZ(thing); thing->SetZ(savedz); @@ -2629,23 +2493,22 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) struct FSlide { - fixed_t bestslidefrac; - fixed_t secondslidefrac; + double bestSlidefrac; + double secondSlidefrac; line_t* bestslideline; line_t* secondslideline; AActor* slidemo; - fixed_t tmxmove; - fixed_t tmymove; + DVector2 tmmove; void HitSlideLine(line_t *ld); - void SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy); - void SlideMove(AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps); + void SlideTraverse(const DVector2 &start, const DVector2 &end); + void SlideMove(AActor *mo, DVector2 tryp, int numsteps); // The bouncing code uses the same data structure - bool BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy); + bool BounceTraverse(const DVector2 &start, const DVector2 &end); bool BounceWall(AActor *mo); }; @@ -2662,11 +2525,11 @@ void FSlide::HitSlideLine(line_t* ld) { int side; - angle_t lineangle; - angle_t moveangle; - angle_t deltaangle; + DAngle lineangle; + DAngle moveangle; + DAngle deltaangle; - fixed_t movelen; + double movelen; bool icyfloor; // is floor icy? // phares // | // Under icy conditions, if the angle of approach to the wall // V @@ -2678,121 +2541,108 @@ void FSlide::HitSlideLine(line_t* ld) // killough 10/98: only bounce if hit hard (prevents wobbling) icyfloor = - (P_AproxDistance(tmxmove, tmymove) > 4 * FRACUNIT) && + tmmove.LengthSquared() > 4*4 && var_friction && // killough 8/28/98: calc friction on demand slidemo->Z() <= slidemo->floorz && P_GetFriction(slidemo, NULL) > ORIG_FRICTION; - if (ld->dx == 0) + if (ld->Delta().X == 0) { // ST_VERTICAL - if (icyfloor && (abs(tmxmove) > abs(tmymove))) + if (icyfloor && (fabs(tmmove.X) > fabs(tmmove.Y))) { - tmxmove = -tmxmove / 2; // absorb half the velocity - tmymove /= 2; + tmmove.X = -tmmove.X / 2; + tmmove.Y /= 2; // absorb half the velocity if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) { S_Sound(slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff!// ^ } } // | else // phares - tmxmove = 0; // no more movement in the X direction + tmmove.X = 0; // no more movement in the X direction return; } - if (ld->dy == 0) + if (ld->Delta().Y == 0) { // ST_HORIZONTAL - if (icyfloor && (abs(tmymove) > abs(tmxmove))) + if (icyfloor && (fabs(tmmove.Y) > fabs(tmmove.X))) { - tmxmove /= 2; // absorb half the velocity - tmymove = -tmymove / 2; + tmmove.X /= 2; // absorb half the velocity + tmmove.Y = -tmmove.Y / 2; if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) { S_Sound(slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! } } else - tmymove = 0; // no more movement in the Y direction + tmmove.Y = 0; // no more movement in the Y direction return; } // The wall is angled. Bounce if the angle of approach is // phares // less than 45 degrees. // phares - fixedvec3 pos = slidemo->PosRelative(ld); - side = P_PointOnLineSide(pos.x, pos.y, ld); + DVector3 pos = slidemo->PosRelative(ld); + side = P_PointOnLineSide(pos, ld); - lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy); + lineangle = ld->Delta().Angle(); if (side == 1) - lineangle += ANG180; + lineangle += 180.; - moveangle = R_PointToAngle2(0, 0, tmxmove, tmymove); + moveangle = tmmove.Angle(); - moveangle += 10; // prevents sudden path reversal due to // phares - // rounding error // | - deltaangle = moveangle - lineangle; // V - movelen = P_AproxDistance(tmxmove, tmymove); - if (icyfloor && (deltaangle > ANG45) && (deltaangle < ANG90 + ANG45)) + // prevents sudden path reversal due to rounding error | // phares + moveangle += 3600/65536.*65536.; // Boom added 10 to the angle here. + + deltaangle = ::deltaangle(lineangle, moveangle); // V + movelen = tmmove.Length(); + if (icyfloor && (deltaangle > 45) && (deltaangle < 135)) { - moveangle = lineangle - deltaangle; + moveangle = ::deltaangle(deltaangle, lineangle); movelen /= 2; // absorb if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) { S_Sound(slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! } - moveangle >>= ANGLETOFINESHIFT; - tmxmove = FixedMul(movelen, finecosine[moveangle]); - tmymove = FixedMul(movelen, finesine[moveangle]); - } // ^ - else // | - { // phares - // Doom's original algorithm here does not work well due to imprecisions of the sine table. - // However, keep it active if the wallrunning compatibility flag is on - if (i_compatflags & COMPATF_WALLRUN) + tmmove = moveangle.ToVector(movelen); + } + else + { + // The compatibility option that used to be here had to be removed because + // with floating point math it was no longer possible to reproduce. + +#if 0 + // with full precision this should work now. Needs some testing + if (deltaangle < 0) deltaangle += 180.; + tmmove = lineangle.ToVector(movelen * deltaangle.Cos()); +#else + divline_t dll, dlv; + double inter1, inter2, inter3; + + P_MakeDivline(ld, &dll); + + dlv.x = pos.X; + dlv.y = pos.Y; + dlv.dx = dll.dy; + dlv.dy = -dll.dx; + + inter1 = P_InterceptVector(&dll, &dlv); + + dlv.dx = tmmove.X; + dlv.dy = tmmove.Y; + inter2 = P_InterceptVector(&dll, &dlv); + inter3 = P_InterceptVector(&dlv, &dll); + + if (inter3 != 0) { - fixed_t newlen; - - if (deltaangle > ANG180) - deltaangle += ANG180; - // I_Error ("SlideLine: ang>ANG180"); - - lineangle >>= ANGLETOFINESHIFT; - deltaangle >>= ANGLETOFINESHIFT; - - newlen = FixedMul(movelen, finecosine[deltaangle]); - - tmxmove = FixedMul(newlen, finecosine[lineangle]); - tmymove = FixedMul(newlen, finesine[lineangle]); + tmmove.X = (inter2 - inter1) * dll.dx / inter3; + tmmove.Y = (inter2 - inter1) * dll.dy / inter3; } else { - divline_t dll, dlv; - fixed_t inter1, inter2, inter3; - - P_MakeDivline(ld, &dll); - - dlv.x = pos.x; - dlv.y = pos.y; - dlv.dx = dll.dy; - dlv.dy = -dll.dx; - - inter1 = P_InterceptVector(&dll, &dlv); - - dlv.dx = tmxmove; - dlv.dy = tmymove; - inter2 = P_InterceptVector(&dll, &dlv); - inter3 = P_InterceptVector(&dlv, &dll); - - if (inter3 != 0) - { - tmxmove = Scale(inter2 - inter1, dll.dx, inter3); - tmymove = Scale(inter2 - inter1, dll.dy, inter3); - } - else - { - tmxmove = tmymove = 0; - } + tmmove.Zero(); } +#endif } // phares } @@ -2803,10 +2653,10 @@ void FSlide::HitSlideLine(line_t* ld) // //========================================================================== -void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy) +void FSlide::SlideTraverse(const DVector2 &start, const DVector2 &end) { FLineOpening open; - FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES); + FPathTraverse it(start.X, start.Y, end.X, end.Y, PT_ADDLINES); intercept_t *in; while ((in = it.Next())) @@ -2824,8 +2674,8 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t if (!(li->flags & ML_TWOSIDED) || !li->backsector) { - fixedvec3 pos = slidemo->PosRelative(li); - if (P_PointOnLineSide(pos.x, pos.y, li)) + DVector3 pos = slidemo->PosRelative(li); + if (P_PointOnLineSide(pos, li)) { // don't hit the back side continue; @@ -2849,10 +2699,10 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t // set openrange, opentop, openbottom P_LineOpening(open, slidemo, li, it.InterceptPoint(in)); - if (open.range < slidemo->height) + if (open.range < slidemo->Height) goto isblocking; // doesn't fit - if (open.top - slidemo->Z() < slidemo->height) + if (open.top < slidemo->Top()) goto isblocking; // mobj is too high if (open.bottom - slidemo->Z() > slidemo->MaxStepHeight) @@ -2861,7 +2711,7 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t } else if (slidemo->Z() < open.bottom) { // [RH] Check to make sure there's nothing in the way for the step up - fixed_t savedz = slidemo->Z(); + double savedz = slidemo->Z(); slidemo->SetZ(open.bottom); bool good = P_TestMobjZ(slidemo); slidemo->SetZ(savedz); @@ -2877,11 +2727,11 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t // the line does block movement, // see if it is closer than best so far isblocking: - if (in->frac < bestslidefrac) + if (in->frac < bestSlidefrac) { - secondslidefrac = bestslidefrac; + secondSlidefrac = bestSlidefrac; secondslideline = bestslideline; - bestslidefrac = in->frac; + bestSlidefrac = in->frac; bestslideline = li; } @@ -2903,12 +2753,12 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t // //========================================================================== -void FSlide::SlideMove(AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) +void FSlide::SlideMove(AActor *mo, DVector2 tryp, int numsteps) { - fixed_t leadx, leady; - fixed_t trailx, traily; - fixed_t newx, newy; - fixed_t xmove, ymove; + DVector2 lead; + DVector2 trail; + DVector2 newpos; + DVector2 move; const secplane_t * walkplane; int hitcount; @@ -2923,107 +2773,104 @@ retry: goto stairstep; // don't loop forever // trace along the three leading corners - if (tryx > 0) + if (tryp.X > 0) { - leadx = mo->X() + mo->radius; - trailx = mo->X() - mo->radius; + lead.X = mo->X() + mo->radius; + trail.X = mo->X() - mo->radius; } else { - leadx = mo->X() - mo->radius; - trailx = mo->X() + mo->radius; + lead.X = mo->X() - mo->radius; + trail.X = mo->X() + mo->radius; } - if (tryy > 0) + if (tryp.Y > 0) { - leady = mo->Y() + mo->radius; - traily = mo->Y() - mo->radius; + lead.Y = mo->Y() + mo->radius; + trail.Y = mo->Y() - mo->radius; } else { - leady = mo->Y() - mo->radius; - traily = mo->Y() + mo->radius; + lead.Y = mo->Y() - mo->radius; + trail.Y = mo->Y() + mo->radius; } - bestslidefrac = FRACUNIT + 1; + bestSlidefrac = 1.01; - SlideTraverse(leadx, leady, leadx + tryx, leady + tryy); - SlideTraverse(trailx, leady, trailx + tryx, leady + tryy); - SlideTraverse(leadx, traily, leadx + tryx, traily + tryy); + SlideTraverse(lead, lead + tryp); + SlideTraverse(DVector2(trail.X, lead.Y), tryp + DVector2(trail.X, lead.Y)); + SlideTraverse(DVector2(lead.X, trail.Y), tryp + DVector2(lead.X, trail.Y)); // move up to the wall - if (bestslidefrac == FRACUNIT + 1) + if (bestSlidefrac > 1) { // the move must have hit the middle, so stairstep stairstep: // killough 3/15/98: Allow objects to drop off ledges - xmove = 0, ymove = tryy; - walkplane = P_CheckSlopeWalk(mo, xmove, ymove); - if (!P_TryMove(mo, mo->X() + xmove, mo->Y() + ymove, true, walkplane)) + move = { 0, tryp.Y }; + walkplane = P_CheckSlopeWalk(mo, move); + if (!P_TryMove(mo, mo->Pos() + move, true, walkplane)) { - xmove = tryx, ymove = 0; - walkplane = P_CheckSlopeWalk(mo, xmove, ymove); - P_TryMove(mo, mo->X() + xmove, mo->Y() + ymove, true, walkplane); + move = { tryp.X, 0 }; + walkplane = P_CheckSlopeWalk(mo, move); + P_TryMove(mo, mo->Pos() + move, true, walkplane); } return; } // fudge a bit to make sure it doesn't hit - bestslidefrac -= FRACUNIT / 32; - if (bestslidefrac > 0) + bestSlidefrac -= 1. / 32; + if (bestSlidefrac > 0) { - newx = FixedMul(tryx, bestslidefrac); - newy = FixedMul(tryy, bestslidefrac); + newpos = tryp * bestSlidefrac; // [BL] We need to abandon this function if we end up going through a teleporter - const fixed_t startvelx = mo->vel.x; - const fixed_t startvely = mo->vel.y; + const DVector2 startvel = mo->Vel.XY(); // killough 3/15/98: Allow objects to drop off ledges - if (!P_TryMove(mo, mo->X() + newx, mo->Y() + newy, true)) + if (!P_TryMove(mo, mo->Pos() + newpos, true)) goto stairstep; - if (mo->vel.x != startvelx || mo->vel.y != startvely) + if (mo->Vel.XY() != startvel) return; } // Now continue along the wall. - bestslidefrac = FRACUNIT - (bestslidefrac + FRACUNIT / 32); // remainder - if (bestslidefrac > FRACUNIT) - bestslidefrac = FRACUNIT; - else if (bestslidefrac <= 0) + bestSlidefrac = 1. - (bestSlidefrac + 1. / 32); // remainder + if (bestSlidefrac > 1) + bestSlidefrac = 1; + else if (bestSlidefrac <= 0) return; - tryx = tmxmove = FixedMul(tryx, bestslidefrac); - tryy = tmymove = FixedMul(tryy, bestslidefrac); + tryp = tmmove = tryp*bestSlidefrac; HitSlideLine(bestslideline); // clip the moves - mo->vel.x = tmxmove * numsteps; - mo->vel.y = tmymove * numsteps; + mo->Vel.X = tmmove.X * numsteps; + mo->Vel.Y = tmmove.Y * numsteps; // killough 10/98: affect the bobbing the same way (but not voodoo dolls) if (mo->player && mo->player->mo == mo) { - if (abs(mo->player->vel.x) > abs(mo->vel.x)) - mo->player->vel.x = mo->vel.x; - if (abs(mo->player->vel.y) > abs(mo->vel.y)) - mo->player->vel.y = mo->vel.y; + if (fabs(mo->player->Vel.X) > fabs(mo->Vel.X)) + mo->player->Vel.X = mo->Vel.X; + if (fabs(mo->player->Vel.Y) > fabs(mo->Vel.Y)) + mo->player->Vel.Y = mo->Vel.Y; } - walkplane = P_CheckSlopeWalk(mo, tmxmove, tmymove); + walkplane = P_CheckSlopeWalk(mo, tmmove); // killough 3/15/98: Allow objects to drop off ledges - if (!P_TryMove(mo, mo->X() + tmxmove, mo->Y() + tmymove, true, walkplane)) + if (!P_TryMove(mo, mo->Pos() + tmmove, true, walkplane)) { goto retry; } } -void P_SlideMove(AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) +void P_SlideMove(AActor *mo, const DVector2 &pos, int numsteps) { FSlide slide; - slide.SlideMove(mo, tryx, tryy, numsteps); + slide.SlideMove(mo, pos, numsteps); } //============================================================================ @@ -3032,7 +2879,7 @@ void P_SlideMove(AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps) // //============================================================================ -const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymove) +const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move) { static secplane_t copyplane; if (actor->flags & MF_NOGRAVITY) @@ -3040,21 +2887,20 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov return NULL; } - fixedvec3 pos = actor->PosRelative(actor->floorsector); + DVector3 pos = actor->PosRelative(actor->floorsector); const secplane_t *plane = &actor->floorsector->floorplane; - fixed_t planezhere = plane->ZatPoint(pos); + double planezhere = plane->ZatPoint(pos); - for (unsigned int i = 0; ifloorsector->e->XFloor.ffloors.Size(); i++) + for (auto rover : actor->floorsector->e->XFloor.ffloors) { - F3DFloor * rover = actor->floorsector->e->XFloor.ffloors[i]; if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - fixed_t thisplanez = rover->top.plane->ZatPoint(pos); + double thisplanez = rover->top.plane->ZatPoint(pos); - if (thisplanez>planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight) + if (thisplanez > planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight) { copyplane = *rover->top.plane; - if (copyplane.c<0) copyplane.FlipVert(); + if (copyplane.fC() < 0) copyplane.FlipVert(); plane = ©plane; planezhere = thisplanez; } @@ -3062,17 +2908,16 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov if (actor->floorsector != actor->Sector) { - for (unsigned int i = 0; iSector->e->XFloor.ffloors.Size(); i++) + for (auto rover : actor->Sector->e->XFloor.ffloors) { - F3DFloor * rover = actor->Sector->e->XFloor.ffloors[i]; if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - fixed_t thisplanez = rover->top.plane->ZatPoint(actor); + double thisplanez = rover->top.plane->ZatPoint(actor); - if (thisplanez>planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight) + if (thisplanez > planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight) { copyplane = *rover->top.plane; - if (copyplane.c<0) copyplane.FlipVert(); + if (copyplane.fC() < 0) copyplane.FlipVert(); plane = ©plane; planezhere = thisplanez; } @@ -3082,27 +2927,26 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov if (actor->floorsector != actor->Sector) { // this additional check prevents sliding on sloped dropoffs - if (planezhere>actor->floorz + 4 * FRACUNIT) + if (planezhere>actor->floorz + 4) return NULL; } - if (actor->Z() - planezhere > FRACUNIT) + if (actor->Z() - planezhere > 1) { // not on floor return NULL; } - if ((plane->a | plane->b) != 0) + if (plane->isSlope()) { - fixed_t destx, desty; - fixed_t t; + DVector2 dest; + double t; - destx = actor->X() + xmove; - desty = actor->Y() + ymove; - t = TMulScale16(plane->a, destx, plane->b, desty, plane->c, actor->Z()) + plane->d; + dest = actor->Pos() + move; + t = (plane->Normal() | DVector3(dest, actor->Z())) + plane->fD(); if (t < 0) { // Desired location is behind (below) the plane // (i.e. Walking up the plane) - if (plane->c < STEEPSLOPE) + if (plane->fC() < STEEPSLOPE) { // Can't climb up slopes of ~45 degrees or more if (actor->flags & MF_NOCLIP) { @@ -3113,16 +2957,14 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov const msecnode_t *node; bool dopush = true; - if (plane->c > STEEPSLOPE * 2 / 3) + if (plane->fC() > STEEPSLOPE * 2 / 3) { for (node = actor->touching_sectorlist; node; node = node->m_tnext) { sector_t *sec = node->m_sector; - if (sec->floorplane.c >= STEEPSLOPE) + if (sec->floorplane.fC() >= STEEPSLOPE) { - fixedvec3 pos = actor->PosRelative(sec); - pos.x += xmove; - pos.y += ymove; + DVector3 pos = actor->PosRelative(sec) +move; if (sec->floorplane.ZatPoint(pos) >= actor->Z() - actor->MaxStepHeight) { @@ -3134,29 +2976,27 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov } if (dopush) { - xmove = actor->vel.x = plane->a * 2; - ymove = actor->vel.y = plane->b * 2; + move = plane->Normal() * 2; + actor->Vel.X = move.X; + actor->Vel.Y = move.Y; } return (actor->floorsector == actor->Sector) ? plane : NULL; } } // Slide the desired location along the plane's normal // so that it lies on the plane's surface - destx -= FixedMul(plane->a, t); - desty -= FixedMul(plane->b, t); - xmove = destx - actor->X(); - ymove = desty - actor->Y(); + dest -= plane->Normal() * t; + move = dest - actor->Pos().XY(); return (actor->floorsector == actor->Sector) ? plane : NULL; } else if (t > 0) { // Desired location is in front of (above) the plane - if (planezhere == actor->Z()) - { // Actor's current spot is on/in the plane, so walk down it + if (actor->isAtZ(planezhere)) // it is very important not to be too precise here. + { + // Actor's current spot is on/in the plane, so walk down it // Same principle as walking up, except reversed - destx += FixedMul(plane->a, t); - desty += FixedMul(plane->b, t); - xmove = destx - actor->X(); - ymove = desty - actor->Y(); + dest += plane->Normal() * t; + move = dest - actor->Pos().XY(); return (actor->floorsector == actor->Sector) ? plane : NULL; } } @@ -3170,10 +3010,10 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov // //============================================================================ -bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy) +bool FSlide::BounceTraverse(const DVector2 &start, const DVector2 &end) { FLineOpening open; - FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES); + FPathTraverse it(start.X, start.Y, end.X, end.Y, PT_ADDLINES); intercept_t *in; while ((in = it.Next())) @@ -3195,17 +3035,17 @@ bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_ } if (!(li->flags&ML_TWOSIDED) || !li->backsector) { - if (P_PointOnLineSide(slidemo->X(), slidemo->Y(), li)) + if (P_PointOnLineSide(slidemo->Pos(), li)) continue; // don't hit the back side goto bounceblocking; } P_LineOpening(open, slidemo, li, it.InterceptPoint(in)); // set openrange, opentop, openbottom - if (open.range < slidemo->height) + if (open.range < slidemo->Height) goto bounceblocking; // doesn't fit - if (open.top - slidemo->Z() < slidemo->height) + if (open.top < slidemo->Top()) goto bounceblocking; // mobj is too high if (open.bottom > slidemo->Z()) @@ -3215,11 +3055,11 @@ bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_ // the line does block movement, see if it is closer than best so far bounceblocking: - if (in->frac < bestslidefrac) + if (in->frac < bestSlidefrac) { - secondslidefrac = bestslidefrac; + secondSlidefrac = bestSlidefrac; secondslideline = bestslideline; - bestslidefrac = in->frac; + bestSlidefrac = in->frac; bestslideline = li; } return false; // stop @@ -3235,10 +3075,10 @@ bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_ bool FSlide::BounceWall(AActor *mo) { - fixed_t leadx, leady; + DVector2 lead; int side; - angle_t lineangle, moveangle, deltaangle; - fixed_t movelen; + DAngle lineangle, moveangle, deltaangle; + double movelen; line_t *line; if (!(mo->BounceFlags & BOUNCE_Walls)) @@ -3250,28 +3090,28 @@ bool FSlide::BounceWall(AActor *mo) // // trace along the three leading corners // - if (mo->vel.x > 0) + if (mo->Vel.X > 0) { - leadx = mo->X() + mo->radius; + lead.X = mo->X() + mo->radius; } else { - leadx = mo->X() - mo->radius; + lead.X = mo->X() - mo->radius; } - if (mo->vel.y > 0) + if (mo->Vel.Y > 0) { - leady = mo->Y() + mo->radius; + lead.Y = mo->Y() + mo->radius; } else { - leady = mo->Y() - mo->radius; + lead.Y = mo->Y() - mo->radius; } - bestslidefrac = FRACUNIT + 1; + bestSlidefrac = 1.01; bestslideline = mo->BlockingLine; - if (BounceTraverse(leadx, leady, leadx + mo->vel.x, leady + mo->vel.y) && mo->BlockingLine == NULL) + if (BounceTraverse(lead, lead+mo->Vel.XY()) && mo->BlockingLine == NULL) { // Could not find a wall, so bounce off the floor/ceiling instead. - fixed_t floordist = mo->Z() - mo->floorz; - fixed_t ceildist = mo->ceilingz - mo->Z(); + double floordist = mo->Z() - mo->floorz; + double ceildist = mo->ceilingz - mo->Z(); if (floordist <= ceildist) { mo->FloorBounceMissile(mo->Sector->floorplane); @@ -3302,36 +3142,33 @@ bool FSlide::BounceWall(AActor *mo) return true; } - side = P_PointOnLineSide(mo->X(), mo->Y(), line); - lineangle = R_PointToAngle2(0, 0, line->dx, line->dy); + side = P_PointOnLineSide(mo->Pos(), line); + lineangle = line->Delta().Angle(); if (side == 1) { - lineangle += ANG180; + lineangle += 180; } - moveangle = R_PointToAngle2(0, 0, mo->vel.x, mo->vel.y); - deltaangle = (2 * lineangle) - moveangle; - mo->angle = deltaangle; + moveangle = mo->Vel.Angle(); + deltaangle = (lineangle * 2) - moveangle; + mo->Angles.Yaw = deltaangle; - deltaangle >>= ANGLETOFINESHIFT; - - movelen = fixed_t(sqrt(double(mo->vel.x)*mo->vel.x + double(mo->vel.y)*mo->vel.y)); - movelen = FixedMul(movelen, mo->wallbouncefactor); + movelen = mo->Vel.XY().Length() * mo->wallbouncefactor; FBoundingBox box(mo->X(), mo->Y(), mo->radius); if (box.BoxOnLineSide(line) == -1) { - fixedvec3 pos = mo->Vec3Offset( - FixedMul(mo->radius, finecosine[deltaangle]), - FixedMul(mo->radius, finesine[deltaangle]), 0); + DVector2 ofs = deltaangle.ToVector(mo->radius); + DVector3 pos = mo->Vec3Offset(ofs.X, ofs.Y, 0.); mo->SetOrigin(pos, true); } - if (movelen < FRACUNIT) + if (movelen < 1) { - movelen = 2 * FRACUNIT; + movelen = 2; } - mo->vel.x = FixedMul(movelen, finecosine[deltaangle]); - mo->vel.y = FixedMul(movelen, finesine[deltaangle]); + DVector2 vel = deltaangle.ToVector(movelen); + mo->Vel.X = vel.X; + mo->Vel.Y = vel.Y; if (mo->BounceFlags & BOUNCE_UseBounceState) { FState *bouncestate = mo->FindState(NAME_Bounce, NAME_Wall); @@ -3374,14 +3211,10 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) if (!ontop) { - fixed_t speed; - angle_t angle = BlockingMobj->AngleTo(mo) + ANGLE_1*((pr_bounce() % 16) - 8); - speed = P_AproxDistance(mo->vel.x, mo->vel.y); - speed = FixedMul(speed, mo->wallbouncefactor); // [GZ] was 0.75, using wallbouncefactor seems more consistent - mo->angle = angle; - angle >>= ANGLETOFINESHIFT; - mo->vel.x = FixedMul(speed, finecosine[angle]); - mo->vel.y = FixedMul(speed, finesine[angle]); + DAngle angle = BlockingMobj->AngleTo(mo) + ((pr_bounce() % 16) - 8); + double speed = mo->VelXYToSpeed() * mo->wallbouncefactor; // [GZ] was 0.75, using wallbouncefactor seems more consistent + mo->Angles.Yaw = angle; + mo->VelFromAngle(speed); mo->PlayBounceSound(true); if (mo->BounceFlags & BOUNCE_UseBounceState) { @@ -3402,11 +3235,11 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) } else { - fixed_t dot = mo->vel.z; + double dot = mo->Vel.Z; if (mo->BounceFlags & (BOUNCE_HereticType | BOUNCE_MBF)) { - mo->vel.z -= MulScale15(FRACUNIT, dot); + mo->Vel.Z -= 2. / dot; if (!(mo->BounceFlags & BOUNCE_MBF)) // Heretic projectiles die, MBF projectiles don't. { mo->flags |= MF_INBOUNCE; @@ -3416,24 +3249,24 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) } else { - mo->vel.z = FixedMul(mo->vel.z, mo->bouncefactor); + mo->Vel.Z *= mo->bouncefactor; } } else // Don't run through this for MBF-style bounces { // The reflected velocity keeps only about 70% of its original speed - mo->vel.z = FixedMul(mo->vel.z - MulScale15(FRACUNIT, dot), mo->bouncefactor); + mo->Vel.Z = (mo->Vel.Z - 2. / dot) * mo->bouncefactor; } mo->PlayBounceSound(true); if (mo->BounceFlags & BOUNCE_MBF) // Bring it to rest below a certain speed { - if (abs(mo->vel.z) < (fixed_t)(mo->Mass * mo->GetGravity() / 64)) - mo->vel.z = 0; + if (fabs(mo->Vel.Z) < mo->Mass * mo->GetGravity() / 64) + mo->Vel.Z = 0; } else if (mo->BounceFlags & (BOUNCE_AutoOff | BOUNCE_AutoOffFloorOnly)) { - if (!(mo->flags & MF_NOGRAVITY) && (mo->vel.z < 3 * FRACUNIT)) + if (!(mo->flags & MF_NOGRAVITY) && (mo->Vel.Z < 3.)) mo->BounceFlags &= ~BOUNCE_TypeMask; } } @@ -3452,13 +3285,13 @@ CVAR(Bool, aimdebug, false, 0) struct AimTarget : public FTranslatedLineTarget { - angle_t pitch; - fixed_t frac; + DAngle pitch; + double frac; void Clear() { memset(this, 0, sizeof(*this)); - frac = FIXED_MAX; + frac = FLT_MAX; } }; @@ -3470,15 +3303,15 @@ struct aim_t aim_down = 2 }; - fixed_t aimpitch; - fixed_t attackrange; - fixed_t shootz; // Height if not aiming up or down - fixed_t limitz; // height limit for portals to avoid bad setups + DAngle aimpitch; + double attackrange; + double shootz; // Height if not aiming up or down + double limitz; // height limit for portals to avoid bad setups AActor* shootthing; AActor* friender; // actor to check friendliness again AActor* aimtarget; // if we want to aim at precisely this target. - fixed_t toppitch, bottompitch; + DAngle toppitch, bottompitch; AimTarget linetarget; AimTarget thing_friend, thing_other; @@ -3488,9 +3321,9 @@ struct aim_t secplane_t * lastceilingplane; int aimdir; - fixedvec3 startpos; - fixedvec2 aimtrace; - fixed_t startfrac; + DVector3 startpos; + DVector2 aimtrace; + double startfrac; bool crossedffloors; bool unlinked; @@ -3512,24 +3345,19 @@ struct aim_t return cloned; } - // Crosing a line portal does not require a recursive call. We can just alter the current set of data - void CrossLinePortal(line_t *line) - { - } - //============================================================================ // // SetResult // //============================================================================ - void SetResult(AimTarget &res, fixed_t frac, AActor *th, fixed_t pitch) + void SetResult(AimTarget &res, double frac, AActor *th, DAngle pitch) { if (res.frac > frac) { res.linetarget = th; res.pitch = pitch; - res.angleFromSource = R_PointToAngle2(startpos.x, startpos.y, th->X(), th->Y()); + res.angleFromSource = (th->Pos() - startpos).Angle(); res.unlinked = unlinked; res.frac = frac; } @@ -3587,11 +3415,11 @@ struct aim_t if (li->frontsector->e->XFloor.ffloors.Size() || li->backsector->e->XFloor.ffloors.Size()) { F3DFloor* rover; - int highpitch, lowpitch; + DAngle highpitch, lowpitch; - fixed_t trX = trace.x + FixedMul(trace.dx, in->frac); - fixed_t trY = trace.y + FixedMul(trace.dy, in->frac); - fixed_t dist = FixedMul(attackrange, in->frac); + double trX = trace.x + trace.dx * in->frac; + double trY = trace.y + trace.dy * in->frac; + double dist = attackrange * in->frac; // 3D floor check. This is not 100% accurate but normally sufficient when // combined with a final sight check @@ -3606,12 +3434,12 @@ struct aim_t if ((rover->flags & FF_SHOOTTHROUGH) || !(rover->flags & FF_EXISTS)) continue; - fixed_t ff_bottom = rover->bottom.plane->ZatPoint(trX, trY); - fixed_t ff_top = rover->top.plane->ZatPoint(trX, trY); + double ff_bottom = rover->bottom.plane->ZatPoint(trX, trY); + double ff_top = rover->top.plane->ZatPoint(trX, trY); - highpitch = -(int)R_PointToAngle2(0, shootz, dist, ff_top); - lowpitch = -(int)R_PointToAngle2(0, shootz, dist, ff_bottom); + highpitch = -VecToAngle(dist, ff_top - shootz); + lowpitch = -VecToAngle(dist, ff_bottom - shootz); if (highpitch <= toppitch) { @@ -3631,7 +3459,7 @@ struct aim_t else if (lowpitch >= bottompitch) { // blocks lower edge of view - if (highpitchSkyBoxes[position]; - if (position == sector_t::ceiling && portal->threshold < limitz) return; - else if (position == sector_t::floor && portal->threshold > limitz) return; + if (position == sector_t::ceiling && portal->specialf1 < limitz) return; + else if (position == sector_t::floor && portal->specialf1 > limitz) return; aim_t newtrace = Clone(); newtrace.toppitch = newtoppitch; newtrace.bottompitch = newbottompitch; newtrace.aimdir = position == sector_t::ceiling? aim_t::aim_up : aim_t::aim_down; - newtrace.startpos = { startpos.x + portal->scaleX, startpos.y + portal->scaleY, startpos.z }; - newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which would produce a bogus opening - newtrace.lastsector = P_PointInSector(newtrace.startpos.x + FixedMul(aimtrace.x, newtrace.startfrac) , newtrace.startpos.y + FixedMul(aimtrace.y, newtrace.startfrac)); - newtrace.limitz = portal->threshold; + newtrace.startpos = startpos + portal->Scale; + newtrace.startfrac = frac + 1. / attackrange; // this is to skip the transition line to the portal which would produce a bogus opening + newtrace.lastsector = P_PointInSector(newtrace.startpos + aimtrace * newtrace.startfrac); + newtrace.limitz = portal->specialf1; if (aimdebug) Printf("-----Entering %s portal from sector %d to sector %d\n", position ? "ceiling" : "floor", lastsector->sectornum, newtrace.lastsector->sectornum); newtrace.AimTraverse(); @@ -3705,11 +3533,10 @@ struct aim_t //============================================================================ // // traverses a line portal - // simply calling PortalRelocate does not work here because more needs to be set up // //============================================================================ - void EnterLinePortal(line_t *li, fixed_t frac) + void EnterLinePortal(line_t *li, double frac) { aim_t newtrace = Clone(); @@ -3722,16 +3549,15 @@ struct aim_t newtrace.unlinked = (port->mType != PORTT_LINKED); newtrace.startpos = startpos; newtrace.aimtrace = aimtrace; - P_TranslatePortalXY(li, newtrace.startpos.x, newtrace.startpos.y); - P_TranslatePortalZ(li, newtrace.startpos.z); - P_TranslatePortalVXVY(li, newtrace.aimtrace.x, newtrace.aimtrace.y); + P_TranslatePortalXY(li, newtrace.startpos.X, newtrace.startpos.Y); + P_TranslatePortalZ(li, newtrace.startpos.Z); + P_TranslatePortalVXVY(li, newtrace.aimtrace.X, newtrace.aimtrace.Y); - newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which would produce a bogus opening + newtrace.startfrac = frac + 1 / attackrange; // this is to skip the transition line to the portal which would produce a bogus opening - fixed_t x = newtrace.startpos.x + FixedMul(newtrace.aimtrace.x, newtrace.startfrac); - fixed_t y = newtrace.startpos.y + FixedMul(newtrace.aimtrace.y, newtrace.startfrac); + DVector2 pos = newtrace.startpos + newtrace.aimtrace * newtrace.startfrac; - newtrace.lastsector = P_PointInSector(x, y); + newtrace.lastsector = P_PointInSector(pos); P_TranslatePortalZ(li, limitz); if (aimdebug) Printf("-----Entering line portal from sector %d to sector %d\n", lastsector->sectornum, newtrace.lastsector->sectornum); @@ -3766,9 +3592,9 @@ struct aim_t { if ((rover->flags & FF_SHOOTTHROUGH) || !(rover->flags & FF_EXISTS)) continue; - fixed_t bottomz = rover->bottom.plane->ZatPoint(startpos); + double bottomz = rover->bottom.plane->ZatPoint(startpos); - if (bottomz >= startpos.z + shootthing->height) + if (bottomz >= startpos.Z + shootthing->Height) { lastceilingplane = rover->bottom.plane; // no ceiling portal if below a 3D floor @@ -3776,43 +3602,43 @@ struct aim_t } bottomz = rover->top.plane->ZatPoint(startpos); - if (bottomz <= startpos.z) + if (bottomz <= startpos.Z) { lastfloorplane = rover->top.plane; // no floor portal if above a 3D floor floorportalstate = false; } } - if (ceilingportalstate) EnterSectorPortal(sector_t::ceiling, 0, lastsector, toppitch, MIN(0, bottompitch)); - if (floorportalstate) EnterSectorPortal(sector_t::floor, 0, lastsector, MAX(0, toppitch), bottompitch); + if (ceilingportalstate) EnterSectorPortal(sector_t::ceiling, 0, lastsector, toppitch, MIN(0., bottompitch)); + if (floorportalstate) EnterSectorPortal(sector_t::floor, 0, lastsector, MAX(0., toppitch), bottompitch); - FPathTraverse it(startpos.x, startpos.y, aimtrace.x, aimtrace.y, PT_ADDLINES | PT_ADDTHINGS | PT_COMPATIBLE | PT_DELTA, startfrac); + FPathTraverse it(startpos.X, startpos.Y, aimtrace.X, aimtrace.Y, PT_ADDLINES | PT_ADDTHINGS | PT_COMPATIBLE | PT_DELTA, startfrac); intercept_t *in; if (aimdebug) Printf("Start AimTraverse, start = %f,%f,%f, vect = %f,%f\n", - startpos.x / 65536., startpos.y / 65536., startpos.z / 65536., - aimtrace.x / 65536., aimtrace.y / 65536.); + startpos.X / 65536., startpos.Y / 65536., startpos.Z / 65536., + aimtrace.X / 65536., aimtrace.Y / 65536.); while ((in = it.Next())) { line_t* li; AActor* th; - fixed_t pitch; - fixed_t thingtoppitch; - fixed_t thingbottompitch; - fixed_t dist; - int thingpitch; + DAngle pitch; + DAngle thingtoppitch; + DAngle thingbottompitch; + double dist; + DAngle thingpitch; if (linetarget.linetarget != NULL && in->frac > linetarget.frac) return; // we already found something better in another portal section. if (in->isaline) { li = in->d.line; - int frontflag = P_PointOnLineSidePrecise(startpos.x, startpos.y, li); + int frontflag = P_PointOnLineSidePrecise(startpos, li); if (aimdebug) - Printf("Found line %d: toppitch = %f, bottompitch = %f\n", int(li - lines), ANGLE2DBL(toppitch), ANGLE2DBL(bottompitch)); + Printf("Found line %d: ___toppitch = %f, ___bottompitch = %f\n", int(li - lines), toppitch.Degrees, bottompitch.Degrees); if (li->isLinePortal() && frontflag == 0) { @@ -3827,24 +3653,24 @@ struct aim_t // Crosses a two sided line. // A two sided line will restrict the possible target ranges. FLineOpening open; - P_LineOpening(open, NULL, li, it.InterceptPoint(in), FIXED_MIN, 0, FFCF_NODROPOFF); + P_LineOpening(open, NULL, li, it.InterceptPoint(in), (DVector2*)nullptr, FFCF_NODROPOFF); // The following code assumes that portals on the front of the line have already been processed. - if (open.range <= 0 || open.bottom >= open.top) + if (open.range <= 0 || open.bottom >= open.top) return; - dist = FixedMul(attackrange, in->frac); + dist = attackrange * in->frac; - if (open.bottom != FIXED_MIN) + if (open.bottom != LINEOPEN_MIN) { - pitch = -(int)R_PointToAngle2(0, shootz, dist, open.bottom); + pitch = -VecToAngle(dist, open.bottom - shootz); if (pitch < bottompitch) bottompitch = pitch; } - if (open.top != FIXED_MAX) + if (open.top != LINEOPEN_MAX) { - pitch = -(int)R_PointToAngle2(0, shootz, dist, open.top); + pitch = -VecToAngle(dist, open.top - shootz); if (pitch > toppitch) toppitch = pitch; } @@ -3856,19 +3682,19 @@ struct aim_t return; if (aimdebug) - Printf("After line %d: toppitch = %f, bottompitch = %f, planestocheck = %d\n", int(li - lines), ANGLE2DBL(toppitch), ANGLE2DBL(bottompitch), planestocheck); + Printf("After line %d: toppitch = %f, bottompitch = %f, planestocheck = %d\n", int(li - lines), toppitch.Degrees, bottompitch.Degrees, planestocheck); sector_t *entersec = frontflag ? li->frontsector : li->backsector; sector_t *exitsec = frontflag ? li->backsector : li->frontsector; lastsector = entersec; // 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 != FIXED_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(0, bottompitch)); + EnterSectorPortal(sector_t::ceiling, in->frac, entersec, toppitch, MIN(0., bottompitch)); } - if ((planestocheck & aim_down) && bottompitch > 0 && open.bottom != FIXED_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(0, toppitch), bottompitch); + EnterSectorPortal(sector_t::floor, in->frac, entersec, MAX(0., toppitch), bottompitch); } continue; // shot continues } @@ -3900,7 +3726,7 @@ struct aim_t } } } - dist = FixedMul(attackrange, in->frac); + dist = attackrange * in->frac; // Don't autoaim certain special actors if (!cl_doautoaim && th->flags6 & MF6_NOTAUTOAIMED) @@ -3913,8 +3739,8 @@ struct aim_t { if (lastceilingplane) { - fixed_t ff_top = lastceilingplane->ZatPoint(th); - fixed_t pitch = -(int)R_PointToAngle2(0, shootz, dist, ff_top); + double ff_top = lastceilingplane->ZatPoint(th); + DAngle pitch = -VecToAngle(dist, ff_top - shootz); // upper slope intersects with this 3d-floor if (pitch > toppitch) { @@ -3923,8 +3749,8 @@ struct aim_t } if (lastfloorplane) { - fixed_t ff_bottom = lastfloorplane->ZatPoint(th); - fixed_t pitch = -(int)R_PointToAngle2(0, shootz, dist, ff_bottom); + double ff_bottom = lastfloorplane->ZatPoint(th); + DAngle pitch = -VecToAngle(dist, ff_bottom - shootz); // lower slope intersects with this 3d-floor if (pitch < bottompitch) { @@ -3935,12 +3761,12 @@ struct aim_t // check angles to see if the thing can be aimed at - thingtoppitch = -(int)R_PointToAngle2(0, shootz, dist, th->Z() + th->height); + thingtoppitch = -VecToAngle(dist, th->Top() - shootz); if (thingtoppitch > bottompitch) continue; // shot over the thing - thingbottompitch = -(int)R_PointToAngle2(0, shootz, dist, th->Z()); + thingbottompitch = -VecToAngle(dist, th->Z() - shootz); if (thingbottompitch < toppitch) continue; // shot under the thing @@ -3979,10 +3805,11 @@ struct aim_t // combination with P_LineAttack. P_LineAttack uses 3D distance but FPathTraverse // only 2D. This causes some problems with Hexen's weapons that use different // attack modes based on distance to target - fixed_t cosine = finecosine[thingpitch >> ANGLETOFINESHIFT]; + double cosine = thingpitch.Cos(); if (cosine != 0) { - fixed_t d3 = FixedDiv(FixedMul(P_AproxDistance(it.Trace().dx, it.Trace().dy), in->frac), cosine); + double tracelen = DVector2(it.Trace().dx, it.Trace().dy).Length(); + double d3 = tracelen * in->frac / cosine; if (d3 > attackrange) { return; @@ -4004,7 +3831,7 @@ struct aim_t { // friends don't aim at friends (except players), at least not first if (aimdebug) - Printf("Hit friend %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + 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); } } @@ -4014,14 +3841,14 @@ struct aim_t { // don't autoaim at barrels and other shootable stuff unless no monsters have been found if (aimdebug) - Printf("Hit other %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + 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); } } else { if (aimdebug) - Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + 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); return; } @@ -4029,7 +3856,7 @@ struct aim_t else { if (aimdebug) - Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + 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); return; } @@ -4043,17 +3870,17 @@ struct aim_t // //============================================================================ -fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslatedLineTarget *pLineTarget, fixed_t vrange, +DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLineTarget *pLineTarget, DAngle vrange, int flags, AActor *target, AActor *friender) { - fixed_t shootz = t1->Z() + (t1->height >> 1) - t1->floorclip; + double shootz = t1->Center() - t1->Floorclip; if (t1->player != NULL) { - shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor); + shootz += t1->player->mo->AttackZOffset * t1->player->crouchfactor; } else { - shootz += 8 * FRACUNIT; + shootz += 8; } // can't shoot outside view angles @@ -4061,7 +3888,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated { if (t1->player == NULL || !level.IsFreelookAllowed()) { - vrange = ANGLE_1 * 35; + vrange = 35.; } else { @@ -4069,7 +3896,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated AWeapon *weapon = t1->player->ReadyWeapon; if (weapon && (weapon->WeaponFlags & WIF_NOAUTOAIM)) { - vrange = ANGLE_1 / 2; + vrange = 0.5; } else { @@ -4077,7 +3904,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated // vrange of 0 degrees, because then toppitch and bottompitch will // be equal, and PTR_AimTraverse will never find anything to shoot at // if it crosses a line. - vrange = clamp(t1->player->userinfo.GetAimDist(), ANGLE_1 / 2, ANGLE_1 * 35); + vrange = clamp(t1->player->userinfo.GetAimDist(), 0.5, 35.); } } } @@ -4089,12 +3916,12 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated aim.friender = (friender == NULL) ? t1 : friender; aim.aimdir = aim_t::aim_up | aim_t::aim_down; aim.startpos = t1->Pos(); - aim.aimtrace = Vec2Angle(distance, angle); + aim.aimtrace = angle.ToVector(distance); aim.limitz = aim.shootz = shootz; - aim.toppitch = t1->pitch - vrange; - aim.bottompitch = t1->pitch + vrange; + aim.toppitch = t1->Angles.Pitch - vrange; + aim.bottompitch = t1->Angles.Pitch + vrange; aim.attackrange = distance; - aim.aimpitch = t1->pitch; + aim.aimpitch = t1->Angles.Pitch; aim.lastsector = t1->Sector; aim.startfrac = 0; aim.unlinked = false; @@ -4108,7 +3935,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated { *pLineTarget = *result; } - return result->linetarget ? result->pitch : t1->pitch; + return result->linetarget ? result->pitch : t1->Angles.Pitch; } @@ -4160,15 +3987,14 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata) // //========================================================================== -AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, - int pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage) +AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, + DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage) { - fixed_t vx, vy, vz, shootz; + DVector3 direction; + double shootz; FTraceResults trace; Origin TData; TData.Caller = t1; - angle_t srcangle = angle; - int srcpitch = pitch; bool killPuff = false; AActor *puff = NULL; int pflag = 0; @@ -4185,17 +4011,14 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, *actualdamage = 0; } - angle >>= ANGLETOFINESHIFT; - pitch = (angle_t)(pitch) >> ANGLETOFINESHIFT; + double pc = pitch.Cos(); - vx = FixedMul(finecosine[pitch], finecosine[angle]); - vy = FixedMul(finecosine[pitch], finesine[angle]); - vz = -finesine[pitch]; + direction = { pc * angle.Cos(), pc * angle.Sin(), -pitch.Sin() }; + shootz = t1->Center() - t1->Floorclip; - shootz = t1->Z() - t1->floorclip + (t1->height >> 1); if (t1->player != NULL) { - shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor); + shootz += t1->player->mo->AttackZOffset * t1->player->crouchfactor; if (damageType == NAME_Melee || damageType == NAME_Hitscan) { // this is coming from a weapon attack function which needs to transfer information to the obituary code, @@ -4205,7 +4028,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, } else { - shootz += 8 * FRACUNIT; + shootz += 8; } // We need to check the defaults of the replacement here @@ -4230,9 +4053,8 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) tflags = TRACE_NoSky; else tflags = TRACE_NoSky | TRACE_Impact; - if (!Trace(t1->X(), t1->Y(), shootz, t1->Sector, vx, vy, vz, distance, - MF_SHOOTABLE, ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, - tflags, CheckForActor, &TData)) + if (!Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, MF_SHOOTABLE, + ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData)) { // hit nothing if (puffDefaults == NULL) { @@ -4243,7 +4065,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, } if (puffDefaults != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) { // Spawn the puff anyway - puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleToTarget, trace.SrcAngleToTarget, 2, puffFlags); + puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget, 2, puffFlags); } else { @@ -4257,10 +4079,10 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, // position a bit closer for puffs if (trace.HitType != TRACE_HitWall || trace.Line->special != Line_Horizon) { - fixedvec2 pos = P_GetOffsetPosition(trace.HitPos.x, trace.HitPos.y, -trace.HitVector.x * 4, -trace.HitVector.y * 4); - puff = P_SpawnPuff(t1, pufftype, pos.x, pos.y, trace.HitPos.z - trace.HitVector.z * 4, trace.SrcAngleToTarget, - trace.SrcAngleToTarget - ANGLE_90, 0, puffFlags); - puff->radius = 1; + DVector2 pos = P_GetOffsetPosition(trace.HitPos.X, trace.HitPos.Y, -trace.HitVector.X * 4, -trace.HitVector.Y * 4); + puff = P_SpawnPuff(t1, pufftype, DVector3(pos, trace.HitPos.Z - trace.HitVector.Z * 4), trace.SrcAngleFromTarget, + trace.SrcAngleFromTarget - 90, 0, puffFlags); + puff->radius = 1/65536.; } // [RH] Spawn a decal @@ -4307,14 +4129,14 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, (t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD)); // Hit a thing, so it could be either a puff or blood - fixedvec3 bleedpos = trace.HitPos; + DVector3 bleedpos = trace.HitPos; // position a bit closer for puffs/blood if using compatibility mode. if (i_compatflags & COMPATF_HITSCAN) { - fixedvec2 ofs = P_GetOffsetPosition(bleedpos.x, bleedpos.y, -10 * trace.HitVector.x, -10 * trace.HitVector.y); - bleedpos.x = ofs.x; - bleedpos.y = ofs.y; - bleedpos.z -= -10 * trace.HitVector.z; + DVector2 ofs = P_GetOffsetPosition(bleedpos.X, bleedpos.Y, -10 * trace.HitVector.X, -10 * trace.HitVector.Y); + bleedpos.X = ofs.X; + bleedpos.Y = ofs.Y; + bleedpos.Z -= -10 * trace.HitVector.Z; } // Spawn bullet puffs or blood spots, depending on target type. @@ -4326,7 +4148,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, puffFlags |= PF_HITTHINGBLEED; // We must pass the unreplaced puff type here - puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 2, puffFlags | PF_HITTHING, trace.Actor); + puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 2, puffFlags | PF_HITTHING, trace.Actor); } // Allow puffs to inflict poison damage, so that hitscans can poison, too. @@ -4352,10 +4174,10 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, { // Since the puff is the damage inflictor we need it here // regardless of whether it is displayed or not. - puff = P_SpawnPuff(t1, pufftype, bleedpos, 0, 0, 2, puffFlags | PF_HITTHING | PF_TEMPORARY); + puff = P_SpawnPuff(t1, pufftype, bleedpos, 0., 0., 2, puffFlags | PF_HITTHING | PF_TEMPORARY); killPuff = true; } - newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags|DMG_USEANGLE, trace.SrcAngleToTarget); + newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags|DMG_USEANGLE, trace.SrcAngleFromTarget); if (actualdamage != NULL) { *actualdamage = newdam; @@ -4367,7 +4189,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, !(trace.Actor->flags & MF_NOBLOOD) && !(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT))) { - P_SpawnBlood(bleedpos, trace.SrcAngleToTarget, newdam > 0 ? newdam : damage, trace.Actor); + P_SpawnBlood(bleedpos, trace.SrcAngleFromTarget, newdam > 0 ? newdam : damage, trace.Actor); } if (damage) @@ -4379,23 +4201,22 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, { if (axeBlood) { - P_BloodSplatter2(bleedpos, trace.Actor); + P_BloodSplatter2(bleedpos, trace.Actor, trace.SrcAngleFromTarget); } if (pr_lineattack() < 192) { - P_BloodSplatter(bleedpos, trace.Actor); + P_BloodSplatter(bleedpos, trace.Actor, trace.SrcAngleFromTarget); } } } // [RH] Stick blood to walls - P_TraceBleed(newdam > 0 ? newdam : damage, trace.HitPos, - trace.Actor, trace.SrcAngleToTarget, srcpitch); + P_TraceBleed(newdam > 0 ? newdam : damage, trace.HitPos, trace.Actor, trace.SrcAngleFromTarget, pitch); } } if (victim != NULL) { victim->linetarget = trace.Actor; - victim->angleFromSource = trace.SrcAngleToTarget; + victim->angleFromSource = trace.SrcAngleFromTarget; victim->unlinked = trace.unlinked; } } @@ -4403,7 +4224,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, { if (puff == NULL) { // Spawn puff just to get a mass for the splash - puff = P_SpawnPuff(t1, pufftype, trace.HitPos, 0, 0, 2, puffFlags | PF_HITTHING | PF_TEMPORARY); + puff = P_SpawnPuff(t1, pufftype, trace.HitPos, 0., 0., 2, puffFlags | PF_HITTHING | PF_TEMPORARY); killPuff = true; } SpawnDeepSplash(t1, trace, puff); @@ -4417,8 +4238,8 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, return puff; } -AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, - int pitch, int damage, FName damageType, FName pufftype, int flags, FTranslatedLineTarget *victim, int *actualdamage) +AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, + DAngle pitch, int damage, FName damageType, FName pufftype, int flags, FTranslatedLineTarget *victim, int *actualdamage) { PClassActor *type = PClass::FindActor(pufftype); if (type == NULL) @@ -4442,26 +4263,22 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, // //========================================================================== -AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, - ActorFlags actorMask, DWORD wallMask) +AActor *P_LinePickActor(AActor *t1, DAngle angle, double distance, DAngle pitch, ActorFlags actorMask, DWORD wallMask) { - fixed_t vx, vy, vz, shootz; - - angle >>= ANGLETOFINESHIFT; - pitch = (angle_t)(pitch) >> ANGLETOFINESHIFT; + DVector3 direction; + double shootz; - vx = FixedMul(finecosine[pitch], finecosine[angle]); - vy = FixedMul(finecosine[pitch], finesine[angle]); - vz = -finesine[pitch]; + double pc = pitch.Cos(); + direction = { pc * angle.Cos(), pc * angle.Sin(), -pitch.Sin() }; + shootz = t1->Center() - t1->Floorclip; - shootz = t1->Z() - t1->floorclip + (t1->height >> 1); if (t1->player != NULL) { - shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor); + shootz += t1->player->mo->AttackZOffset * t1->player->crouchfactor; } else { - shootz += 8 * FRACUNIT; + shootz += 8; } FTraceResults trace; @@ -4470,7 +4287,7 @@ AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, TData.Caller = t1; TData.hitGhosts = true; - if (Trace(t1->X(), t1->Y(), shootz, t1->Sector, vx, vy, vz, distance, + if (Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, actorMask, wallMask, t1, trace, TRACE_NoSky | TRACE_PortalRestrict, CheckForActor, &TData)) { if (trace.HitType == TRACE_HitActor) @@ -4488,14 +4305,14 @@ AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, // //========================================================================== -void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, angle_t angle, int pitch) +void P_TraceBleed(int damage, const DVector3 &pos, AActor *actor, DAngle angle, DAngle pitch) { if (!cl_bloodsplats) return; const char *bloodType = "BloodSplat"; int count; - int noise; + double noise; if ((actor->flags & MF_NOBLOOD) || @@ -4505,6 +4322,7 @@ void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, an { return; } + if (damage < 15) { // For low damages, there is a chance to not spray blood at all if (damage <= 10) @@ -4515,12 +4333,12 @@ void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, an } } count = 1; - noise = 18; + noise = 11.25 / 256.; } else if (damage < 25) { count = 2; - noise = 19; + noise = 22.5 / 256.; } else { // For high damages, there is a chance to spray just one big glob of blood @@ -4528,12 +4346,12 @@ void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, an { bloodType = "BloodSmear"; count = 1; - noise = 20; + noise = 45. / 256.; } else { count = 3; - noise = 20; + noise = 45. / 256.; } } @@ -4541,15 +4359,12 @@ void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, an { FTraceResults bleedtrace; - angle_t bleedang = (angle + ((pr_tracebleed() - 128) << noise)) >> ANGLETOFINESHIFT; - angle_t bleedpitch = (angle_t)(pitch + ((pr_tracebleed() - 128) << noise)) >> ANGLETOFINESHIFT; - fixed_t vx = FixedMul(finecosine[bleedpitch], finecosine[bleedang]); - fixed_t vy = FixedMul(finecosine[bleedpitch], finesine[bleedang]); - fixed_t vz = -finesine[bleedpitch]; + DAngle bleedang = angle + (pr_tracebleed() - 128) * noise; + DAngle bleedpitch = pitch + (pr_tracebleed() - 128) * noise; + double cosp = bleedpitch.Cos(); + DVector3 vdir = DVector3(cosp * bleedang.Cos(), cosp * bleedang.Sin(), -bleedpitch.Sin()); - if (Trace(x, y, z, actor->Sector, - vx, vy, vz, 172 * FRACUNIT, 0, ML_BLOCKEVERYTHING, actor, - bleedtrace, TRACE_NoSky)) + if (Trace(pos, actor->Sector, vdir, 172, 0, ML_BLOCKEVERYTHING, actor, bleedtrace, TRACE_NoSky)) { if (bleedtrace.HitType == TRACE_HitWall) { @@ -4562,17 +4377,16 @@ void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, an bloodcolor.a = 1; } - DImpactDecal::StaticCreate(bloodType, bleedtrace.HitPos, + DImpactDecal::StaticCreate(bloodType, bleedtrace.HitPos, bleedtrace.Line->sidedef[bleedtrace.Side], bleedtrace.ffloor, bloodcolor); } } } } -void P_TraceBleed(int damage, AActor *target, angle_t angle, int pitch) +void P_TraceBleed(int damage, AActor *target, DAngle angle, DAngle pitch) { - P_TraceBleed(damage, target->X(), target->Y(), target->Z() + target->height / 2, - target, angle, pitch); + P_TraceBleed(damage, target->PosPlusZ(target->Height/2), target, angle, pitch); } //========================================================================== @@ -4583,27 +4397,25 @@ void P_TraceBleed(int damage, AActor *target, angle_t angle, int pitch) void P_TraceBleed(int damage, AActor *target, AActor *missile) { - int pitch; + DAngle pitch; if (target == NULL || missile->flags3 & MF3_BLOODLESSIMPACT) { return; } - if (missile->vel.z != 0) + if (missile->Vel.Z != 0) { double aim; - aim = atan((double)missile->vel.z / (double)target->AproxDistance(missile)); - pitch = -(int)(aim * ANGLE_180 / PI); + aim = g_atan(missile->Vel.Z / target->Distance2D(missile)); + pitch = -DAngle::ToDegrees(aim); } else { - pitch = 0; + pitch = 0.; } - P_TraceBleed(damage, target->X(), target->Y(), target->Z() + target->height / 2, - target, missile->AngleTo(target), - pitch); + P_TraceBleed(damage, target->PosPlusZ(target->Height/2), target, missile->AngleTo(target), pitch); } //========================================================================== @@ -4619,9 +4431,8 @@ void P_TraceBleed(int damage, FTranslatedLineTarget *t, AActor *puff) return; } - fixed_t randpitch = (pr_tracebleed() - 128) << 16; - P_TraceBleed(damage, t->linetarget->X(), t->linetarget->Y(), t->linetarget->Z() + t->linetarget->height / 2, - t->linetarget, t->angleFromSource, 0); + DAngle pitch = (pr_tracebleed() - 128) * (360 / 65536.); + P_TraceBleed(damage, t->linetarget->PosPlusZ(t->linetarget->Height/2), t->linetarget, t->angleFromSource, pitch); } //========================================================================== @@ -4634,11 +4445,9 @@ void P_TraceBleed(int damage, AActor *target) { if (target != NULL) { - fixed_t one = pr_tracebleed() << 24; - fixed_t two = (pr_tracebleed() - 128) << 16; - - P_TraceBleed(damage, target->X(), target->Y(), target->Z() + target->height / 2, - target, one, two); + DAngle angle = pr_tracebleed() * (360 / 256.); + DAngle pitch = (pr_tracebleed() - 128) * (360 / 65536.); + P_TraceBleed(damage, target->PosPlusZ(target->Height / 2), target, angle, pitch); } } @@ -4651,8 +4460,8 @@ void P_TraceBleed(int damage, AActor *target) struct SRailHit { AActor *HitActor; - fixedvec3 HitPos; - angle_t HitAngle; + DVector3 HitPos; + DAngle HitAngle; }; struct RailData { @@ -4687,13 +4496,13 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata) SRailHit newhit; newhit.HitActor = res.Actor; newhit.HitPos = res.HitPos; - newhit.HitAngle = res.SrcAngleToTarget; + newhit.HitAngle = res.SrcAngleFromTarget; if (i_compatflags & COMPATF_HITSCAN) { - fixedvec2 ofs = P_GetOffsetPosition(newhit.HitPos.x, newhit.HitPos.y, -10 * res.HitVector.x, -10 * res.HitVector.y); - newhit.HitPos.x = ofs.x; - newhit.HitPos.y = ofs.y; - newhit.HitPos.z -= -10 * res.HitVector.z; + DVector2 ofs = P_GetOffsetPosition(newhit.HitPos.X, newhit.HitPos.Y, -10 * res.HitVector.X, -10 * res.HitVector.Y); + newhit.HitPos.X = ofs.X; + newhit.HitPos.Y = ofs.Y; + newhit.HitPos.Z -= -10 * res.HitVector.Z; } data->RailHits.Push(newhit); @@ -4705,51 +4514,45 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata) // // //========================================================================== -void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, int color1, int color2, double maxdiff, int railflags, PClassActor *puffclass, angle_t angleoffset, angle_t pitchoffset, fixed_t distance, int duration, double sparsity, double drift, PClassActor *spawnclass, int SpiralOffset) +void P_RailAttack(FRailParams *p) { - fixed_t vx, vy, vz; - angle_t angle, pitch; - DVector3 start, end; + DVector3 start; FTraceResults trace; - fixed_t shootz; + PClassActor *puffclass = p->puff; if (puffclass == NULL) { puffclass = PClass::FindActor(NAME_BulletPuff); } - pitch = ((angle_t)(-source->pitch) + pitchoffset) >> ANGLETOFINESHIFT; - angle = (source->angle + angleoffset) >> ANGLETOFINESHIFT; + AActor *source = p->source; + DAngle pitch = -source->Angles.Pitch + p->pitchoffset; + DAngle angle = source->Angles.Yaw + p->angleoffset; - vx = FixedMul(finecosine[pitch], finecosine[angle]); - vy = FixedMul(finecosine[pitch], finesine[angle]); - vz = finesine[pitch]; + DVector3 vec(DRotator(pitch, angle, angle)); + double shootz = source->Center() - source->FloatSpeed + p->offset_z; - shootz = source->Z() - source->floorclip + (source->height >> 1) + offset_z; - - if (!(railflags & RAF_CENTERZ)) + if (!(p->flags & RAF_CENTERZ)) { if (source->player != NULL) { - shootz += FixedMul(source->player->mo->AttackZOffset, source->player->crouchfactor); + shootz += source->player->mo->AttackZOffset * source->player->crouchfactor; } else { - shootz += 8 * FRACUNIT; + shootz += 8; } } - angle = ((source->angle + angleoffset) - ANG90) >> ANGLETOFINESHIFT; - - fixedvec2 xy = source->Vec2Offset(offset_xy * finecosine[angle], offset_xy * finesine[angle]); + DVector2 xy = source->Vec2Angle(p->offset_xy, angle - 90.); RailData rail_data; rail_data.Caller = source; - rail_data.StopAtOne = !!(railflags & RAF_NOPIERCE); - start.X = FIXED2DBL(xy.x); - start.Y = FIXED2DBL(xy.y); - start.Z = FIXED2DBL(shootz); + rail_data.StopAtOne = !!(p->flags & RAF_NOPIERCE); + start.X = xy.X; + start.Y = xy.Y; + start.Z = shootz; int flags; @@ -4759,9 +4562,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i flags = (puffDefaults->flags6 & MF6_NOTRIGGER) ? 0 : TRACE_PCross | TRACE_Impact; rail_data.StopAtInvul = (puffDefaults->flags3 & MF3_FOILINVUL) ? false : true; rail_data.ThruSpecies = (puffDefaults->flags6 & MF6_MTHRUSPECIES) ? true : false; - Trace(xy.x, xy.y, shootz, source->Sector, vx, vy, vz, - distance, MF_SHOOTABLE, ML_BLOCKEVERYTHING, source, trace, - flags, ProcessRailHit, &rail_data); + Trace(start, source->Sector, vec, p->distance, MF_SHOOTABLE, ML_BLOCKEVERYTHING, source, trace, flags, ProcessRailHit, &rail_data); // Hurt anything the trace hit unsigned int i; @@ -4774,15 +4575,13 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i for (i = 0; i < rail_data.RailHits.Size(); i++) { - - bool spawnpuff; bool bleed = false; int puffflags = PF_HITTHING; AActor *hitactor = rail_data.RailHits[i].HitActor; - fixedvec3 &hitpos = rail_data.RailHits[i].HitPos; - angle_t hitangle = rail_data.RailHits[i].HitAngle; + DVector3 &hitpos = rail_data.RailHits[i].HitPos; + DAngle hitangle = rail_data.RailHits[i].HitAngle; if ((hitactor->flags & MF_NOBLOOD) || (hitactor->flags2 & MF2_DORMANT || ((hitactor->flags2 & MF2_INVULNERABLE) && !(puffDefaults->flags3 & MF3_FOILINVUL)))) @@ -4800,7 +4599,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i } if (spawnpuff) { - P_SpawnPuff(source, puffclass, hitpos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 1, puffflags, hitactor); + P_SpawnPuff(source, puffclass, hitpos, hitangle, hitangle - 90, 1, puffflags, hitactor); } int dmgFlagPass = DMG_INFLICTOR_IS_PUFF; @@ -4813,12 +4612,12 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i if (puffDefaults->flags3 & MF3_FOILINVUL) dmgFlagPass |= DMG_FOILINVUL; if (puffDefaults->flags7 & MF7_FOILBUDDHA) dmgFlagPass |= DMG_FOILBUDDHA; } - int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass|DMG_USEANGLE, hitangle); + int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, p->damage, damagetype, dmgFlagPass|DMG_USEANGLE, hitangle); if (bleed) { - P_SpawnBlood(hitpos, hitangle, newdam > 0 ? newdam : damage, hitactor); - P_TraceBleed(newdam > 0 ? newdam : damage, hitpos, hitactor, source->angle, pitch); + P_SpawnBlood(hitpos, hitangle, newdam > 0 ? newdam : p->damage, hitactor); + P_TraceBleed(newdam > 0 ? newdam : p->damage, hitpos, hitactor, hitangle, pitch); } } @@ -4829,7 +4628,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) { - puff = P_SpawnPuff(source, puffclass, trace.HitPos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 1, 0); + puff = P_SpawnPuff(source, puffclass, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 1, 0); if (puff && (trace.Line != NULL) && (trace.Line->special == Line_Horizon) && !(puff->flags3 & MF3_SKYEXPLODE)) puff->Destroy(); } @@ -4844,7 +4643,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i AActor* puff = NULL; if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) { - puff = P_SpawnPuff(source, puffclass, trace.HitPos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 1, 0); + puff = P_SpawnPuff(source, puffclass, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 1, 0); if (puff && !(puff->flags3 & MF3_SKYEXPLODE) && (((trace.HitType == TRACE_HitFloor) && (puff->floorpic == skyflatnum)) || ((trace.HitType == TRACE_HitCeiling) && (puff->ceilingpic == skyflatnum)))) @@ -4867,10 +4666,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i } // Draw the slug's trail. - end.X = FIXED2DBL(trace.HitPos.x); - end.Y = FIXED2DBL(trace.HitPos.y); - end.Z = FIXED2DBL(trace.HitPos.z); - P_DrawRailTrail(source, start, end, color1, color2, maxdiff, railflags, spawnclass, source->angle + angleoffset, duration, sparsity, drift, SpiralOffset); + P_DrawRailTrail(source, start, trace.HitPos, p->color1, p->color2, p->maxdiff, p->flags, p->spawnclass, angle, p->duration, p->sparsity, p->drift, p->SpiralOffset); } //========================================================================== @@ -4882,35 +4678,29 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i CVAR(Float, chase_height, -8.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Float, chase_dist, 90.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &CameraZ, sector_t *&CameraSector, bool &unlinked) +void P_AimCamera(AActor *t1, DVector3 &campos, sector_t *&CameraSector, bool &unlinked) { - fixed_t distance = (fixed_t)(clamp(chase_dist, 0, 30000) * FRACUNIT); - angle_t angle = (t1->angle - ANG180) >> ANGLETOFINESHIFT; - angle_t pitch = (angle_t)(t1->pitch) >> ANGLETOFINESHIFT; + double distance = clamp(chase_dist, 0, 30000); + DAngle angle = t1->Angles.Yaw - 180; + DAngle pitch = t1->Angles.Pitch; FTraceResults trace; - fixed_t vx, vy, vz, sz; + DVector3 vvec; + double sz; - vx = FixedMul(finecosine[pitch], finecosine[angle]); - vy = FixedMul(finecosine[pitch], finesine[angle]); - vz = finesine[pitch]; + double pc = pitch.Cos(); - sz = t1->Z() - t1->floorclip + t1->height + (fixed_t)(clamp(chase_height, -1000, 1000) * FRACUNIT); + vvec = { pc * angle.Cos(), pc * angle.Sin(), -pitch.Sin() }; + sz = t1->Top() - t1->Floorclip + clamp(chase_height, -1000, 1000); - if (Trace(t1->X(), t1->Y(), sz, t1->Sector, - vx, vy, vz, distance, 0, 0, NULL, trace) && - trace.Distance > 10 * FRACUNIT) + if (Trace(t1->PosAtZ(sz), t1->Sector, vvec, distance, 0, 0, NULL, trace) && + trace.Distance > 10) { // Position camera slightly in front of hit thing - fixed_t dist = trace.Distance - 5 * FRACUNIT; - CameraX = t1->X() + FixedMul(vx, dist); - CameraY = t1->Y() + FixedMul(vy, dist); - CameraZ = sz + FixedMul(vz, dist); + campos = t1->PosAtZ(sz) + vvec *(trace.Distance - 5); } else { - CameraX = trace.HitPos.x; - CameraY = trace.HitPos.y; - CameraZ = trace.HitPos.z; + campos = trace.HitPos; } CameraSector = trace.Sector; unlinked = trace.unlinked; @@ -4928,12 +4718,12 @@ void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camera bool P_TalkFacing(AActor *player) { - static const int angleofs[] = { 0, ANGLE_90 >> 4, - ANGLE_90 >> 4 }; + static const double angleofs[] = { 0, 90./16, -90./16 }; FTranslatedLineTarget t; - for (int angle : angleofs) + for (double angle : angleofs) { - P_AimLineAttack(player, player->angle + angle, TALKRANGE, &t, ANGLE_1 * 35, ALF_FORCENOSMART | ALF_CHECKCONVERSATION | ALF_PORTALRESTRICT); + P_AimLineAttack(player, player->Angles.Yaw + angle, TALKRANGE, &t, 35., ALF_FORCENOSMART | ALF_CHECKCONVERSATION | ALF_PORTALRESTRICT); if (t.linetarget != NULL) { if (t.linetarget->health > 0 && // Dead things can't talk. @@ -4957,11 +4747,11 @@ bool P_TalkFacing(AActor *player) // //========================================================================== -bool P_UseTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, bool &foundline) +bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end, bool &foundline) { - FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES | PT_ADDTHINGS); + FPathTraverse it(start.X, start.Y, end.X, end.Y, PT_ADDLINES | PT_ADDTHINGS); intercept_t *in; - fixedvec3 xpos = { startx, starty, usething->Z() }; + DVector3 xpos = { start.X, start.Y, usething->Z() }; while ((in = it.Next())) { @@ -4981,6 +4771,7 @@ bool P_UseTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t end } continue; } + if (it.PortalRelocate(in, PT_ADDLINES | PT_ADDTHINGS, &xpos)) { continue; @@ -5012,7 +4803,7 @@ bool P_UseTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t end return true; } - sec = P_PointOnLineSide(xpos.x, xpos.y, in->d.line) == 0 ? + sec = P_PointOnLineSide(xpos, in->d.line) == 0 ? in->d.line->frontsector : in->d.line->backsector; if (sec != NULL && sec->SecActTarget && @@ -5031,7 +4822,7 @@ bool P_UseTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t end continue; // not a special line, but keep checking } - if (P_PointOnLineSide(xpos.x, xpos.y, in->d.line) == 1) + if (P_PointOnLineSide(xpos, in->d.line) == 1) { if (!(in->d.line->activation & SPAC_UseBack)) { @@ -5089,9 +4880,9 @@ bool P_UseTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t end // //========================================================================== -bool P_NoWayTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy) +bool P_NoWayTraverse(AActor *usething, const DVector2 &start, const DVector2 &end) { - FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES); + FPathTraverse it(start.X, start.Y, end.X, end.Y, PT_ADDLINES); intercept_t *in; while ((in = it.Next())) @@ -5120,30 +4911,25 @@ bool P_NoWayTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t e // //========================================================================== -CVAR(Int, userange, 0, 0); - void P_UseLines(player_t *player) { bool foundline = false; // If the player is transitioning a portal, use the group that is at its vertical center. - fixedvec2 start = player->mo->GetPortalTransition(player->mo->height / 2); + DVector2 start = player->mo->GetPortalTransition(player->mo->Height / 2); // [NS] Now queries the Player's UseRange. - fixedvec2 end = start + Vec2Angle(userange > 0? fixed_t(userange<mo->UseRange, player->mo->angle); + DVector2 end = start + player->mo->Angles.Yaw.ToVector(player->mo->UseRange); // old code: - // - // P_PathTraverse ( x1, y1, x2, y2, PT_ADDLINES, PTR_UseTraverse ); - // // This added test makes the "oof" sound work on 2s lines -- killough: - if (!P_UseTraverse(player->mo, start.x, start.y, end.x, end.y, foundline)) + if (!P_UseTraverse(player->mo, start, end, foundline)) { // [RH] Give sector a chance to eat the use sector_t *sec = player->mo->Sector; int spac = SECSPAC_Use; if (foundline) spac |= SECSPAC_UseWall; if ((!sec->SecActTarget || !sec->SecActTarget->TriggerAction(player->mo, spac)) && - P_NoWayTraverse(player->mo, start.x, start.y, end.x, end.y)) + P_NoWayTraverse(player->mo, start, end)) { S_Sound(player->mo, CHAN_VOICE, "*usefail", 1, ATTN_IDLE); } @@ -5160,12 +4946,9 @@ void P_UseLines(player_t *player) bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) { - int angle; - fixed_t x1, y1, x2, y2, usedist; - - angle = PuzzleItemUser->angle >> ANGLETOFINESHIFT; - x1 = PuzzleItemUser->X(); - y1 = PuzzleItemUser->Y(); + DVector2 start; + DVector2 end; + double usedist; // [NS] If it's a Player, get their UseRange. if (PuzzleItemUser->player) @@ -5173,10 +4956,10 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) else usedist = USERANGE; - x2 = x1 + FixedMul(usedist, finecosine[angle]); - y2 = y1 + FixedMul(usedist, finesine[angle]); + start = PuzzleItemUser->GetPortalTransition(PuzzleItemUser->Height / 2); + end = PuzzleItemUser->Angles.Yaw.ToVector(usedist); - FPathTraverse it(x1, y1, x2, y2, PT_ADDLINES | PT_ADDTHINGS); + FPathTraverse it(start.X, start.Y, end.X, end.Y, PT_ADDLINES | PT_ADDTHINGS); intercept_t *in; while ((in = it.Next())) @@ -5195,7 +4978,7 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) } continue; } - if (P_PointOnLineSide(PuzzleItemUser->X(), PuzzleItemUser->Y(), in->d.line) == 1) + if (P_PointOnLineSide(PuzzleItemUser->Pos(), in->d.line) == 1) { // Don't use back sides return false; } @@ -5258,13 +5041,12 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo if (bombdistance <= 0) return; fulldamagedistance = clamp(fulldamagedistance, 0, bombdistance - 1); - fixed_t bombdistfix = bombdistance << FRACBITS; - double bombdistancefloat = 1.f / (double)(bombdistance - fulldamagedistance); + double bombdistancefloat = 1. / (double)(bombdistance - fulldamagedistance); double bombdamagefloat = (double)bombdamage; FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d); - FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistfix, bombspot->height + bombdistfix*2, bombdistfix, false, bombspot->Sector); + FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistance, bombspot->Height + bombdistance*2, bombdistance, false, bombspot->Sector); FMultiBlockThingsIterator::CheckResult cres; if (flags & RADF_SOURCEISSPOT) @@ -5311,13 +5093,13 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo // height of the thing and not the height of the map. double points; double len; - fixed_t dx, dy; + double dx, dy; double boxradius; - fixedvec2 vec = bombspot->Vec2To(thing); - dx = abs(vec.x); - dy = abs(vec.y); - boxradius = double(thing->radius); + DVector2 vec = bombspot->Vec2To(thing); + dx = fabs(vec.X); + dy = fabs(vec.Y); + boxradius = thing->radius; // The damage pattern is square, not circular. len = double(dx > dy ? dx : dy); @@ -5341,7 +5123,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo else { len -= boxradius; - len = sqrt(len*len + dz*dz); + len = g_sqrt(len*len + dz*dz); } } else @@ -5350,14 +5132,13 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo if (len < 0.f) len = 0.f; } - len /= FRACUNIT; len = clamp(len - (double)fulldamagedistance, 0, len); - points = bombdamagefloat * (1.f - len * bombdistancefloat); + points = bombdamagefloat * (1. - len * bombdistancefloat); if (thing == bombsource) { points = points * splashfactor; } - points *= thing->GetClass()->RDFactor / (float)FRACUNIT; + points *= thing->GetClass()->RDFactor; // points and bombdamage should be the same sign if (((int(points) * bombdamage) > 0) && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) @@ -5384,25 +5165,23 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo if (!(thing->flags7 & MF7_DONTTHRUST)) { - thrust = points * 0.5f / (double)thing->Mass; + thrust = points * 0.5 / (double)thing->Mass; if (bombsource == thing) { thrust *= selfthrustscale; } - vz = (double)(thing->Z() + (thing->height >> 1) - bombspot->Z()) * thrust; + vz = (thing->Center() - bombspot->Z()) * thrust; if (bombsource != thing) { - vz *= 0.5f; + vz *= 0.5; } else { - vz *= 0.8f; + vz *= 0.8; } - angle_t ang = bombspot->AngleTo(thing) >> ANGLETOFINESHIFT; - thing->vel.x += fixed_t(finecosine[ang] * thrust); - thing->vel.y += fixed_t(finesine[ang] * thrust); + thing->Thrust(bombspot->AngleTo(thing), thrust); if (!(flags & RADF_NODAMAGE)) - thing->vel.z += (fixed_t)vz; // this really doesn't work well + thing->Vel.Z += vz; // this really doesn't work well } } } @@ -5412,14 +5191,14 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo else { // [RH] Old code just for barrels - fixed_t dx, dy, dist; + double dx, dy, dist; - fixedvec2 vec = bombspot->Vec2To(thing); - dx = abs(vec.x); - dy = abs(vec.y); + DVector2 vec = bombspot->Vec2To(thing); + dx = fabs(vec.X); + dy = fabs(vec.Y); dist = dx>dy ? dx : dy; - dist = (dist - thing->radius) >> FRACBITS; + dist -= thing->radius; if (dist < 0) dist = 0; @@ -5429,11 +5208,11 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo if (P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) { // OK to damage; target is in direct path - dist = clamp(dist - fulldamagedistance, 0, dist); - int damage = Scale(bombdamage, bombdistance - dist, bombdistance); - damage = (int)((double)damage * splashfactor); + dist = clamp(dist - fulldamagedistance, 0, dist); + int damage = Scale(bombdamage, bombdistance - int(dist), bombdistance); - damage = Scale(damage, thing->GetClass()->RDFactor, FRACUNIT); + double factor = splashfactor * thing->GetClass()->RDFactor; + damage = int(damage * factor); if (damage > 0) { int newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod); @@ -5469,7 +5248,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo struct FChangePosition { sector_t *sector; - int moveamt; + double moveamt; int crushchange; bool nofit; bool movemidtex; @@ -5503,7 +5282,7 @@ bool P_AdjustFloorCeil(AActor *thing, FChangePosition *cpos) thing->flags2 |= MF2_PASSMOBJ; } - bool isgood = P_CheckPosition(thing, thing->X(), thing->Y(), tm); + bool isgood = P_CheckPosition(thing, thing->Pos(), tm); thing->floorz = tm.floorz; thing->ceilingz = tm.ceilingz; thing->dropoffz = tm.dropoffz; // killough 11/98: remember dropoffs @@ -5539,8 +5318,8 @@ void P_FindAboveIntersectors(AActor *actor) while (it.Next(&cres)) { AActor *thing = cres.thing; - fixed_t blockdist = actor->radius + thing->radius; - if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist) + double blockdist = actor->radius + thing->radius; + if (fabs(thing->X() - cres.Position.X) >= blockdist || fabs(thing->Y() - cres.Position.Y) >= blockdist) continue; if (!(thing->flags & MF_SOLID)) @@ -5595,8 +5374,8 @@ void P_FindBelowIntersectors(AActor *actor) while (it.Next(&cres)) { AActor *thing = cres.thing; - fixed_t blockdist = actor->radius + thing->radius; - if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist) + double blockdist = actor->radius + thing->radius; + if (fabs(thing->X() - cres.Position.X) >= blockdist || fabs(thing->Y() - cres.Position.Y) >= blockdist) continue; if (!(thing->flags & MF_SOLID)) @@ -5659,10 +5438,10 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos) { AActor *mo; - mo = Spawn(bloodcls, thing->PosPlusZ(thing->height / 2), ALLOW_REPLACE); + mo = Spawn(bloodcls, thing->PosPlusZ(thing->Height / 2), ALLOW_REPLACE); - mo->vel.x = pr_crunch.Random2() << 12; - mo->vel.y = pr_crunch.Random2() << 12; + mo->Vel.X = pr_crunch.Random2() / 16.; + mo->Vel.Y = pr_crunch.Random2() / 16.; if (bloodcolor != 0 && !(mo->flags2 & MF2_DONTTRANSLATE)) { mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); @@ -5671,11 +5450,10 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos) if (!(cl_bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE; } - angle_t an; - an = (M_Random() - 128) << 24; + DAngle an = (M_Random() - 128) * (360./256); if (cl_bloodtype >= 1) { - P_DrawSplash2(32, thing->X(), thing->Y(), thing->Z() + thing->height / 2, an, 2, bloodcolor); + P_DrawSplash2(32, thing->PosPlusZ(thing->Height/2), an, 2, bloodcolor); } } if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound)) @@ -5731,10 +5509,9 @@ int P_PushUp(AActor *thing, FChangePosition *cpos) // Can't push bridges or things more massive than ourself return 2; } - fixed_t oldz; - oldz = intersect->Z(); + double oldz = intersect->Z(); P_AdjustFloorCeil(intersect, cpos); - intersect->SetZ(thing->Top() + 1); + intersect->SetZ(thing->Top() + 1/65536.); if (P_PushUp(intersect, cpos)) { // Move blocked P_DoCrunch(intersect, cpos); @@ -5777,11 +5554,11 @@ int P_PushDown(AActor *thing, FChangePosition *cpos) // Can't push bridges or things more massive than ourself return 2; } - fixed_t oldz = intersect->Z(); + double oldz = intersect->Z(); P_AdjustFloorCeil(intersect, cpos); - if (oldz > thing->Z() - intersect->height) + if (oldz > thing->Z() - intersect->Height) { // Only push things down, not up. - intersect->SetZ(thing->Z() - intersect->height); + intersect->SetZ(thing->Z() - intersect->Height); if (P_PushDown(intersect, cpos)) { // Move blocked P_DoCrunch(intersect, cpos); @@ -5802,22 +5579,20 @@ int P_PushDown(AActor *thing, FChangePosition *cpos) void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) { - fixed_t oldfloorz = thing->floorz; - fixed_t oldz = thing->Z(); + double oldfloorz = thing->floorz; + double oldz = thing->Z(); P_AdjustFloorCeil(thing, cpos); if (oldfloorz == thing->floorz) return; if (thing->flags4 & MF4_ACTLIKEBRIDGE) return; // do not move bridge things - if (thing->vel.z == 0 && + if (thing->Vel.Z == 0 && (!(thing->flags & MF_NOGRAVITY) || (thing->Z() == oldfloorz && !(thing->flags & MF_NOLIFTDROP)))) { - fixed_t oldz = thing->Z(); - if ((thing->flags & MF_NOGRAVITY) || (thing->flags5 & MF5_MOVEWITHSECTOR) || - (((cpos->sector->Flags & SECF_FLOORDROP) || cpos->moveamt < 9 * FRACUNIT) + (((cpos->sector->Flags & SECF_FLOORDROP) || cpos->moveamt < 9) && thing->Z() - thing->floorz <= cpos->moveamt)) { thing->SetZ(thing->floorz); @@ -5826,7 +5601,6 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) } else if ((thing->Z() != oldfloorz && !(thing->flags & MF_NOLIFTDROP))) { - fixed_t oldz = thing->Z(); if ((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR)) { thing->AddZ(-oldfloorz + thing->floorz); @@ -5835,7 +5609,7 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) } if (thing->player && thing->player->mo == thing) { - //thing->player->viewz += thing->Z() - oldz; + thing->player->viewz += thing->Z() - oldz; } } @@ -5847,8 +5621,8 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) void PIT_FloorRaise(AActor *thing, FChangePosition *cpos) { - fixed_t oldfloorz = thing->floorz; - fixed_t oldz = thing->Z(); + double oldfloorz = thing->floorz; + double oldz = thing->Z(); P_AdjustFloorCeil(thing, cpos); @@ -5903,7 +5677,7 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos) void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) { bool onfloor; - fixed_t oldz = thing->Z(); + double oldz = thing->Z(); onfloor = thing->Z() <= thing->floorz; P_AdjustFloorCeil(thing, cpos); @@ -5916,10 +5690,9 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) return; // do not move bridge things } intersectors.Clear(); - fixed_t oldz = thing->Z(); - if (thing->ceilingz - thing->height >= thing->floorz) + if (thing->ceilingz - thing->Height >= thing->floorz) { - thing->SetZ(thing->ceilingz - thing->height); + thing->SetZ(thing->ceilingz - thing->Height); } else { @@ -5955,7 +5728,7 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos) { bool isgood = P_AdjustFloorCeil(thing, cpos); - fixed_t oldz = thing->Z(); + double oldz = thing->Z(); if (thing->flags4 & MF4_ACTLIKEBRIDGE) return; // do not move bridge things @@ -5966,11 +5739,10 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos) thing->Top() >= thing->ceilingz - cpos->moveamt && !(thing->flags & MF_NOLIFTDROP)) { - fixed_t oldz = thing->Z(); thing->SetZ(thing->floorz); if (thing->Top() > thing->ceilingz) { - thing->SetZ(thing->ceilingz - thing->height); + thing->SetZ(thing->ceilingz - thing->Height); } P_CheckFakeFloorTriggers(thing, oldz); } @@ -5979,7 +5751,7 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos) AActor *onmobj; if (!P_TestMobjZ(thing, true, &onmobj) && onmobj->Z() <= thing->Z()) { - thing->SetZ( MIN(thing->ceilingz - thing->height, onmobj->Top())); + thing->SetZ(MIN(thing->ceilingz - thing->Height, onmobj->Top())); } } if (thing->player && thing->player->mo == thing) @@ -5998,7 +5770,7 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos) // //============================================================================= -bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool isreset) +bool P_ChangeSector(sector_t *sector, int crunch, double amt, int floorOrCeil, bool isreset) { FChangePosition cpos; void(*iterator)(AActor *, FChangePosition *); @@ -6007,7 +5779,7 @@ bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool cpos.nofit = false; cpos.crushchange = crunch; - cpos.moveamt = abs(amt); + cpos.moveamt = fabs(amt); cpos.movemidtex = false; cpos.sector = sector; @@ -6143,7 +5915,7 @@ bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool { n->visited = true; // mark thing as processed - n->m_thing->UpdateWaterLevel(n->m_thing->Z(), false); + n->m_thing->UpdateWaterLevel(false); P_CheckFakeFloorTriggers(n->m_thing, n->m_thing->Z() - amt); } } @@ -6348,7 +6120,7 @@ void P_DelSeclist(msecnode_t *node) // //============================================================================= -void P_CreateSecNodeList(AActor *thing, fixed_t x, fixed_t y) +void P_CreateSecNodeList(AActor *thing) { msecnode_t *node; @@ -6370,13 +6142,7 @@ void P_CreateSecNodeList(AActor *thing, fixed_t x, fixed_t y) while ((ld = it.Next())) { - if (box.Right() <= ld->bbox[BOXLEFT] || - box.Left() >= ld->bbox[BOXRIGHT] || - box.Top() <= ld->bbox[BOXBOTTOM] || - box.Bottom() >= ld->bbox[BOXTOP]) - continue; - - if (box.BoxOnLineSide(ld) != -1) + if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) continue; // This line crosses through the object. @@ -6455,7 +6221,7 @@ void SpawnShootDecal(AActor *t1, const FTraceResults &trace) static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff) { - const fixedvec3 *hitpos; + const DVector3 *hitpos; if (trace.Crossed3DWater) { hitpos = &trace.Crossed3DWaterPos; @@ -6466,7 +6232,7 @@ static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff } else return; - P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitpos->x, hitpos->y), *hitpos); + P_HitWater(puff != NULL ? puff : t1, P_PointInSector(*hitpos), *hitpos); } //============================================================================= diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 2670ead2c..97c2af104 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -46,8 +46,8 @@ #include "po_man.h" static AActor *RoughBlockCheck (AActor *mo, int index, void *); -static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node); -sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y); +sector_t *P_PointInSectorBuggy(double x, double y); +int P_VanillaPointOnDivlineSide(double x, double y, const divline_t* line); //========================================================================== @@ -58,7 +58,7 @@ sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y); // //========================================================================== -fixed_t P_AproxDistance (fixed_t dx, fixed_t dy) +int P_AproxDistance (int dx, int dy) { dx = abs(dx); dy = abs(dy); @@ -73,68 +73,29 @@ fixed_t P_AproxDistance (fixed_t dx, fixed_t dy) // //========================================================================== -fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1) +double P_InterceptVector(const divline_t *v2, const divline_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->x - v2->x)*v1->dy + (SQWORD)(v2->y - v1->y)*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->x - v2->x)>>8 ,v1->dy ) - +FixedMul ( (v2->y - v1->y)>>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; - + double v1x = v1->x; + double v1y = v1->y; + double v1dx = v1->dx; + double v1dy = v1->dy; + double v2x = v2->x; + double v2y = v2->y; + double v2dx = v2->dx; + double v2dy = 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 + return num / den; } - //========================================================================== // // P_LineOpening @@ -144,13 +105,12 @@ fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1) // //========================================================================== -void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, - fixed_t x, fixed_t y, fixed_t refx, fixed_t refy, int flags) +void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, const DVector2 &pos, const DVector2 *ref, int flags) { if (!(flags & FFCF_ONLY3DFLOORS)) { sector_t *front, *back; - fixed_t fc = 0, ff = 0, bc = 0, bf = 0; + double fc = 0, ff = 0, bc = 0, bf = 0; if (linedef->backsector == NULL) { @@ -164,16 +124,16 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, if (!(flags & FFCF_NOPORTALS) && (linedef->flags & ML_PORTALCONNECT)) { - if (!linedef->frontsector->PortalBlocksMovement(sector_t::ceiling)) fc = FIXED_MAX; - if (!linedef->backsector->PortalBlocksMovement(sector_t::ceiling)) bc = FIXED_MAX; - if (!linedef->frontsector->PortalBlocksMovement(sector_t::floor)) ff = FIXED_MIN; - if (!linedef->backsector->PortalBlocksMovement(sector_t::floor)) bf = FIXED_MIN; + if (!linedef->frontsector->PortalBlocksMovement(sector_t::ceiling)) fc = LINEOPEN_MAX; + if (!linedef->backsector->PortalBlocksMovement(sector_t::ceiling)) bc = LINEOPEN_MAX; + if (!linedef->frontsector->PortalBlocksMovement(sector_t::floor)) ff = LINEOPEN_MIN; + if (!linedef->backsector->PortalBlocksMovement(sector_t::floor)) bf = LINEOPEN_MIN; } - if (fc == 0) fc = front->ceilingplane.ZatPoint(x, y); - if (bc == 0) bc = back->ceilingplane.ZatPoint(x, y); - if (ff == 0) ff = front->floorplane.ZatPoint(x, y); - if (bf == 0) bf = back->floorplane.ZatPoint(x, y); + if (fc == 0) fc = front->ceilingplane.ZatPoint(pos); + if (bc == 0) bc = back->ceilingplane.ZatPoint(pos); + if (ff == 0) ff = front->floorplane.ZatPoint(pos); + if (bf == 0) bf = back->floorplane.ZatPoint(pos); /*Printf ("]]]]]] %d %d\n", ff, bf);*/ @@ -189,18 +149,18 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, // that imprecisions in the plane equation mean there is a // good chance that even if a slope and non-slope look like // they line up, they won't be perfectly aligned. - if (ff == FIXED_MIN || bf == FIXED_MIN || (refx == FIXED_MIN || abs (ff-bf) > 256)) + if (ff == -FLT_MIN || bf == -FLT_MIN || ref == NULL || fabs (ff-bf) > 1./256) { usefront = (ff > bf); } else { - if ((front->floorplane.a | front->floorplane.b) == 0) + if (!front->floorplane.isSlope()) usefront = true; - else if ((back->floorplane.a | front->floorplane.b) == 0) + else if (!back->floorplane.isSlope()) usefront = false; else - usefront = !P_PointOnLineSide (refx, refy, linedef); + usefront = !P_PointOnLineSide (*ref, linedef); } if (usefront) @@ -209,12 +169,12 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, open.bottomsec = front; open.floorpic = front->GetTexture(sector_t::floor); open.floorterrain = front->GetTerrain(sector_t::floor); - if (bf != FIXED_MIN) open.lowfloor = bf; + if (bf != -FLT_MIN) open.lowfloor = bf; else if (!(flags & FFCF_NODROPOFF)) { // We must check through the portal for the actual dropoff. // If there's no lines in the lower sections we'd never get a usable value otherwise. - open.lowfloor = back->NextLowestFloorAt(refx, refy, back->SkyBoxes[sector_t::floor]->threshold-1); + open.lowfloor = back->NextLowestFloorAt(pos.X, pos.Y, back->SkyBoxes[sector_t::floor]->specialf1-1); } } else @@ -223,12 +183,12 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, open.bottomsec = back; open.floorpic = back->GetTexture(sector_t::floor); open.floorterrain = back->GetTerrain(sector_t::floor); - if (ff != FIXED_MIN) open.lowfloor = ff; + if (ff != -FLT_MIN) open.lowfloor = ff; else if (!(flags & FFCF_NODROPOFF)) { // We must check through the portal for the actual dropoff. // If there's no lines in the lower sections we'd never get a usable value otherwise. - open.lowfloor = front->NextLowestFloorAt(refx, refy, front->SkyBoxes[sector_t::floor]->threshold - 1); + open.lowfloor = front->NextLowestFloorAt(pos.X, pos.Y, front->SkyBoxes[sector_t::floor]->specialf1 - 1); } } open.frontfloorplane = front->floorplane; @@ -238,20 +198,20 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, { // Dummy stuff to have some sort of opening for the 3D checks to modify open.topsec = NULL; open.ceilingpic.SetInvalid(); - open.top = FIXED_MAX; + open.top = LINEOPEN_MAX; open.bottomsec = NULL; open.floorpic.SetInvalid(); open.floorterrain = -1; - open.bottom = FIXED_MIN; - open.lowfloor = FIXED_MAX; - open.frontfloorplane.SetAtHeight(FIXED_MIN, sector_t::floor); - open.backfloorplane.SetAtHeight(FIXED_MIN, sector_t::floor); + open.bottom = LINEOPEN_MIN; + open.lowfloor = LINEOPEN_MAX; + open.frontfloorplane.SetAtHeight(LINEOPEN_MIN, sector_t::floor); + open.backfloorplane.SetAtHeight(LINEOPEN_MIN, sector_t::floor); } // Check 3D floors if (actor != NULL) { - P_LineOpening_XFloors(open, actor, linedef, x, y, refx, refy, !!(flags & FFCF_3DRESTRICT)); + P_LineOpening_XFloors(open, actor, linedef, pos.X, pos.Y, !!(flags & FFCF_3DRESTRICT)); } if (actor != NULL && linedef->frontsector != NULL && linedef->backsector != NULL && @@ -265,7 +225,7 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, } // avoid overflows in the opening. - open.range = (fixed_t)MIN((SQWORD)open.top - open.bottom, FIXED_MAX); + open.range = clamp(open.top - open.bottom, LINEOPEN_MIN, LINEOPEN_MAX); } @@ -353,8 +313,8 @@ bool AActor::FixMapthingPos() { sector_t *secstart = P_PointInSectorBuggy(X(), Y()); - int blockx = GetSafeBlockX(X() - bmaporgx); - int blocky = GetSafeBlockY(Y() - bmaporgy); + int blockx = GetBlockX(X()); + int blocky = GetBlockY(Y()); bool success = false; if ((unsigned int)blockx < (unsigned int)bmapwidth && @@ -388,37 +348,36 @@ bool AActor::FixMapthingPos() // Get the exact distance to the line divline_t dll, dlv; - fixed_t linelen = (fixed_t)sqrt((double)ldef->dx*ldef->dx + (double)ldef->dy*ldef->dy); + double linelen = ldef->Delta().Length(); P_MakeDivline(ldef, &dll); dlv.x = X(); dlv.y = Y(); - dlv.dx = FixedDiv(dll.dy, linelen); - dlv.dy = -FixedDiv(dll.dx, linelen); + dlv.dx = dll.dy / linelen; + dlv.dy = -dll.dx / linelen; - fixed_t distance = abs(P_InterceptVector(&dlv, &dll)); + double distance = fabs(P_InterceptVector(&dlv, &dll)); if (distance < radius) { - DPrintf("%s at (%d,%d) lies on %s line %td, distance = %f\n", - this->GetClass()->TypeName.GetChars(), X() >> FRACBITS, Y() >> FRACBITS, - ldef->dx == 0 ? "vertical" : ldef->dy == 0 ? "horizontal" : "diagonal", - ldef - lines, FIXED2DBL(distance)); - angle_t finean = R_PointToAngle2(0, 0, ldef->dx, ldef->dy); + DPrintf("%s at (%f,%f) lies on %s line %td, distance = %f\n", + this->GetClass()->TypeName.GetChars(), X(), Y(), + ldef->Delta().X == 0 ? "vertical" : ldef->Delta().Y == 0 ? "horizontal" : "diagonal", + ldef - lines, distance); + DAngle ang = ldef->Delta().Angle(); if (ldef->backsector != NULL && ldef->backsector == secstart) { - finean += ANGLE_90; + ang += 90.; } else { - finean -= ANGLE_90; + ang -= 90.; } - finean >>= ANGLETOFINESHIFT; // Get the distance we have to move the object away from the wall distance = radius - distance; - SetXY(X() + FixedMul(distance, finecosine[finean]), Y() + FixedMul(distance, finesine[finean])); + SetXY(Pos().XY() + ang.ToVector(distance)); ClearInterpolation(); success = true; } @@ -446,7 +405,7 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) { if (!spawningmapthing || numgamenodes == 0) { - sector = P_PointInSector(X(), Y()); + sector = P_PointInSector(Pos()); } else { @@ -455,7 +414,7 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) } Sector = sector; - subsector = R_PointInSubsector(X(), 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)) { @@ -482,7 +441,7 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) // When a node is deleted, its sector links (the links starting // at sector_t->touching_thinglist) are broken. When a node is // added, new sector links are created. - P_CreateSecNodeList(this, X(), Y()); + P_CreateSecNodeList(this); touching_sectorlist = sector_list; // Attach to thing sector_list = NULL; // clear for next time } @@ -497,12 +456,12 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) for (int i = -1; i < (int)check.Size(); i++) { - fixedvec3 pos = i==-1? Pos() : PosRelative(check[i]); + DVector3 pos = i==-1? Pos() : PosRelative(check[i]); - int x1 = GetSafeBlockX(pos.x - radius - bmaporgx); - int x2 = GetSafeBlockX(pos.x + radius - bmaporgx); - int y1 = GetSafeBlockY(pos.y - radius - bmaporgy); - int y2 = GetSafeBlockY(pos.y + radius - bmaporgy); + int x1 = GetBlockX(pos.X - radius); + int x2 = GetBlockX(pos.X + radius); + int y1 = GetBlockY(pos.Y - radius); + int y2 = GetBlockY(pos.Y + radius); if (x1 >= bmapwidth || x2 < 0 || y1 >= bmapheight || y2 < 0) { // thing is off the map @@ -542,10 +501,10 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) } } -void AActor::SetOrigin (fixed_t ix, fixed_t iy, fixed_t iz, bool moving) +void AActor::SetOrigin(double x, double y, double z, bool moving) { UnlinkFromWorld (); - SetXYZ(ix, iy, iz); + SetXYZ(x, y, z); LinkToWorld (); P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS); if (!moving) ClearInterpolation(); @@ -616,10 +575,10 @@ FBlockLinesIterator::FBlockLinesIterator(int _minx, int _miny, int _maxx, int _m void FBlockLinesIterator::init(const FBoundingBox &box) { validcount++; - maxy = GetSafeBlockY(box.Top() - bmaporgy); - miny = GetSafeBlockY(box.Bottom() - bmaporgy); - maxx = GetSafeBlockX(box.Right() - bmaporgx); - minx = GetSafeBlockX(box.Left() - bmaporgx); + maxy = GetBlockY(box.Top()); + miny = GetBlockY(box.Bottom()); + maxx = GetBlockX(box.Right()); + minx = GetBlockX(box.Left()); Reset(); } @@ -734,28 +693,26 @@ line_t *FBlockLinesIterator::Next() // //=========================================================================== -FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius) +FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, double checkradius) : checklist(check) { checkpoint = origin->Pos(); if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist); - checkpoint.z = checkradius == -1? origin->radius : checkradius; + checkpoint.Z = checkradius == -1? origin->radius : checkradius; basegroup = origin->Sector->PortalGroup; startsector = origin->Sector; Reset(); } -FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, sector_t *newsec) +FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, sector_t *newsec) : checklist(check) { - checkpoint.x = checkx; - checkpoint.y = checky; - checkpoint.z = checkz; + checkpoint = { checkx, checky, checkz }; if (newsec == NULL) newsec = P_PointInSector(checkx, checky); startsector = newsec; basegroup = newsec->PortalGroup; if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist); - checkpoint.z = checkradius; + checkpoint.Z = checkradius; Reset(); } @@ -765,7 +722,7 @@ FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, fix // //=========================================================================== -bool FMultiBlockLinesIterator::GoUp(fixed_t x, fixed_t y) +bool FMultiBlockLinesIterator::GoUp(double x, double y) { if (continueup) { @@ -786,7 +743,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) { @@ -813,8 +770,8 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) if (line != NULL) { item->line = line; - item->position.x = offset.x; - item->position.y = offset.y; + item->Position.X = offset.X; + item->Position.Y = offset.Y; item->portalflags = portalflags; return true; } @@ -824,19 +781,19 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) if (portalflags == FFCF_NOFLOOR && nextflags != FPortalGroupArray::UPPER) { // if this is the last upper portal in the list, check if we need to go further up to find the real ceiling. - if (GoUp(offset.x, offset.y)) return Next(item); + if (GoUp(offset.X, offset.Y)) return Next(item); } else if (portalflags == FFCF_NOCEILING && nextflags != FPortalGroupArray::LOWER) { // if this is the last lower portal in the list, check if we need to go further down to find the real floor. - if (GoDown(offset.x, offset.y)) return Next(item); + if (GoDown(offset.X, offset.Y)) return Next(item); } if (onlast) { cursector = startsector; // We reached the end of the list. Check if we still need to check up- and downwards. - if (GoUp(checkpoint.x, checkpoint.y) || - GoDown(checkpoint.x, checkpoint.y)) + if (GoUp(checkpoint.X, checkpoint.Y) || + GoDown(checkpoint.X, checkpoint.Y)) { return Next(item); } @@ -871,10 +828,10 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) void FMultiBlockLinesIterator::startIteratorForGroup(int group) { offset = Displacements.getOffset(basegroup, group); - offset.x += checkpoint.x; - offset.y += checkpoint.y; - cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset.x, offset.y); - bbox.setBox(offset.x, offset.y, checkpoint.z); + offset.X += checkpoint.X; + offset.Y += checkpoint.Y; + cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset); + bbox.setBox(offset.X, offset.Y, checkpoint.Z); blockIterator.init(bbox); } @@ -920,10 +877,10 @@ FBlockThingsIterator::FBlockThingsIterator(int _minx, int _miny, int _maxx, int void FBlockThingsIterator::init(const FBoundingBox &box) { - maxy = GetSafeBlockY(box.Top() - bmaporgy); - miny = GetSafeBlockY(box.Bottom() - bmaporgy); - maxx = GetSafeBlockX(box.Right() - bmaporgx); - minx = GetSafeBlockX(box.Left() - bmaporgx); + maxy = GetBlockY(box.Top()); + miny = GetBlockY(box.Bottom()); + maxx = GetBlockX(box.Right()); + minx = GetBlockX(box.Left()); ClearHash(); Reset(); } @@ -1001,10 +958,10 @@ AActor *FBlockThingsIterator::Next(bool centeronly) if (centeronly) { // Block boundaries for compatibility mode - fixed_t blockleft = (curx << MAPBLOCKSHIFT) + bmaporgx; - fixed_t blockright = blockleft + MAPBLOCKSIZE; - fixed_t blockbottom = (cury << MAPBLOCKSHIFT) + bmaporgy; - fixed_t blocktop = blockbottom + MAPBLOCKSIZE; + double blockleft = (curx * MAPBLOCKUNITS) + bmaporgx; + double blockright = blockleft + MAPBLOCKUNITS; + double blockbottom = (cury * MAPBLOCKUNITS) + bmaporgy; + double blocktop = blockbottom + MAPBLOCKUNITS; // only return actors with the center in this block if (me->X() >= blockleft && me->X() < blockright && @@ -1069,26 +1026,26 @@ AActor *FBlockThingsIterator::Next(bool centeronly) // //=========================================================================== -FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius, bool ignorerestricted) +FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, double checkradius, bool ignorerestricted) : checklist(check) { checkpoint = origin->Pos(); if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist); - checkpoint.z = checkradius == -1? origin->radius : checkradius; + checkpoint.Z = checkradius == -1? origin->radius : checkradius; basegroup = origin->Sector->PortalGroup; Reset(); } -FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted, sector_t *newsec) +FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec) : checklist(check) { - checkpoint.x = checkx; - checkpoint.y = checky; - checkpoint.z = checkz; + checkpoint.X = checkx; + checkpoint.Y = checky; + checkpoint.Z = checkz; if (newsec == NULL) newsec = P_PointInSector(checkx, checky); basegroup = newsec->PortalGroup; if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist); - checkpoint.z = checkradius; + checkpoint.Z = checkradius; Reset(); } @@ -1104,7 +1061,7 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite if (thing != NULL) { item->thing = thing; - item->position = checkpoint + Displacements.getOffset(basegroup, thing->Sector->PortalGroup); + item->Position = checkpoint + Displacements.getOffset(basegroup, thing->Sector->PortalGroup); item->portalflags = portalflags; return true; } @@ -1143,10 +1100,10 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite void FMultiBlockThingsIterator::startIteratorForGroup(int group) { - fixedvec2 offset = Displacements.getOffset(basegroup, group); - offset.x += checkpoint.x; - offset.y += checkpoint.y; - bbox.setBox(offset.x, offset.y, checkpoint.z); + DVector2 offset = Displacements.getOffset(basegroup, group); + offset.X += checkpoint.X; + offset.Y += checkpoint.Y; + bbox.setBox(offset.X, offset.Y, checkpoint.Z); blockIterator.init(bbox); } @@ -1193,23 +1150,11 @@ void FPathTraverse::AddLineIntercepts(int bx, int by) { int s1; int s2; - fixed_t frac; + double frac; divline_t dl; - // avoid precision problems with two routines - if ( trace.dx > FRACUNIT*16 - || trace.dy > FRACUNIT*16 - || trace.dx < -FRACUNIT*16 - || trace.dy < -FRACUNIT*16) - { - s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace); - s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace); - } - else - { - s1 = P_PointOnLineSide (trace.x, trace.y, ld); - s2 = P_PointOnLineSide (trace.x+trace.dx, trace.y+trace.dy, ld); - } + s1 = P_PointOnDivlineSide (ld->v1->fX(), ld->v1->fY(), &trace); + s2 = P_PointOnDivlineSide (ld->v2->fX(), ld->v2->fY(), &trace); if (s1 == s2) continue; // line isn't crossed @@ -1217,7 +1162,7 @@ void FPathTraverse::AddLineIntercepts(int bx, int by) P_MakeDivline (ld, &dl); frac = P_InterceptVector (&trace, &dl); - if (frac < startfrac || frac > FRACUNIT) continue; // behind source or beyond end point + if (frac < Startfrac || frac > 1.) continue; // behind source or beyond end point intercept_t newintercept; @@ -1260,81 +1205,82 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it switch (i) { case 0: // Top edge - line.x = thing->X() + thing->radius; line.y = thing->Y() + thing->radius; + if (trace.y < line.y) continue; + line.x = thing->X() + thing->radius; line.dx = -thing->radius * 2; line.dy = 0; break; case 1: // Right edge line.x = thing->X() + thing->radius; + if (trace.x < line.x) continue; line.y = thing->Y() - thing->radius; line.dx = 0; line.dy = thing->radius * 2; break; case 2: // Bottom edge - line.x = thing->X() - thing->radius; line.y = thing->Y() - thing->radius; + if (trace.y > line.y) continue; + line.x = thing->X() - thing->radius; line.dx = thing->radius * 2; line.dy = 0; break; case 3: // Left edge line.x = thing->X() - thing->radius; + if (trace.x > line.x) continue; line.y = thing->Y() + thing->radius; line.dx = 0; line.dy = thing->radius * -2; break; } // Check if this side is facing the trace origin - if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &line) == 0) + numfronts++; + + // If it is, see if the trace crosses it + if (P_PointOnDivlineSide (line.x, line.y, &trace) != + P_PointOnDivlineSide (line.x + line.dx, line.y + line.dy, &trace)) { - numfronts++; - - // If it is, see if the trace crosses it - if (P_PointOnDivlineSidePrecise (line.x, line.y, &trace) != - P_PointOnDivlineSidePrecise (line.x + line.dx, line.y + line.dy, &trace)) - { - // It's a hit - fixed_t frac = P_InterceptVector (&trace, &line); - if (frac < startfrac) - { // behind source - if (startfrac > 0) + // It's a hit + double frac = P_InterceptVector (&trace, &line); + if (frac < Startfrac) + { // behind source + if (Startfrac > 0) + { + // check if the trace starts within this actor + switch (i) { - // check if the trace starts within this actor - switch (i) - { - case 0: - line.y -= 2 * thing->radius; - break; + case 0: + line.y -= 2 * thing->radius; + break; - case 1: - line.x -= 2 * thing->radius; - break; + case 1: + line.x -= 2 * thing->radius; + break; - case 2: - line.y += 2 * thing->radius; - break; + case 2: + line.y += 2 * thing->radius; + break; - case 3: - line.x += 2 * thing->radius; - break; - } - fixed_t frac2 = P_InterceptVector(&trace, &line); - if (frac2 >= startfrac) goto addit; + case 3: + line.x += 2 * thing->radius; + break; } - continue; + double frac2 = P_InterceptVector(&trace, &line); + if (frac2 >= Startfrac) goto addit; } - addit: - intercept_t newintercept; - newintercept.frac = frac; - newintercept.isaline = false; - newintercept.done = false; - newintercept.d.thing = thing; - intercepts.Push (newintercept); continue; } + addit: + intercept_t newintercept; + newintercept.frac = frac; + newintercept.isaline = false; + newintercept.done = false; + newintercept.d.thing = thing; + intercepts.Push (newintercept); + break; } } @@ -1353,12 +1299,12 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it else { // Old code for compatibility purposes - fixed_t x1, y1, x2, y2; + double x1, y1, x2, y2; int s1, s2; 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 if (tracepositive) @@ -1390,7 +1336,7 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it frac = P_InterceptVector (&trace, &dl); - if (frac >= startfrac) + if (frac >= Startfrac) { intercept_t newintercept; newintercept.frac = frac; @@ -1415,7 +1361,7 @@ intercept_t *FPathTraverse::Next() { intercept_t *in = NULL; - fixed_t dist = FIXED_MAX; + double dist = FLT_MAX; for (unsigned scanpos = intercept_index; scanpos < intercepts.Size (); scanpos++) { intercept_t *scan = &intercepts[scanpos]; @@ -1426,7 +1372,7 @@ intercept_t *FPathTraverse::Next() } } - if (dist > FRACUNIT || in == NULL) return NULL; // checked everything in range + if (dist > 1. || in == NULL) return NULL; // checked everything in range in->done = true; return in; } @@ -1438,19 +1384,12 @@ intercept_t *FPathTraverse::Next() // //=========================================================================== -void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac) +void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags, double startfrac) { - fixed_t xt1, xt2; - fixed_t yt1, yt2; - long long _x1, _x2, _y1, _y2; - - fixed_t xstep; - fixed_t ystep; - - fixed_t partialx, partialy; - - fixed_t xintercept; - fixed_t yintercept; + double xt1, yt1, xt2, yt2; + double xstep, ystep; + double partialx, partialy; + double xintercept, yintercept; int mapx; int mapy; @@ -1474,8 +1413,8 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl } if (startfrac > 0) { - fixed_t startdx = FixedMul(trace.dx, startfrac); - fixed_t startdy = FixedMul(trace.dy, startfrac); + double startdx = trace.dx * startfrac; + double startdy = trace.dy * startfrac; x1 += startdx; y1 += startdy; @@ -1486,113 +1425,101 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl validcount++; intercept_index = intercepts.Size(); - this->startfrac = startfrac; - - if ( ((x1-bmaporgx)&(MAPBLOCKSIZE-1)) == 0) - x1 += FRACUNIT; // don't side exactly on a line - - if ( ((y1-bmaporgy)&(MAPBLOCKSIZE-1)) == 0) - y1 += FRACUNIT; // don't side exactly on a line - - _x1 = (long long)x1 - bmaporgx; - _y1 = (long long)y1 - bmaporgy; - x1 -= bmaporgx; - y1 -= bmaporgy; - xt1 = int(_x1 >> MAPBLOCKSHIFT); - yt1 = int(_y1 >> MAPBLOCKSHIFT); + Startfrac = startfrac; if (flags & PT_DELTA) { - _x2 = _x1 + x2; - _y2 = _y1 + y2; - xt2 = int(_x2 >> MAPBLOCKSHIFT); - yt2 = int(_y2 >> MAPBLOCKSHIFT); - x2 = (int)_x2; - y2 = (int)_y2; - } - else - { - _x2 = (long long)x2 - bmaporgx; - _y2 = (long long)y2 - bmaporgy; - x2 -= bmaporgx; - y2 -= bmaporgy; - xt2 = int(_x2 >> MAPBLOCKSHIFT); - yt2 = int(_y2 >> MAPBLOCKSHIFT); + x2 += x1; + y2 += y1; } - if (xt2 > xt1) + x1 -= bmaporgx; + y1 -= bmaporgy; + xt1 = x1 / MAPBLOCKUNITS; + yt1 = y1 / MAPBLOCKUNITS; + + x2 -= bmaporgx; + y2 -= bmaporgy; + xt2 = x2 / MAPBLOCKUNITS; + yt2 = y2 / MAPBLOCKUNITS; + + mapx = xs_FloorToInt(xt1); + mapy = xs_FloorToInt(yt1); + int mapex = xs_FloorToInt(xt2); + int mapey = xs_FloorToInt(yt2); + + + if (mapex > mapx) { mapxstep = 1; - partialx = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1)); - ystep = FixedDiv (y2-y1,abs(x2-x1)); + partialx = xs_CeilToInt(xt1) - xt1; + ystep = (y2 - y1) / fabs(x2 - x1); } - else if (xt2 < xt1) + else if (mapex < mapx) { mapxstep = -1; - partialx = (x1>>MAPBTOFRAC)&(FRACUNIT-1); - ystep = FixedDiv (y2-y1,abs(x2-x1)); + partialx = xt1 - xs_FloorToInt(xt1); + ystep = (y2 - y1) / fabs(x2 - x1); } else { mapxstep = 0; - partialx = FRACUNIT; - ystep = 256*FRACUNIT; - } - yintercept = int(_y1>>MAPBTOFRAC) + FixedMul (partialx, ystep); + partialx = 1.; + ystep = 256; + } + yintercept = yt1 + partialx * ystep; - if (yt2 > yt1) + if (mapey > mapy) { mapystep = 1; - partialy = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1)); - xstep = FixedDiv (x2-x1,abs(y2-y1)); + partialy = xs_CeilToInt(yt1) - yt1; + xstep = (x2 - x1) / fabs(y2 - y1); } - else if (yt2 < yt1) + else if (mapey < mapy) { mapystep = -1; - partialy = (y1>>MAPBTOFRAC)&(FRACUNIT-1); - xstep = FixedDiv (x2-x1,abs(y2-y1)); + partialy = yt1 - xs_FloorToInt(yt1); + xstep = (x2 - x1) / fabs(y2 - y1); } else { mapystep = 0; - partialy = FRACUNIT; - xstep = 256*FRACUNIT; - } - xintercept = int(_x1>>MAPBTOFRAC) + FixedMul (partialy, xstep); + partialy = 1; + xstep = 256; + } + xintercept = xt1 + partialy * xstep; // [RH] Fix for traces that pass only through blockmap corners. In that case, // xintercept and yintercept can both be set ahead of mapx and mapy, so the // for loop would never advance anywhere. - if (abs(xstep) == FRACUNIT && abs(ystep) == FRACUNIT) + if (fabs(xstep) == 1. && fabs(ystep) == 1.) { if (ystep < 0) { - partialx = FRACUNIT - partialx; + partialx = 1. - partialx; } if (xstep < 0) { - partialy = FRACUNIT - partialy; + partialy = 1. - partialy; } if (partialx == partialy) { - xintercept = xt1 << FRACBITS; - yintercept = yt1 << FRACBITS; + xintercept = xt1; + yintercept = yt1; } } // Step through map blocks. // Count is present to prevent a round off error // from skipping the break statement. - mapx = xt1; - mapy = yt1; bool compatible = (flags & PT_COMPATIBLE) && (i_compatflags & COMPATF_HITSCAN); // we want to use one list of checked actors for the entire operation FBlockThingsIterator btit; - for (count = 0 ; count < 100 ; count++) + for (count = 0 ; count < 1000 ; count++) { if (flags & PT_ADDLINES) { @@ -1604,26 +1531,30 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl AddThingIntercepts(mapx, mapy, btit, compatible); } - if (mapx == xt2 && mapy == yt2) - { + // both coordinates reached the end, so end the traversing. + if ((mapxstep | mapystep) == 0) break; - } + // [RH] Handle corner cases properly instead of pretending they don't exist. - switch ((((yintercept >> FRACBITS) == mapy) << 1) | ((xintercept >> FRACBITS) == mapx)) + switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx)) { case 0: // neither xintercept nor yintercept match! - count = 100; // Stop traversing, because somebody screwed up. + count = 1000; // Stop traversing, because somebody screwed up. break; case 1: // xintercept matches xintercept += xstep; mapy += mapystep; + if (mapy == mapey) + mapystep = 0; break; case 2: // yintercept matches yintercept += ystep; mapx += mapxstep; + if (mapx == mapex) + mapxstep = 0; break; case 3: // xintercept and yintercept both match @@ -1631,6 +1562,7 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl // being entered need to be checked (which will happen when this loop // continues), but the other two blocks adjacent to the corner also need to // be checked. + // Since Doom.exe did not do this, this code won't either if run in compatibility mode. if (!compatible) { if (flags & PT_ADDLINES) @@ -1648,10 +1580,14 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl yintercept += ystep; mapx += mapxstep; mapy += mapystep; + if (mapx == mapex) + mapxstep = 0; + if (mapy == mapey) + mapystep = 0; } else { - count = 100; // Doom originally did not handle this case so do the same in compatibility mode. + count = 1000; // Doom originally did not handle this case so do the same in compatibility mode. } break; } @@ -1664,22 +1600,22 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl // //=========================================================================== -int FPathTraverse::PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos) +int FPathTraverse::PortalRelocate(intercept_t *in, int flags, DVector3 *optpos) { if (!in->isaline || !in->d.line->isLinePortal()) return false; if (P_PointOnLineSidePrecise(trace.x, trace.y, in->d.line) == 1) return false; - fixed_t hitx = trace.x; - fixed_t hity = trace.y; - fixed_t endx = trace.x + trace.dx; - fixed_t endy = trace.y + trace.dy; + double hitx = trace.x; + double hity = trace.y; + double endx = trace.x + trace.dx; + double endy = trace.y + trace.dy; P_TranslatePortalXY(in->d.line, hitx, hity); P_TranslatePortalXY(in->d.line, endx, endy); if (optpos != NULL) { - P_TranslatePortalXY(in->d.line, optpos->x, optpos->y); - P_TranslatePortalZ(in->d.line, optpos->z); + P_TranslatePortalXY(in->d.line, optpos->X, optpos->Y); + P_TranslatePortalZ(in->d.line, optpos->Z); } line_t *saved = in->d.line; // this gets overwriitten by the init call. intercepts.Resize(intercept_index); @@ -1725,8 +1661,8 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in int count; AActor *target; - startX = GetSafeBlockX(mo->X()-bmaporgx); - startY = GetSafeBlockY(mo->Y()-bmaporgy); + startX = GetBlockX(mo->X()); + startY = GetBlockY(mo->Y()); validcount++; if (startX >= 0 && startX < bmapwidth && startY >= 0 && startY < bmapheight) @@ -1838,12 +1774,12 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param) // //========================================================================== -static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node) +static int R_PointOnSideSlow(double xx, double yy, node_t *node) { // [RH] This might have been faster than two multiplies and an // add on a 386/486, but it certainly isn't on anything newer than that. - fixed_t dx; - fixed_t dy; + auto x = FloatToFixed(xx); + auto y = FloatToFixed(yy); double left; double right; @@ -1862,8 +1798,8 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node) return node->dx > 0; } - dx = (x - node->x); - dy = (y - node->y); + auto dx = (x - node->x); + auto dy = (y - node->y); // Try to quickly decide by looking at sign bits. if ((node->dy ^ node->dx ^ dx ^ dy) & 0x80000000) @@ -1877,6 +1813,7 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node) } // we must use doubles here because the fixed point code will produce errors due to loss of precision for extremely short linedefs. + // Note that this function is used for all map spawned actors and not just a compatibility fallback! left = (double)node->dy * (double)dx; right = (double)dy * (double)node->dx; @@ -1897,88 +1834,48 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node) // //=========================================================================== -int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line) +int P_VanillaPointOnLineSide(double x, double y, const line_t* line) { - fixed_t dx; - fixed_t dy; - fixed_t left; - fixed_t right; + DVector2 delta = line->Delta(); - if (!line->dx) + if (delta.X == 0) { - if (x <= line->v1->x) - return line->dy > 0; + if (x <= line->v1->fX()) + return delta.Y > 0; - return line->dy < 0; + return delta.Y < 0; } - if (!line->dy) + if (delta.Y == 0) { - if (y <= line->v1->y) - return line->dx < 0; + if (y <= line->v1->fY()) + return delta.X < 0; - return line->dx > 0; + return delta.X > 0; } - dx = (x - line->v1->x); - dy = (y - line->v1->y); + // Note: This cannot really be converted to floating point + // without breaking the intended use of this function + // (i.e. to emulate the horrible imprecision of the entire method) - left = FixedMul ( line->dy>>FRACBITS , dx ); - right = FixedMul ( dy , line->dx>>FRACBITS ); + auto dx = FloatToFixed(x - line->v1->fX()); + auto dy = FloatToFixed(y - line->v1->fY()); + + auto left = MulScale16( int(delta.Y * 256) , dx ); + auto right = MulScale16( dy , int(delta.X * 256) ); if (right < left) return 0; // front side return 1; // back side } -//=========================================================================== +//========================================================================== // -// P_VanillaPointOnDivlineSide -// P_PointOnDivlineSide() from the initial Doom source code release +// Use buggy PointOnSide and fix actors that lie on +// lines to compensate for some IWAD maps. // -//=========================================================================== +//========================================================================== -int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line) -{ - fixed_t dx; - fixed_t dy; - fixed_t left; - fixed_t right; - - if (!line->dx) - { - if (x <= line->x) - return line->dy > 0; - - return line->dy < 0; - } - if (!line->dy) - { - if (y <= line->y) - return line->dx < 0; - - return line->dx > 0; - } - - dx = (x - line->x); - dy = (y - line->y); - - // try to quickly decide by looking at sign bits - if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 ) - { - if ( (line->dy ^ dx) & 0x80000000 ) - return 1; // (left is negative) - return 0; - } - - left = FixedMul ( line->dy>>8, dx>>8 ); - right = FixedMul ( dy>>8 , line->dx>>8 ); - - if (right < left) - return 0; // front side - return 1; // back side -} - -sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y) +sector_t *P_PointInSectorBuggy(double x, double y) { // single subsector is a special case if (numgamenodes == 0) diff --git a/src/p_maputl.h b/src/p_maputl.h index 6ef5aa6c8..d53ab49a7 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -1,6 +1,7 @@ #ifndef __P_MAPUTL_H #define __P_MAPUTL_H +#include #include "r_defs.h" #include "doomstat.h" #include "m_bbox.h" @@ -9,15 +10,15 @@ extern int validcount; struct divline_t { - fixed_t x; - fixed_t y; - fixed_t dx; - fixed_t dy; + double x; + double y; + double dx; + double dy; }; struct intercept_t { - fixed_t frac; // along trace line + double frac; bool isaline; bool done; union { @@ -35,65 +36,71 @@ struct intercept_t // //========================================================================== -inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) +inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line) { - extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); + return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > -EQUAL_EPSILON; +} + +inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line) +{ + return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > -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) - : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; + ? P_VanillaPointOnLineSide(x, y, line) : P_PointOnLineSidePrecise(x, y, line); } -inline int P_PointOnLineSidePrecise (fixed_t x, fixed_t y, const line_t *line) +inline int P_PointOnLineSide(const DVector2 & p, const line_t *line) { - return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; + return P_PointOnLineSide(p.X, p.Y, line); } + + //========================================================================== // -// P_PointOnDivlineSide +// P_PointOnDivlineSideCompat // // Same as P_PointOnLineSide except it uses divlines // [RH] inlined, stripped down, and made more precise // //========================================================================== -inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_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 divline_t* line); - - return (i_compatflags2 & COMPATF2_POINTONLINE) - ? P_VanillaPointOnDivlineSide(x, y, line) - : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); + return (y - line->y) * line->dx + (line->x - x) * line->dy > -EQUAL_EPSILON; } -inline int P_PointOnDivlineSidePrecise (fixed_t x, fixed_t y, const divline_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; } - //========================================================================== // // P_MakeDivline // //========================================================================== -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->x; - dl->y = li->v1->y; - dl->dx = li->dx; - dl->dy = li->dy; + dl->x = li->v1->fX(); + dl->y = li->v1->fY(); + dl->dx = li->Delta().X; + dl->dy = li->Delta().Y; } struct FLineOpening { - fixed_t top; - fixed_t bottom; - fixed_t range; - fixed_t lowfloor; + double top; + double bottom; + double range; + double lowfloor; sector_t *bottomsec; sector_t *topsec; FTextureID ceilingpic; @@ -105,10 +112,13 @@ struct FLineOpening bool abovemidtex; }; -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); -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) +static const double LINEOPEN_MIN = -FLT_MAX; +static const double LINEOPEN_MAX = FLT_MAX; + +void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *linedef, const DVector2 &xy, const DVector2 *ref = NULL, int flags = 0); +inline void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *linedef, const DVector2 &xy, const DVector3 *ref, int flags = 0) { - P_LineOpening(open, thing, linedef, xy.x, xy.y, refx, refy, flags); + P_LineOpening(open, thing, linedef, xy, reinterpret_cast(ref), flags); } class FBoundingBox; @@ -216,8 +226,8 @@ public: class FMultiBlockLinesIterator { FPortalGroupArray &checklist; - fixedvec3 checkpoint; - fixedvec2 offset; + DVector3 checkpoint; + DVector2 offset; sector_t *startsector; sector_t *cursector; short basegroup; @@ -228,8 +238,8 @@ class FMultiBlockLinesIterator FBlockLinesIterator blockIterator; FBoundingBox bbox; - bool GoUp(fixed_t x, fixed_t y); - bool GoDown(fixed_t x, fixed_t y); + bool GoUp(double x, double y); + bool GoDown(double x, double y); void startIteratorForGroup(int group); public: @@ -237,12 +247,13 @@ public: struct CheckResult { line_t *line; - fixedvec3 position; + DVector3 Position; int portalflags; }; - FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1); - FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, sector_t *newsec); + FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, double checkradius = -1); + FMultiBlockLinesIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, sector_t *newsec); + bool Next(CheckResult *item); void Reset(); // for stopping group traversal through portals. Only the calling code can decide whether this is needed so this needs to be set from the outside. @@ -308,7 +319,7 @@ public: class FMultiBlockThingsIterator { FPortalGroupArray &checklist; - fixedvec3 checkpoint; + DVector3 checkpoint; short basegroup; short portalflags; short index; @@ -322,12 +333,12 @@ public: struct CheckResult { AActor *thing; - fixedvec3 position; + DVector3 Position; int portalflags; }; - FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1, bool ignorerestricted = false); - FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted, sector_t *newsec); + FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, double checkradius = -1, bool ignorerestricted = false); + FMultiBlockThingsIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec); bool Next(CheckResult *item); void Reset(); const FBoundingBox &Box() const @@ -344,7 +355,7 @@ protected: static TArray intercepts; divline_t trace; - fixed_t startfrac; + double Startfrac; unsigned int intercept_index; unsigned int intercept_count; unsigned int count; @@ -356,21 +367,21 @@ public: intercept_t *Next(); - FPathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac = 0) + FPathTraverse(double x1, double y1, double x2, double y2, int flags, double startfrac = 0) { init(x1, y1, x2, y2, flags, startfrac); } - 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, fixedvec3 *optpos = NULL); + void init(double x1, double y1, double x2, double y2, int flags, double startfrac = 0); + int PortalRelocate(intercept_t *in, int flags, DVector3 *optpos = NULL); virtual ~FPathTraverse(); const divline_t &Trace() const { return trace; } - inline fixedvec2 InterceptPoint(const intercept_t *in) + inline DVector2 InterceptPoint(const intercept_t *in) { return { - trace.x + FixedMul(trace.dx, in->frac), - trace.y + FixedMul(trace.dy, in->frac) + trace.x + trace.dx * in->frac, + trace.y + trace.dy * in->frac }; } @@ -393,18 +404,14 @@ public: } }; - - // // P_MAPUTL // typedef bool(*traverser_t) (intercept_t *in); -fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); - - -fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1); +int P_AproxDistance (int dx, int dy); +double P_InterceptVector(const divline_t *v2, const divline_t *v1); #define PT_ADDLINES 1 #define PT_ADDTHINGS 2 diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 43ba4355d..bacef28e4 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1,5 +1,4 @@ // Emacs style mode select -*- C++ -*- -// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ @@ -24,6 +23,7 @@ // HEADER FILES ------------------------------------------------------------ +#include #include "templates.h" #include "i_system.h" #include "m_random.h" @@ -73,10 +73,10 @@ // MACROS ------------------------------------------------------------------ -#define WATER_SINK_FACTOR 3 -#define WATER_SINK_SMALL_FACTOR 4 -#define WATER_SINK_SPEED (FRACUNIT/2) -#define WATER_JUMP_SPEED (FRACUNIT*7/2) +#define WATER_SINK_FACTOR 0.125 +#define WATER_SINK_SMALL_FACTOR 0.25 +#define WATER_SINK_SPEED 0.5 +#define WATER_JUMP_SPEED 3.5 // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -221,26 +221,25 @@ static VMFunction *UncalcDamageValue(int dmg, VMFunction *def) // //========================================================================== -void AActor::Serialize (FArchive &arc) +void AActor::Serialize(FArchive &arc) { - Super::Serialize (arc); + Super::Serialize(arc); - if (arc.IsStoring ()) + if (arc.IsStoring()) { - arc.WriteSprite (sprite); + arc.WriteSprite(sprite); } else { - sprite = arc.ReadSprite (); + sprite = arc.ReadSprite(); } - arc << __pos.x - << __pos.y - << __pos.z - << angle + arc << __Pos + << Angles.Yaw + << Angles.Pitch + << Angles.Roll << frame - << scaleX - << scaleY + << Scale << RenderStyle << renderflags << picnum @@ -250,10 +249,8 @@ void AActor::Serialize (FArchive &arc) << LastLookPlayerNumber << LastLookActor << effects - << alpha + << Alpha << fillcolor - << pitch - << roll << Sector << floorz << ceilingz @@ -261,11 +258,9 @@ void AActor::Serialize (FArchive &arc) << floorsector << ceilingsector << radius - << height + << Height << projectilepassheight - << vel.x - << vel.y - << vel.z + << Vel << tics << state; if (arc.IsStoring()) @@ -280,30 +275,20 @@ void AActor::Serialize (FArchive &arc) arc << dmg; Damage = UncalcDamageValue(dmg, GetDefault()->Damage); } - if (SaveVersion >= 4530) - { - P_SerializeTerrain(arc, floorterrain); - } - if (SaveVersion >= 3227) - { - arc << projectileKickback; - } - arc << flags + P_SerializeTerrain(arc, floorterrain); + arc << projectileKickback + << flags << flags2 << flags3 << flags4 << flags5 - << flags6; - if (SaveVersion >= 4504) - { - arc << flags7; - } - if (SaveVersion >= 4512) - { - arc << weaponspecial; - } - arc << special1 + << flags6 + << flags7 + << weaponspecial + << special1 << special2 + << specialf1 + << specialf2 << health << movedir << visdir @@ -315,15 +300,12 @@ void AActor::Serialize (FArchive &arc) << reactiontime << threshold << player - << SpawnPoint[0] << SpawnPoint[1] << SpawnPoint[2] - << SpawnAngle; - if (SaveVersion >= 4506) - { - arc << StartHealth; - } - arc << skillrespawncount + << SpawnPoint + << SpawnAngle + << StartHealth + << skillrespawncount << tracer - << floorclip + << Floorclip << tid << special; if (P_IsACSSpecial(special)) @@ -335,21 +317,13 @@ void AActor::Serialize (FArchive &arc) arc << args[0]; } arc << args[1] << args[2] << args[3] << args[4]; - if (SaveVersion >= 3427) - { - arc << accuracy << stamina; - } + arc << accuracy << stamina; arc << goal << waterlevel << MinMissileChance << SpawnFlags << Inventory << InventoryID; - if (SaveVersion < 4513) - { - SDWORD id; - arc << id; - } arc << FloatBobPhase << Translation << SeeSound @@ -369,7 +343,7 @@ void AActor::Serialize (FArchive &arc) << SeeState << MeleeState << MissileState - << MaxDropOffHeight + << MaxDropOffHeight << MaxStepHeight << BounceFlags << bouncefactor @@ -379,17 +353,10 @@ void AActor::Serialize (FArchive &arc) << meleethreshold << meleerange << DamageType; - if (SaveVersion >= 4501) - { - arc << DamageTypeReceived; - } - if (SaveVersion >= 3237) - { - arc - << PainType + arc << DamageTypeReceived; + arc << PainType << DeathType; - } - arc << gravity + arc << Gravity << FastChaseStrafeCount << master << smokecounter @@ -399,48 +366,23 @@ void AActor::Serialize (FArchive &arc) << pushfactor << Species << Score; - if (SaveVersion >= 3113) - { - arc << DesignatedTeam; - } + arc << DesignatedTeam; arc << lastpush << lastbump << PainThreshold << DamageFactor; - if (SaveVersion >= 4516) - { - arc << DamageMultiply; - } - else - { - DamageMultiply = FRACUNIT; - } + arc << DamageMultiply; arc << WeaveIndexXY << WeaveIndexZ << PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner << PoisonDamage << PoisonDuration << PoisonPeriod; - if (SaveVersion >= 3235) - { - arc << PoisonDamageType << PoisonDamageTypeReceived; - } + arc << PoisonDamageType << PoisonDamageTypeReceived; arc << ConversationRoot << Conversation; - if (SaveVersion >= 4509) - { - arc << FriendPlayer; - } - if (SaveVersion >= 4517) - { - arc << TeleFogSourceType - << TeleFogDestType; - } - if (SaveVersion >= 4518) - { - arc << RipperLevel - << RipLevelMin - << RipLevelMax; - } - if (SaveVersion >= 4533) - { - arc << DefThreshold; - } + arc << FriendPlayer; + arc << TeleFogSourceType + << TeleFogDestType; + arc << RipperLevel + << RipLevelMin + << RipLevelMax; + arc << DefThreshold; { FString tagstr; @@ -474,7 +416,7 @@ void AActor::Serialize (FArchive &arc) } } ClearInterpolation(); - UpdateWaterLevel(Z(), false); + UpdateWaterLevel(false); } } @@ -832,19 +774,17 @@ bool AActor::UseInventory (AInventory *item) AInventory *AActor::DropInventory (AInventory *item) { - angle_t an; AInventory *drop = item->CreateTossable (); if (drop == NULL) { return NULL; } - an = angle >> ANGLETOFINESHIFT; - drop->SetOrigin(PosPlusZ(10*FRACUNIT), false); - drop->angle = angle; - drop->vel.x = vel.x + 5 * finecosine[an]; - drop->vel.y = vel.y + 5 * finesine[an]; - drop->vel.z = vel.z + FRACUNIT; + drop->SetOrigin(PosPlusZ(10.), false); + drop->Angles.Yaw = Angles.Yaw; + drop->VelFromAngle(5.); + drop->Vel.Z = 1.; + drop->Vel += Vel; drop->flags &= ~MF_NOGRAVITY; // Don't float drop->ClearCounters(); // do not count for statistics again return drop; @@ -901,7 +841,7 @@ AInventory *AActor::GiveInventoryType (PClassActor *type) if (type != NULL) { - item = static_cast(Spawn (type, 0,0,0, NO_REPLACE)); + item = static_cast(Spawn (type)); if (!item->CallTryPickup (this)) { item->Destroy (); @@ -923,7 +863,7 @@ bool AActor::GiveAmmo (PClassAmmo *type, int amount) { if (type != NULL) { - AInventory *item = static_cast(Spawn (type, 0, 0, 0, NO_REPLACE)); + AInventory *item = static_cast(Spawn (type)); if (item) { item->Amount = amount; @@ -1203,7 +1143,8 @@ bool AActor::Grind(bool items) { flags &= ~MF_SOLID; flags3 |= MF3_DONTGIB; - height = radius = 0; + Height = 0; + radius = 0; return false; } @@ -1229,7 +1170,8 @@ bool AActor::Grind(bool items) } flags &= ~MF_SOLID; flags3 |= MF3_DONTGIB; - height = radius = 0; + Height = 0; + radius = 0; SetState (state); if (isgeneric) // Not a custom crush state, so colorize it appropriately. { @@ -1264,7 +1206,8 @@ bool AActor::Grind(bool items) // if there's no gib sprite don't crunch it. flags &= ~MF_SOLID; flags3 |= MF3_DONTGIB; - height = radius = 0; + Height = 0; + radius = 0; return false; } @@ -1272,8 +1215,8 @@ bool AActor::Grind(bool items) if (gib != NULL) { gib->RenderStyle = RenderStyle; - gib->alpha = alpha; - gib->height = 0; + gib->Alpha = Alpha; + gib->Height = 0; gib->radius = 0; PalEntry bloodcolor = GetBloodColor(); @@ -1285,7 +1228,7 @@ bool AActor::Grind(bool items) if (flags & MF_ICECORPSE) { tics = 1; - vel.x = vel.y = vel.z = 0; + Vel.Zero(); } else if (player) { @@ -1362,7 +1305,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) return; } } - mo->vel.x = mo->vel.y = mo->vel.z = 0; + mo->Vel.Zero(); mo->effects = 0; // [RH] mo->flags &= ~MF_SHOOTABLE; @@ -1387,8 +1330,8 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) if (line != NULL && cl_missiledecals) { - fixedvec3 pos = mo->PosRelative(line); - int side = P_PointOnLineSidePrecise (pos.x, pos.y, line); + DVector3 pos = mo->PosRelative(line); + int side = P_PointOnLineSidePrecise (pos, line); if (line->sidedef[side] == NULL) side ^= 1; if (line->sidedef[side] != NULL) @@ -1397,31 +1340,15 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) if (base != NULL) { // Find the nearest point on the line, and stick a decal there - fixed_t x, y, z; - SQWORD num, den; + DVector3 linepos; + double den, frac; - den = (SQWORD)line->dx*line->dx + (SQWORD)line->dy*line->dy; + den = line->Delta().LengthSquared(); if (den != 0) { - SDWORD frac; + frac = clamp((mo->Pos().XY() - line->v1->fPos()) | line->Delta(), 0, den) / den; - num = (SQWORD)(pos.x-line->v1->x)*line->dx+(SQWORD)(pos.y-line->v1->y)*line->dy; - if (num <= 0) - { - frac = 0; - } - else if (num >= den) - { - frac = 1<<30; - } - else - { - frac = (SDWORD)(num / (den>>30)); - } - - x = line->v1->x + MulScale30 (line->dx, frac); - y = line->v1->y + MulScale30 (line->dy, frac); - z = pos.z; + linepos = DVector3(line->v1->fPos() + line->Delta() * frac, pos.Z); F3DFloor * ffloor=NULL; if (line->sidedef[side^1] != NULL) @@ -1435,16 +1362,16 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) if ((rover->flags&(FF_EXISTS|FF_SOLID|FF_RENDERSIDES))==(FF_EXISTS|FF_SOLID|FF_RENDERSIDES)) { - if (z<=rover->top.plane->ZatPoint(x, y) && z>=rover->bottom.plane->ZatPoint( x, y)) + if (pos.Z <= rover->top.plane->ZatPoint(linepos) && pos.Z >= rover->bottom.plane->ZatPoint(linepos)) { - ffloor=rover; + ffloor = rover; break; } } } } - DImpactDecal::StaticCreate(base->GetDecal(), { x, y, z }, line->sidedef[side], ffloor); + DImpactDecal::StaticCreate(base->GetDecal(), linepos, line->sidedef[side], ffloor); } } } @@ -1469,18 +1396,18 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) if (addrocketexplosion) { mo->RenderStyle = STYLE_Add; - mo->alpha = FRACUNIT; + mo->Alpha = 1.; } else { mo->RenderStyle = STYLE_Translucent; - mo->alpha = FRACUNIT*2/3; + mo->Alpha = 0.6666; } } else { mo->RenderStyle = ERenderStyle(deh.ExplosionStyle); - mo->alpha = deh.ExplosionAlpha; + mo->Alpha = deh.ExplosionAlpha; } } @@ -1548,7 +1475,7 @@ bool AActor::FloorBounceMissile (secplane_t &plane) } } - if (plane.c < 0) + if (plane.fC() < 0) { // on ceiling if (!(BounceFlags & BOUNCE_Ceilings)) return true; @@ -1569,14 +1496,12 @@ bool AActor::FloorBounceMissile (secplane_t &plane) return true; } - fixed_t dot = TMulScale16 (vel.x, plane.a, vel.y, plane.b, vel.z, plane.c); + double dot = (Vel | plane.Normal()) * 2; if (BounceFlags & (BOUNCE_HereticType | BOUNCE_MBF)) { - vel.x -= MulScale15 (plane.a, dot); - vel.y -= MulScale15 (plane.b, dot); - vel.z -= MulScale15 (plane.c, dot); - angle = R_PointToAngle2 (0, 0, vel.x, vel.y); + Vel -= plane.Normal() * dot; + AngleFromVel(); if (!(BounceFlags & BOUNCE_MBF)) // Heretic projectiles die, MBF projectiles don't. { flags |= MF_INBOUNCE; @@ -1584,15 +1509,13 @@ bool AActor::FloorBounceMissile (secplane_t &plane) flags &= ~MF_INBOUNCE; return false; } - else vel.z = FixedMul(vel.z, bouncefactor); + else Vel.Z *= bouncefactor; } else // Don't run through this for MBF-style bounces { // The reflected velocity keeps only about 70% of its original speed - vel.x = FixedMul (vel.x - MulScale15 (plane.a, dot), bouncefactor); - vel.y = FixedMul (vel.y - MulScale15 (plane.b, dot), bouncefactor); - vel.z = FixedMul (vel.z - MulScale15 (plane.c, dot), bouncefactor); - angle = R_PointToAngle2 (0, 0, vel.x, vel.y); + Vel = (Vel - plane.Normal() * dot) * bouncefactor; + AngleFromVel(); } PlayBounceSound(true); @@ -1604,7 +1527,7 @@ bool AActor::FloorBounceMissile (secplane_t &plane) FState *bouncestate; names[0] = NAME_Bounce; - names[1] = plane.c < 0 ? NAME_Ceiling : NAME_Floor; + names[1] = plane.fC() < 0 ? NAME_Ceiling : NAME_Floor; bouncestate = FindState(2, names); if (bouncestate != NULL) { @@ -1614,34 +1537,21 @@ bool AActor::FloorBounceMissile (secplane_t &plane) if (BounceFlags & BOUNCE_MBF) // Bring it to rest below a certain speed { - if (abs(vel.z) < (fixed_t)(Mass * GetGravity() / 64)) - vel.z = 0; + if (fabs(Vel.Z) < Mass * GetGravity() / 64) + Vel.Z = 0; } else if (BounceFlags & (BOUNCE_AutoOff|BOUNCE_AutoOffFloorOnly)) { - if (plane.c > 0 || (BounceFlags & BOUNCE_AutoOff)) + if (plane.fC() > 0 || (BounceFlags & BOUNCE_AutoOff)) { // AutoOff only works when bouncing off a floor, not a ceiling (or in compatibility mode.) - if (!(flags & MF_NOGRAVITY) && (vel.z < 3*FRACUNIT)) + if (!(flags & MF_NOGRAVITY) && (Vel.Z < 3)) BounceFlags &= ~BOUNCE_TypeMask; } } return false; } -//---------------------------------------------------------------------------- -// -// PROC P_ThrustMobj -// -//---------------------------------------------------------------------------- - -void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move) -{ - angle >>= ANGLETOFINESHIFT; - mo->vel.x += FixedMul (move, finecosine[angle]); - mo->vel.y += FixedMul (move, finesine[angle]); -} - //---------------------------------------------------------------------------- // // FUNC P_FaceMobj @@ -1652,41 +1562,20 @@ void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move) // //---------------------------------------------------------------------------- -int P_FaceMobj (AActor *source, AActor *target, angle_t *delta) +int P_FaceMobj (AActor *source, AActor *target, DAngle *delta) { - angle_t diff; - angle_t angle1; - angle_t angle2; + DAngle diff; - angle1 = source->angle; - angle2 = source->AngleTo(target); - if (angle2 > angle1) + diff = deltaangle(source->Angles.Yaw, source->AngleTo(target)); + if (diff > 0) { - diff = angle2 - angle1; - if (diff > ANGLE_180) - { - *delta = ANGLE_MAX - diff; - return 0; - } - else - { - *delta = diff; - return 1; - } + *delta = diff; + return 1; } else { - diff = angle1 - angle2; - if (diff > ANGLE_180) - { - *delta = ANGLE_MAX - diff; - return 1; - } - else - { - *delta = diff; - return 0; - } + *delta = -diff; + return 0; } } @@ -1704,7 +1593,7 @@ bool AActor::CanSeek(AActor *target) const if ((flags2 & MF2_DONTSEEKINVISIBLE) && ((target->flags & MF_SHADOW) || (target->renderflags & RF_INVISIBLE) || - !target->RenderStyle.IsVisible(target->alpha) + !target->RenderStyle.IsVisible(target->Alpha) ) ) return false; return true; @@ -1719,16 +1608,14 @@ bool AActor::CanSeek(AActor *target) const // //---------------------------------------------------------------------------- -bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise, bool usecurspeed) +bool P_SeekerMissile (AActor *actor, double thresh, double turnMax, bool precise, bool usecurspeed) { int dir; - int dist; - angle_t delta; - angle_t angle; + DAngle delta; AActor *target; - fixed_t speed; + double speed; - speed = !usecurspeed ? actor->Speed : xs_CRoundToInt(DVector3(actor->vel.x, actor->vel.y, actor->vel.z).Length()); + speed = !usecurspeed ? actor->Speed : actor->VelToSpeed(); target = actor->tracer; if (target == NULL || !actor->CanSeek(target)) { @@ -1746,7 +1633,7 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci dir = P_FaceMobj (actor, target, &delta); if (delta > thresh) { - delta >>= 1; + delta /= 2; if (delta > turnMax) { delta = turnMax; @@ -1754,54 +1641,41 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci } if (dir) { // Turn clockwise - actor->angle += delta; + actor->Angles.Yaw += delta; } else { // Turn counter clockwise - actor->angle -= delta; + actor->Angles.Yaw -= delta; } - angle = actor->angle>>ANGLETOFINESHIFT; if (!precise) { - actor->vel.x = FixedMul (speed, finecosine[angle]); - actor->vel.y = FixedMul (speed, finesine[angle]); + actor->VelFromAngle(speed); if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { if (actor->Top() < target->Z() || target->Top() < actor->Z()) { // Need to seek vertically - dist = actor->AproxDistance (target) / speed; - if (dist < 1) - { - dist = 1; - } - actor->vel.z = ((target->Z() + target->height / 2) - (actor->Z() + actor->height / 2)) / dist; + actor->Vel.Z = (target->Center() - actor->Center()) / actor->DistanceBySpeed(target, speed); } } } else { - angle_t pitch = 0; + DAngle pitch = 0.; if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { // Need to seek vertically - fixedvec2 vec = actor->Vec2To(target); - double dist = MAX(1.0, DVector2(vec.x, vec.y).Length()); + double dist = MAX(1., actor->Distance2D(target)); // Aim at a player's eyes and at the middle of the actor for everything else. - fixed_t aimheight = target->height/2; + double aimheight = target->Height/2; if (target->IsKindOf(RUNTIME_CLASS(APlayerPawn))) { aimheight = static_cast(target)->ViewHeight; } - pitch = R_PointToAngle2(0, actor->Z() + actor->height/2, xs_CRoundToInt(dist), target->Z() + aimheight); - pitch >>= ANGLETOFINESHIFT; + pitch = DVector2(dist, target->Z() + aimheight - actor->Center()).Angle(); } - - fixed_t xyscale = FixedMul(speed, finecosine[pitch]); - actor->vel.z = FixedMul(speed, finesine[pitch]); - actor->vel.x = FixedMul(xyscale, finecosine[angle]); - actor->vel.y = FixedMul(xyscale, finesine[angle]); + actor->Vel3DFromAngle(-pitch, speed); } return true; @@ -1813,26 +1687,26 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci // // Returns the actor's old floorz. // -#define STOPSPEED 0x1000 -#define CARRYSTOPSPEED (STOPSPEED*32/3) +#define STOPSPEED (0x1000/65536.) +#define CARRYSTOPSPEED ((0x1000*32/3)/65536.) -fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) +double P_XYMovement (AActor *mo, DVector2 scroll) { static int pushtime = 0; - bool bForceSlide = scrollx || scrolly; - angle_t angle; - fixed_t ptryx, ptryy; + bool bForceSlide = !scroll.isZero(); + DAngle Angle; + DVector2 ptry; player_t *player; - fixed_t xmove, ymove; + DVector2 move; const secplane_t * walkplane; - static const int windTab[3] = {2048*5, 2048*10, 2048*25}; + static const double windTab[3] = { 5 / 32., 10 / 32., 25 / 32. }; int steps, step, totalsteps; - fixed_t startx, starty; - fixed_t oldfloorz = mo->floorz; - fixed_t oldz = mo->Z(); + DVector2 start; + double Oldfloorz = mo->floorz; + double oldz = mo->Z(); - fixed_t maxmove = (mo->waterlevel < 1) || (mo->flags & MF_MISSILE) || - (mo->player && mo->player->crouchoffset<-10*FRACUNIT) ? MAXMOVE : MAXMOVE/4; + double maxmove = (mo->waterlevel < 1) || (mo->flags & MF_MISSILE) || + (mo->player && mo->player->crouchoffset<-10) ? MAXMOVE : MAXMOVE/4; if (mo->flags2 & MF2_WINDTHRUST && mo->waterlevel < 2 && !(mo->flags & MF_NOCLIP)) { @@ -1840,16 +1714,16 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) switch (special) { case 40: case 41: case 42: // Wind_East - P_ThrustMobj (mo, 0, windTab[special-40]); + mo->Thrust(0., windTab[special-40]); break; case 43: case 44: case 45: // Wind_North - P_ThrustMobj (mo, ANG90, windTab[special-43]); + mo->Thrust(90., windTab[special-43]); break; case 46: case 47: case 48: // Wind_South - P_ThrustMobj (mo, ANG270, windTab[special-46]); + mo->Thrust(270., windTab[special-46]); break; case 49: case 50: case 51: // Wind_West - P_ThrustMobj (mo, ANG180, windTab[special-49]); + mo->Thrust(180., windTab[special-49]); break; } } @@ -1859,51 +1733,43 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // running depends on the player's original movement continuing even after // it gets blocked. if ((mo->player != NULL && (i_compatflags & COMPATF_WALLRUN)) || (mo->waterlevel >= 1) || - (mo->player != NULL && mo->player->crouchfactor < FRACUNIT*3/4)) + (mo->player != NULL && mo->player->crouchfactor < 0.75)) { // preserve the direction instead of clamping x and y independently. - xmove = clamp (mo->vel.x, -maxmove, maxmove); - ymove = clamp (mo->vel.y, -maxmove, maxmove); + double cx = mo->Vel.X == 0 ? 1. : clamp(mo->Vel.X, -maxmove, maxmove) / mo->Vel.X; + double cy = mo->Vel.Y == 0 ? 1. : clamp(mo->Vel.Y, -maxmove, maxmove) / mo->Vel.Y; + double fac = MIN(cx, cy); - fixed_t xfac = FixedDiv(xmove, mo->vel.x); - fixed_t yfac = FixedDiv(ymove, mo->vel.y); - fixed_t fac = MIN(xfac, yfac); - - xmove = mo->vel.x = FixedMul(mo->vel.x, fac); - ymove = mo->vel.y = FixedMul(mo->vel.y, fac); - } - else - { - xmove = mo->vel.x; - ymove = mo->vel.y; + mo->Vel.X *= fac; + mo->Vel.Y *= fac; } + move = mo->Vel; // [RH] Carrying sectors didn't work with low speeds in BOOM. This is // because BOOM relied on the speed being fast enough to accumulate // despite friction. If the speed is too low, then its movement will get // cancelled, and it won't accumulate to the desired speed. mo->flags4 &= ~MF4_SCROLLMOVE; - if (abs(scrollx) > CARRYSTOPSPEED) + if (fabs(scroll.X) > CARRYSTOPSPEED) { - scrollx = FixedMul (scrollx, CARRYFACTOR); - mo->vel.x += scrollx; + scroll.X *= CARRYFACTOR; + mo->Vel.X += scroll.X; mo->flags4 |= MF4_SCROLLMOVE; } - if (abs(scrolly) > CARRYSTOPSPEED) + if (fabs(scroll.Y) > CARRYSTOPSPEED) { - scrolly = FixedMul (scrolly, CARRYFACTOR); - mo->vel.y += scrolly; + scroll.Y *= CARRYFACTOR; + mo->Vel.Y += scroll.Y; mo->flags4 |= MF4_SCROLLMOVE; } - xmove += scrollx; - ymove += scrolly; + move += scroll; - if ((xmove | ymove) == 0) + if (move.isZero()) { if (mo->flags & MF_SKULLFLY) { // the skull slammed into something mo->flags &= ~MF_SKULLFLY; - mo->vel.x = mo->vel.y = mo->vel.z = 0; + mo->Vel.Zero(); if (!(mo->flags2 & MF2_DORMANT)) { if (mo->SeeState != NULL) mo->SetState (mo->SeeState); @@ -1915,15 +1781,14 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) mo->tics = -1; } } - return oldfloorz; + return Oldfloorz; } player = mo->player; // [RH] Adjust player movement on sloped floors - fixed_t startxmove = xmove; - fixed_t startymove = ymove; - walkplane = P_CheckSlopeWalk (mo, xmove, ymove); + DVector2 startmove = move; + walkplane = P_CheckSlopeWalk (mo, move); // [RH] Take smaller steps when moving faster than the object's size permits. // Moving as fast as the object's "diameter" is bad because it could skip @@ -1932,15 +1797,15 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // through the actor. { - maxmove = mo->radius - FRACUNIT; + double maxmove = mo->radius - 1; if (maxmove <= 0) { // gibs can have radius 0, so don't divide by zero below! maxmove = MAXMOVE; } - const fixed_t xspeed = abs (xmove); - const fixed_t yspeed = abs (ymove); + const double xspeed = fabs (move.X); + const double yspeed = fabs (move.Y); steps = 1; @@ -1948,25 +1813,23 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { if (xspeed > maxmove) { - steps = 1 + xspeed / maxmove; + steps = int(1 + xspeed / maxmove); } } else { if (yspeed > maxmove) { - steps = 1 + yspeed / maxmove; + steps = int(1 + yspeed / maxmove); } } } // P_SlideMove needs to know the step size before P_CheckSlopeWalk // because it also calls P_CheckSlopeWalk on its clipped steps. - fixed_t onestepx = startxmove / steps; - fixed_t onestepy = startymove / steps; + DVector2 onestep = startmove / steps; - startx = mo->X(); - starty = mo->Y(); + start = mo->Pos(); step = 1; totalsteps = steps; @@ -1983,23 +1846,19 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) FCheckPosition tm(!!(mo->flags2 & MF2_RIP)); - angle_t oldangle = mo->angle; + DAngle oldangle = mo->Angles.Yaw; do { if (i_compatflags & COMPATF_WALLRUN) pushtime++; tm.PushTime = pushtime; - ptryx = startx + Scale (xmove, step, steps); - ptryy = starty + Scale (ymove, step, steps); + ptry = start + move * step / steps; + + DVector2 startvel = mo->Vel; -/* if (mo->player) - Printf ("%d,%d/%d: %d %d %d %d %d %d %d\n", level.time, step, steps, startxmove, Scale(xmove,step,steps), startymove, Scale(ymove,step,steps), mo->x, mo->y, mo->z); -*/ - // [RH] If walking on a slope, stay on the slope // killough 3/15/98: Allow objects to drop off - fixed_t startvelx = mo->vel.x, startvely = mo->vel.y; - - if (!P_TryMove (mo, ptryx, ptryy, true, walkplane, tm)) + // [RH] If walking on a slope, stay on the slope + if (!P_TryMove (mo, ptry, true, walkplane, tm)) { // blocked move AActor *BlockingMobj = mo->BlockingMobj; @@ -2020,11 +1879,11 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) (mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove) && mo->BlockingLine->sidedef[1] != NULL) { - mo->vel.z = WATER_JUMP_SPEED; + mo->Vel.Z = WATER_JUMP_SPEED; } // If the blocked move executed any push specials that changed the // actor's velocity, do not attempt to slide. - if (mo->vel.x == startvelx && mo->vel.y == startvely) + if (mo->Vel.XY() == startvel) { if (player && (i_compatflags & COMPATF_WALLRUN)) { @@ -2032,13 +1891,13 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // If the move is done a second time (because it was too fast for one move), it // is still clipped against the wall at its full speed, so you effectively // execute two moves in one tic. - P_SlideMove (mo, mo->vel.x, mo->vel.y, 1); + P_SlideMove (mo, mo->Vel, 1); } else { - P_SlideMove (mo, onestepx, onestepy, totalsteps); + P_SlideMove (mo, onestep, totalsteps); } - if ((mo->vel.x | mo->vel.y) == 0) + if (mo->Vel.XY().isZero()) { steps = 0; } @@ -2046,14 +1905,11 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { if (!player || !(i_compatflags & COMPATF_WALLRUN)) { - xmove = mo->vel.x; - ymove = mo->vel.y; - onestepx = xmove / steps; - onestepy = ymove / steps; - P_CheckSlopeWalk (mo, xmove, ymove); + move = mo->Vel; + onestep = move / steps; + P_CheckSlopeWalk (mo, move); } - startx = mo->X() - Scale (xmove, step, steps); - starty = mo->Y() - Scale (ymove, step, steps); + start = mo->Pos().XY() - move * step / steps; } } else @@ -2063,32 +1919,32 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) } else { // slide against another actor - fixed_t tx, ty; - tx = 0, ty = onestepy; - walkplane = P_CheckSlopeWalk (mo, tx, ty); - if (P_TryMove (mo, mo->X() + tx, mo->Y() + ty, true, walkplane, tm)) + DVector2 t; + t.X = 0, t.Y = onestep.Y; + walkplane = P_CheckSlopeWalk (mo, t); + if (P_TryMove (mo, mo->Pos() + t, true, walkplane, tm)) { - mo->vel.x = 0; + mo->Vel.X = 0; } else { - tx = onestepx, ty = 0; - walkplane = P_CheckSlopeWalk (mo, tx, ty); - if (P_TryMove (mo, mo->X() + tx, mo->Y() + ty, true, walkplane, tm)) + t.X = onestep.X, t.Y = 0; + walkplane = P_CheckSlopeWalk (mo, t); + if (P_TryMove (mo, mo->Pos() + t, true, walkplane, tm)) { - mo->vel.y = 0; + mo->Vel.Y = 0; } else { - mo->vel.x = mo->vel.y = 0; + mo->Vel.X = mo->Vel.Y = 0; } } if (player && player->mo == mo) { - if (mo->vel.x == 0) - player->vel.x = 0; - if (mo->vel.y == 0) - player->vel.y = 0; + if (mo->Vel.X == 0) + player->Vel.X = 0; + if (mo->Vel.Y == 0) + player->Vel.Y = 0; } steps = 0; } @@ -2105,7 +1961,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { // Struck a player/creature P_ExplodeMissile (mo, NULL, BlockingMobj); } - return oldfloorz; + return Oldfloorz; } } else @@ -2114,7 +1970,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) if (P_BounceWall (mo)) { mo->PlayBounceSound(false); - return oldfloorz; + return Oldfloorz; } } if (BlockingMobj && (BlockingMobj->flags2 & MF2_REFLECTIVE)) @@ -2123,7 +1979,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // Don't change the angle if there's THRUREFLECT on the monster. if (!(BlockingMobj->flags7 & MF7_THRUREFLECT)) { - angle = BlockingMobj->AngleTo(mo); + DAngle angle = BlockingMobj->AngleTo(mo); bool dontReflect = (mo->AdjustReflectionAngle(BlockingMobj, angle)); // Change angle for deflection/reflection @@ -2135,32 +1991,23 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { AActor *origin = tg ? mo->target : BlockingMobj->target; - float speed = (float)(mo->Speed); //dest->x - source->x - fixedvec3 vect = mo->Vec3To(origin); - vect.z += origin->height / 2; - DVector3 velocity(vect.x, vect.y, vect.z); - velocity.Resize(speed); - mo->vel.x = (fixed_t)(velocity.X); - mo->vel.y = (fixed_t)(velocity.Y); - mo->vel.z = (fixed_t)(velocity.Z); + DVector3 vect = mo->Vec3To(origin); + vect.Z += origin->Height / 2; + mo->Vel = vect.Resized(mo->Speed); } else { if ((BlockingMobj->flags7 & MF7_MIRRORREFLECT) && (tg | blockingtg)) { - mo->angle += ANGLE_180; - mo->vel.x = -mo->vel.x / 2; - mo->vel.y = -mo->vel.y / 2; - mo->vel.z = -mo->vel.z / 2; + mo->Angles.Yaw += 180.; + mo->Vel *= -.5; } else { - mo->angle = angle; - angle >>= ANGLETOFINESHIFT; - mo->vel.x = FixedMul(mo->Speed >> 1, finecosine[angle]); - mo->vel.y = FixedMul(mo->Speed >> 1, finesine[angle]); - mo->vel.z = -mo->vel.z / 2; + mo->Angles.Yaw = angle; + mo->VelFromAngle(mo->Speed / 2); + mo->Vel.Z *= -.5; } } } @@ -2174,7 +2021,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) mo->tracer = mo->target; } mo->target = BlockingMobj; - return oldfloorz; + return Oldfloorz; } explode: // explode a missile @@ -2188,52 +2035,46 @@ explode: // Hack to prevent missiles exploding against the sky. // Does not handle sky floors. mo->Destroy (); - return oldfloorz; + return Oldfloorz; } // [RH] Don't explode on horizon lines. if (mo->BlockingLine != NULL && mo->BlockingLine->special == Line_Horizon) { mo->Destroy (); - return oldfloorz; + return Oldfloorz; } } P_ExplodeMissile (mo, mo->BlockingLine, BlockingMobj); - return oldfloorz; + return Oldfloorz; } else { - mo->vel.x = mo->vel.y = 0; + mo->Vel.X = mo->Vel.Y = 0; steps = 0; } } else { - if (mo->X() != ptryx || mo->Y() != ptryy) + if (mo->Pos().XY() != ptry) { // If the new position does not match the desired position, the player // must have gone through a teleporter, so stop moving right now if it // was a regular teleporter. If it was a line-to-line or fogless teleporter, - // the move should continue, but startx, starty and xmove, ymove need to change. - if (mo->vel.x == 0 && mo->vel.y == 0) + // the move should continue, but start and move need to change. + if (mo->Vel.X == 0 && mo->Vel.Y == 0) { step = steps; } else { - angle_t anglediff = (mo->angle - oldangle) >> ANGLETOFINESHIFT; + DAngle anglediff = deltaangle(oldangle, mo->Angles.Yaw); if (anglediff != 0) { - fixed_t xnew = FixedMul(xmove, finecosine[anglediff]) - FixedMul(ymove, finesine[anglediff]); - fixed_t ynew = FixedMul(xmove, finesine[anglediff]) + FixedMul(ymove, finecosine[anglediff]); - - xmove = xnew; - ymove = ynew; - oldangle = mo->angle; // in case more moves are needed this needs to be updated. + move = move.Rotated(anglediff); + oldangle = mo->Angles.Yaw; // in case more moves are needed this needs to be updated. } - - startx = mo->X() - Scale (xmove, step, steps); - starty = mo->Y() - Scale (ymove, step, steps); + start = mo->Pos() - move * step / steps; } } } @@ -2243,14 +2084,14 @@ explode: if (player && player->mo == mo && player->cheats & CF_NOVELOCITY) { // debug option for no sliding at all - mo->vel.x = mo->vel.y = 0; - player->vel.x = player->vel.y = 0; - return oldfloorz; + mo->Vel.X = mo->Vel.Y = 0; + player->Vel.X = player->Vel.Y = 0; + return Oldfloorz; } if (mo->flags & (MF_MISSILE | MF_SKULLFLY)) { // no friction for missiles - return oldfloorz; + return Oldfloorz; } if (mo->Z() > mo->floorz && !(mo->flags2 & MF2_ONMOBJ) && @@ -2258,18 +2099,18 @@ explode: (!(mo->flags2 & MF2_FLY) || !(mo->flags & MF_NOGRAVITY)) && !mo->waterlevel) { // [RH] Friction when falling is available for larger aircontrols - if (player != NULL && level.airfriction != FRACUNIT) + if (player != NULL && level.airfriction != 1.) { - mo->vel.x = FixedMul (mo->vel.x, level.airfriction); - mo->vel.y = FixedMul (mo->vel.y, level.airfriction); + mo->Vel.X *= level.airfriction; + mo->Vel.Y *= level.airfriction; if (player->mo == mo) // Not voodoo dolls { - player->vel.x = FixedMul (player->vel.x, level.airfriction); - player->vel.y = FixedMul (player->vel.y, level.airfriction); + player->Vel.X *= level.airfriction; + player->Vel.Y *= level.airfriction; } } - return oldfloorz; + return Oldfloorz; } // killough 8/11/98: add bouncers @@ -2277,7 +2118,7 @@ explode: // killough 11/98: only include bouncers hanging off ledges if ((mo->flags & MF_CORPSE) || (mo->BounceFlags & BOUNCE_MBF && mo->Z() > mo->dropoffz) || (mo->flags6 & MF6_FALLING)) { // Don't stop sliding if halfway off a step with some velocity - if (mo->vel.x > FRACUNIT/4 || mo->vel.x < -FRACUNIT/4 || mo->vel.y > FRACUNIT/4 || mo->vel.y < -FRACUNIT/4) + if (fabs(mo->Vel.X) > 0.25 || fabs(mo->Vel.Y) > 0.25) { if (mo->floorz > mo->Sector->floorplane.ZatPoint(mo)) { @@ -2293,7 +2134,7 @@ explode: if (rover->flags&FF_SOLID && rover->top.plane->ZatPoint(mo) == mo->floorz) break; } if (i==mo->Sector->e->XFloor.ffloors.Size()) - return oldfloorz; + return Oldfloorz; } } } @@ -2302,8 +2143,7 @@ explode: // killough 11/98: // Stop voodoo dolls that have come to rest, despite any // moving corresponding player: - if (mo->vel.x > -STOPSPEED && mo->vel.x < STOPSPEED - && mo->vel.y > -STOPSPEED && mo->vel.y < STOPSPEED + if (fabs(mo->Vel.X) < STOPSPEED && fabs(mo->Vel.Y) < STOPSPEED && (!player || (player->mo != mo) || !(player->cmd.ucmd.forwardmove | player->cmd.ucmd.sidemove))) { @@ -2315,12 +2155,12 @@ explode: player->mo->PlayIdle (); } - mo->vel.x = mo->vel.y = 0; + mo->Vel.X = mo->Vel.Y = 0; mo->flags4 &= ~MF4_SCROLLMOVE; // killough 10/98: kill any bobbing velocity too (except in voodoo dolls) if (player && player->mo == mo) - player->vel.x = player->vel.y = 0; + player->Vel.X = player->Vel.Y = 0; } else { @@ -2337,10 +2177,10 @@ explode: // Reducing player velocity is no longer needed to reduce // bobbing, so ice works much better now. - fixed_t friction = P_GetFriction (mo, NULL); + double friction = P_GetFriction (mo, NULL); - mo->vel.x = FixedMul (mo->vel.x, friction); - mo->vel.y = FixedMul (mo->vel.y, friction); + mo->Vel.X *= friction; + mo->Vel.Y *= friction; // killough 10/98: Always decrease player bobbing by ORIG_FRICTION. // This prevents problems with bobbing on ice, where it was not being @@ -2348,32 +2188,41 @@ explode: if (player && player->mo == mo) // Not voodoo dolls { - player->vel.x = FixedMul (player->vel.x, ORIG_FRICTION); - player->vel.y = FixedMul (player->vel.y, ORIG_FRICTION); + player->Vel.X *= ORIG_FRICTION; + player->Vel.Y *= ORIG_FRICTION; + } + + // Don't let the velocity become less than the smallest representable fixed point value. + if (fabs(mo->Vel.X) < MinVel) mo->Vel.X = 0; + if (fabs(mo->Vel.Y) < MinVel) mo->Vel.Y = 0; + if (player && player->mo == mo) // Not voodoo dolls + { + if (fabs(player->Vel.X) < MinVel) player->Vel.X = 0; + if (fabs(player->Vel.Y) < MinVel) player->Vel.Y = 0; } } - return oldfloorz; + return Oldfloorz; } // Move this to p_inter *** void P_MonsterFallingDamage (AActor *mo) { int damage; - int vel; + double vel; if (!(level.flags2 & LEVEL2_MONSTERFALLINGDAMAGE)) return; if (mo->floorsector->Flags & SECF_NOFALLINGDAMAGE) return; - vel = abs(mo->vel.z); - if (vel > 35*FRACUNIT) + vel = fabs(mo->Vel.Z); + if (vel > 35) { // automatic death damage = TELEFRAG_DAMAGE; } else { - damage = ((vel - (23*FRACUNIT))*6)>>FRACBITS; + damage = int((vel - 23)*6); } damage = TELEFRAG_DAMAGE; // always kill 'em P_DamageMobj (mo, NULL, NULL, damage, NAME_Falling); @@ -2383,12 +2232,12 @@ void P_MonsterFallingDamage (AActor *mo) // P_ZMovement // -void P_ZMovement (AActor *mo, fixed_t oldfloorz) +void P_ZMovement (AActor *mo, double oldfloorz) { - fixed_t dist; - fixed_t delta; - fixed_t oldz = mo->Z(); - fixed_t grav = mo->GetGravity(); + double dist; + double delta; + double oldz = mo->Z(); + double grav = mo->GetGravity(); // // check for smooth step up @@ -2399,34 +2248,34 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) mo->player->deltaviewheight = mo->player->GetDeltaViewHeight(); } - mo->AddZ(mo->vel.z); + mo->AddZ(mo->Vel.Z); // // apply gravity // if (mo->Z() > mo->floorz && !(mo->flags & MF_NOGRAVITY)) { - fixed_t startvelz = mo->vel.z; + double startvelz = mo->Vel.Z; if (mo->waterlevel == 0 || (mo->player && !(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove))) { // [RH] Double gravity only if running off a ledge. Coming down from // an upward thrust (e.g. a jump) should not double it. - if (mo->vel.z == 0 && oldfloorz > mo->floorz && mo->Z() == oldfloorz) + if (mo->Vel.Z == 0 && oldfloorz > mo->floorz && mo->Z() == oldfloorz) { - mo->vel.z -= grav + grav; + mo->Vel.Z -= grav + grav; } else { - mo->vel.z -= grav; + mo->Vel.Z -= grav; } } if (mo->player == NULL) { if (mo->waterlevel >= 1) { - fixed_t sinkspeed; + double sinkspeed; if ((mo->flags & MF_SPECIAL) && !(mo->flags3 & MF3_ISMONSTER)) { // Pickup items don't sink if placed and drop slowly if dropped @@ -2440,23 +2289,23 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) // 100 being equivalent to a player. if (mo->player == NULL) { - sinkspeed = Scale(sinkspeed, clamp(mo->Mass, 1, 4000), 100); + sinkspeed = sinkspeed * clamp(mo->Mass, 1, 4000) / 100; } } - if (mo->vel.z < sinkspeed) + if (mo->Vel.Z < sinkspeed) { // Dropping too fast, so slow down toward sinkspeed. - mo->vel.z -= MAX(sinkspeed*2, -FRACUNIT*8); - if (mo->vel.z > sinkspeed) + mo->Vel.Z -= MAX(sinkspeed*2, -8.); + if (mo->Vel.Z > sinkspeed) { - mo->vel.z = sinkspeed; + mo->Vel.Z = sinkspeed; } } - else if (mo->vel.z > sinkspeed) + else if (mo->Vel.Z > sinkspeed) { // Dropping too slow/going up, so trend toward sinkspeed. - mo->vel.z = startvelz + MAX(sinkspeed/3, -FRACUNIT*8); - if (mo->vel.z < sinkspeed) + mo->Vel.Z = startvelz + MAX(sinkspeed/3, -8.); + if (mo->Vel.Z < sinkspeed) { - mo->vel.z = sinkspeed; + mo->Vel.Z = sinkspeed; } } } @@ -2465,15 +2314,15 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) { if (mo->waterlevel > 1) { - fixed_t sinkspeed = -WATER_SINK_SPEED; + double sinkspeed = -WATER_SINK_SPEED; - if (mo->vel.z < sinkspeed) + if (mo->Vel.Z < sinkspeed) { - mo->vel.z = (startvelz < sinkspeed) ? startvelz : sinkspeed; + mo->Vel.Z = (startvelz < sinkspeed) ? startvelz : sinkspeed; } else { - mo->vel.z = startvelz + ((mo->vel.z - startvelz) >> + mo->Vel.Z = startvelz + ((mo->Vel.Z - startvelz) * (mo->waterlevel == 1 ? WATER_SINK_SMALL_FACTOR : WATER_SINK_FACTOR)); } } @@ -2484,9 +2333,9 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) // Hexen yanked all items to the floor, except those being spawned at map start in the air. // Those were kept at their original height. // Do this only if the item was actually spawned by the map above ground to avoid problems. - if (mo->special1 > 0 && (mo->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) + if (mo->specialf1 > 0 && (mo->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) { - mo->SetZ(mo->floorz + mo->special1); + mo->SetZ(mo->floorz + mo->specialf1); } @@ -2497,8 +2346,8 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) { // float down towards target if too close if (!(mo->flags & (MF_SKULLFLY | MF_INFLOAT))) { - dist = mo->AproxDistance (mo->target); - delta = (mo->target->Z() + (mo->height>>1)) - mo->Z(); + dist = mo->Distance2D (mo->target); + delta = (mo->target->Center()) - mo->Z(); if (delta < 0 && dist < -(delta*3)) mo->AddZ(-mo->FloatSpeed); else if (delta > 0 && dist < (delta*3)) @@ -2509,13 +2358,31 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) { if (!mo->IsNoClip2()) { - mo->AddZ(finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8); + mo->AddZ(DAngle(360 / 80.f * level.maptime).Sin() / 8); } - mo->vel.z = FixedMul (mo->vel.z, FRICTION_FLY); + mo->Vel.Z *= FRICTION_FLY; } if (mo->waterlevel && !(mo->flags & MF_NOGRAVITY)) { - mo->vel.z = FixedMul (mo->vel.z, mo->Sector->friction); + double friction = -1; + + // Check 3D floors -- might be the source of the waterlevel + for (auto rover : mo->Sector->e->XFloor.ffloors) + { + if (!(rover->flags & FF_EXISTS)) continue; + if (!(rover->flags & FF_SWIMMABLE)) continue; + + if (mo->Z() >= rover->top.plane->ZatPoint(mo) || + mo->Center() < rover->bottom.plane->ZatPoint(mo)) + continue; + + friction = rover->model->GetFriction(rover->top.isceiling); + break; + } + if (friction < 0) + friction = mo->Sector->GetFriction(); // get real friction, even if from a terrain definition + + mo->Vel.Z *= friction; } // @@ -2545,7 +2412,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) else if (mo->flags3 & MF3_NOEXPLODEFLOOR) { P_HitFloor (mo); - mo->vel.z = 0; + mo->Vel.Z = 0; return; } else if (mo->flags3 & MF3_FLOORHUGGER) @@ -2566,41 +2433,39 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) return; } } - else if (mo->BounceFlags & BOUNCE_MBF && mo->vel.z) // check for MBF-like bounce on non-missiles + else if (mo->BounceFlags & BOUNCE_MBF && mo->Vel.Z) // check for MBF-like bounce on non-missiles { mo->FloorBounceMissile(mo->floorsector->floorplane); } if (mo->flags3 & MF3_ISMONSTER) // Blasted mobj falling { - if (mo->vel.z < -(23*FRACUNIT)) + if (mo->Vel.Z < -23) { P_MonsterFallingDamage (mo); } } mo->SetZ(mo->floorz); - if (mo->vel.z < 0) + if (mo->Vel.Z < 0) { - const fixed_t minvel = -8*FRACUNIT; // landing speed from a jump with normal gravity + const double minvel = -8; // landing speed from a jump with normal gravity // Spawn splashes, etc. P_HitFloor (mo); - if (mo->DamageType == NAME_Ice && mo->vel.z < minvel) + if (mo->DamageType == NAME_Ice && mo->Vel.Z < minvel) { mo->tics = 1; - mo->vel.x = 0; - mo->vel.y = 0; - mo->vel.z = 0; + mo->Vel.Zero(); return; } // Let the actor do something special for hitting the floor mo->HitFloor (); if (mo->player) { - if (mo->player->jumpTics < 0 || mo->vel.z < minvel) + if (mo->player->jumpTics < 0 || mo->Vel.Z < minvel) { // delay any jumping for a short while mo->player->jumpTics = 7; } - if (mo->vel.z < minvel && !(mo->flags & MF_NOGRAVITY)) + if (mo->Vel.Z < minvel && !(mo->flags & MF_NOGRAVITY)) { // Squat down. // Decrease viewheight for a moment after hitting the ground (hard), @@ -2608,11 +2473,11 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) PlayerLandedOnThing (mo, NULL); } } - mo->vel.z = 0; + mo->Vel.Z = 0; } if (mo->flags & MF_SKULLFLY) { // The skull slammed into something - mo->vel.z = -mo->vel.z; + mo->Vel.Z = -mo->Vel.Z; } mo->Crash(); } @@ -2636,7 +2501,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) // teleported the actor so it is no longer above the ceiling. if (mo->Top() > mo->ceilingz) { - mo->SetZ(mo->ceilingz - mo->height); + mo->SetZ(mo->ceilingz - mo->Height); if (mo->BounceFlags & BOUNCE_Ceilings) { // ceiling bounce mo->FloorBounceMissile (mo->ceilingsector->ceilingplane); @@ -2644,10 +2509,10 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) } if (mo->flags & MF_SKULLFLY) { // the skull slammed into something - mo->vel.z = -mo->vel.z; + mo->Vel.Z = -mo->Vel.Z; } - if (mo->vel.z > 0) - mo->vel.z = 0; + if (mo->Vel.Z > 0) + mo->Vel.Z = 0; if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP)) { if (mo->flags3 & MF3_CEILINGHUGGER) @@ -2667,7 +2532,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) P_CheckFakeFloorTriggers (mo, oldz); } -void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight) +void P_CheckFakeFloorTriggers (AActor *mo, double oldz, bool oldz_has_viewheight) { if (mo->player && (mo->player->cheats & CF_PREDICTING)) { @@ -2682,9 +2547,9 @@ void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheigh if (sec->heightsec != NULL && sec->SecActTarget != NULL) { sector_t *hs = sec->heightsec; - fixed_t waterz = hs->floorplane.ZatPoint(mo); - fixed_t newz; - fixed_t viewheight; + double waterz = hs->floorplane.ZatPoint(mo); + double newz; + double viewheight; if (mo->player != NULL) { @@ -2692,7 +2557,7 @@ void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheigh } else { - viewheight = mo->height / 2; + viewheight = mo->Height; } if (oldz > waterz && mo->Z() <= waterz) @@ -2745,7 +2610,7 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj) if (mo->player->mo == mo) { - mo->player->deltaviewheight = mo->vel.z >> 3; + mo->player->deltaviewheight = mo->Vel.Z / 8.; } if (mo->player->cheats & CF_PREDICTING) @@ -2758,7 +2623,7 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj) { grunted = false; // Why should this number vary by gravity? - if (mo->health > 0 && mo->vel.z < -mo->player->mo->GruntSpeed) + if (mo->health > 0 && mo->Vel.Z < -mo->player->mo->GruntSpeed) { S_Sound (mo, CHAN_VOICE, "*grunt", 1, ATTN_NORM); grunted = true; @@ -2781,7 +2646,7 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj) // void P_NightmareRespawn (AActor *mobj) { - fixed_t x, y, z; + double z; AActor *mo; AActor *info = mobj->GetDefault(); @@ -2796,13 +2661,11 @@ void P_NightmareRespawn (AActor *mobj) z = ONFLOORZ; // spawn it - x = mobj->SpawnPoint[0]; - y = mobj->SpawnPoint[1]; - mo = AActor::StaticSpawn(mobj->GetClass(), x, y, z, NO_REPLACE, true); + mo = AActor::StaticSpawn(mobj->GetClass(), DVector3(mobj->SpawnPoint.X, mobj->SpawnPoint.Y, z), NO_REPLACE, true); if (z == ONFLOORZ) { - mo->AddZ(mobj->SpawnPoint[2]); + mo->AddZ(mobj->SpawnPoint.Z); if (mo->Z() < mo->floorz) { // Do not respawn monsters in the floor, even if that's where they // started. The initial P_ZMovement() call would have put them on @@ -2812,12 +2675,12 @@ void P_NightmareRespawn (AActor *mobj) } if (mo->Top() > mo->ceilingz) { - mo->SetZ(mo->ceilingz - mo->height); + mo->SetZ(mo->ceilingz- mo->Height); } } else if (z == ONCEILINGZ) { - mo->AddZ(-mobj->SpawnPoint[2]); + mo->AddZ(-mobj->SpawnPoint.Z); } // If there are 3D floors, we need to find floor/ceiling again. @@ -2834,12 +2697,12 @@ void P_NightmareRespawn (AActor *mobj) } if (mo->Top() > mo->ceilingz) { // Do the same for the ceiling. - mo->SetZ(mo->ceilingz - mo->height); + mo->SetZ(mo->ceilingz - mo->Height); } } // something is occupying its position? - if (!P_CheckPosition(mo, mo->X(), mo->Y(), true)) + if (!P_CheckPosition(mo, mo->Pos(), true)) { //[GrafZahl] MF_COUNTKILL still needs to be checked here. mo->ClearCounters(); @@ -2850,12 +2713,10 @@ void P_NightmareRespawn (AActor *mobj) z = mo->Z(); // inherit attributes from deceased one - mo->SpawnPoint[0] = mobj->SpawnPoint[0]; - mo->SpawnPoint[1] = mobj->SpawnPoint[1]; - mo->SpawnPoint[2] = mobj->SpawnPoint[2]; + mo->SpawnPoint = mobj->SpawnPoint; mo->SpawnAngle = mobj->SpawnAngle; mo->SpawnFlags = mobj->SpawnFlags & ~MTF_DORMANT; // It wasn't dormant when it died, so it's not dormant now, either. - mo->angle = ANG45 * (mobj->SpawnAngle/45); + mo->Angles.Yaw = (double)mobj->SpawnAngle; mo->HandleSpawnFlags (); mo->reactiontime = 18; @@ -2864,13 +2725,13 @@ void P_NightmareRespawn (AActor *mobj) mo->skillrespawncount = mobj->skillrespawncount; - mo->PrevZ = z; // Do not interpolate Z position if we changed it since spawning. + mo->Prev.Z = z; // Do not interpolate Z position if we changed it since spawning. // spawn a teleport fog at old spot because of removal of the body? P_SpawnTeleportFog(mobj, mobj->PosPlusZ(TELEFOGHEIGHT), true, true); // spawn a teleport fog at the new spot - P_SpawnTeleportFog(mobj, x, y, z + TELEFOGHEIGHT, false, true); + P_SpawnTeleportFog(mobj, DVector3(mobj->SpawnPoint, z + TELEFOGHEIGHT), false, true); // remove the old monster mobj->Destroy (); @@ -3085,7 +2946,7 @@ void AActor::HitFloor () bool AActor::Slam (AActor *thing) { flags &= ~MF_SKULLFLY; - vel.x = vel.y = vel.z = 0; + Vel.Zero(); if (health > 0) { if (!(flags2 & MF2_DORMANT)) @@ -3109,7 +2970,7 @@ bool AActor::Slam (AActor *thing) return false; // stop moving } -bool AActor::SpecialBlastHandling (AActor *source, fixed_t strength) +bool AActor::SpecialBlastHandling (AActor *source, double strength) { return true; } @@ -3119,37 +2980,37 @@ int AActor::SpecialMissileHit (AActor *victim) return -1; } -bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle) +bool AActor::AdjustReflectionAngle (AActor *thing, DAngle &angle) { if (flags2 & MF2_DONTREFLECT) return true; if (thing->flags7 & MF7_THRUREFLECT) return false; // Change angle for reflection if (thing->flags4&MF4_SHIELDREFLECT) { - // Shield reflection (from the Centaur - if (absangle(angle - thing->angle)>>24 > 45) + // Shield reflection (from the Centaur) + if (absangle(angle, thing->Angles.Yaw) > 45) return true; // Let missile explode if (thing->IsKindOf (RUNTIME_CLASS(AHolySpirit))) // shouldn't this be handled by another flag??? return true; if (pr_reflect () < 128) - angle += ANGLE_45; + angle += 45; else - angle -= ANGLE_45; + angle -= 45; } else if (thing->flags4&MF4_DEFLECT) { // deflect (like the Heresiarch) if(pr_reflect() < 128) - angle += ANG45; + angle += 45; else - angle -= ANG45; + angle -= 45; } else { - angle += ANGLE_1 * ((pr_reflect() % 16) - 8); + angle += ((pr_reflect() % 16) - 8); } //Always check for AIMREFLECT, no matter what else is checked above. if (thing->flags7 & MF7_AIMREFLECT) @@ -3219,9 +3080,8 @@ bool AActor::IsOkayToAttack (AActor *link) // to only allow the check to succeed if the enemy was in a ~84� FOV of the player if (flags3 & MF3_SCREENSEEKER) { - angle_t angle = Friend->AngleTo(link) - Friend->angle; - angle >>= 24; - if (angle>226 || angle<30) + DAngle angle = absangle(Friend->AngleTo(link), Friend->Angles.Yaw); + if (angle < 30 * (256./360.)) { return true; } @@ -3244,11 +3104,11 @@ void AActor::SetShade (int r, int g, int b) fillcolor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b); } -void AActor::SetPitch(int p, bool interpolate, bool forceclamp) +void AActor::SetPitch(DAngle p, bool interpolate, bool forceclamp) { if (player != NULL || forceclamp) { // clamp the pitch we set - int min, max; + DAngle min, max; if (player != NULL) { @@ -3257,14 +3117,14 @@ void AActor::SetPitch(int p, bool interpolate, bool forceclamp) } else { - min = -ANGLE_90 + (1 << ANGLETOFINESHIFT); - max = ANGLE_90 - (1 << ANGLETOFINESHIFT); + min = -89.; + max = 89.; } - p = clamp(p, min, max); + p = clamp(p, min, max); } - if (p != pitch) + if (p != Angles.Pitch) { - pitch = p; + Angles.Pitch = p; if (player != NULL && interpolate) { player->cheats |= CF_INTERPVIEW; @@ -3272,11 +3132,11 @@ void AActor::SetPitch(int p, bool interpolate, bool forceclamp) } } -void AActor::SetAngle(angle_t ang, bool interpolate) +void AActor::SetAngle(DAngle ang, bool interpolate) { - if (ang != angle) + if (ang != Angles.Yaw) { - angle = ang; + Angles.Yaw = ang; if (player != NULL && interpolate) { player->cheats |= CF_INTERPVIEW; @@ -3284,11 +3144,11 @@ void AActor::SetAngle(angle_t ang, bool interpolate) } } -void AActor::SetRoll(angle_t r, bool interpolate) +void AActor::SetRoll(DAngle r, bool interpolate) { - if (r != roll) + if (r != Angles.Roll) { - roll = r; + Angles.Roll = r; if (player != NULL && interpolate) { player->cheats |= CF_INTERPVIEW; @@ -3297,20 +3157,20 @@ void AActor::SetRoll(angle_t r, bool interpolate) } -fixedvec3 AActor::GetPortalTransition(fixed_t byoffset, sector_t **pSec) +DVector3 AActor::GetPortalTransition(double byoffset, sector_t **pSec) { bool moved = false; sector_t *sec = Sector; - fixed_t testz = Z() + byoffset; - fixedvec3 pos = Pos(); + double testz = Z() + byoffset; + DVector3 pos = Pos(); while (!sec->PortalBlocksMovement(sector_t::ceiling)) { AActor *port = sec->SkyBoxes[sector_t::ceiling]; - if (testz > port->threshold) + if (testz > port->specialf1) { pos = PosRelative(port->Sector); - sec = P_PointInSector(pos.x, pos.y); + sec = P_PointInSector(pos); moved = true; } else break; @@ -3320,10 +3180,10 @@ fixedvec3 AActor::GetPortalTransition(fixed_t byoffset, sector_t **pSec) while (!sec->PortalBlocksMovement(sector_t::floor)) { AActor *port = sec->SkyBoxes[sector_t::floor]; - if (testz <= port->threshold) + if (testz <= port->specialf1) { pos = PosRelative(port->Sector); - sec = P_PointInSector(pos.x, pos.y); + sec = P_PointInSector(pos); } else break; } @@ -3340,15 +3200,13 @@ void AActor::CheckPortalTransition(bool islinked) while (!Sector->PortalBlocksMovement(sector_t::ceiling)) { AActor *port = Sector->SkyBoxes[sector_t::ceiling]; - if (Z() > port->threshold) + if (Z() > port->specialf1) { - fixedvec3 oldpos = Pos(); + DVector3 oldpos = Pos(); if (islinked && !moved) UnlinkFromWorld(); SetXYZ(PosRelative(port->Sector)); - PrevX += X() - oldpos.x; - PrevY += Y() - oldpos.y; - PrevZ += Z() - oldpos.z; - Sector = P_PointInSector(X(), Y()); + Prev = Pos() - oldpos; + Sector = P_PointInSector(Pos()); PrevPortalGroup = Sector->PortalGroup; moved = true; } @@ -3359,15 +3217,13 @@ void AActor::CheckPortalTransition(bool islinked) while (!Sector->PortalBlocksMovement(sector_t::floor)) { AActor *port = Sector->SkyBoxes[sector_t::floor]; - if (Z() < port->threshold && floorz < port->threshold) + if (Z() < port->specialf1 && floorz < port->specialf1) { - fixedvec3 oldpos = Pos(); + DVector3 oldpos = Pos(); if (islinked && !moved) UnlinkFromWorld(); SetXYZ(PosRelative(port->Sector)); - PrevX += X() - oldpos.x; - PrevY += Y() - oldpos.y; - PrevZ += Z() - oldpos.z; - Sector = P_PointInSector(X(), Y()); + Prev = Pos() - oldpos; + Sector = P_PointInSector(Pos()); PrevPortalGroup = Sector->PortalGroup; moved = true; } @@ -3383,8 +3239,7 @@ void AActor::CheckPortalTransition(bool islinked) void AActor::Tick () { // [RH] Data for Heretic/Hexen scrolling sectors - static const BYTE HexenScrollDirs[8] = { 64, 0, 192, 128, 96, 32, 224, 160 }; - static const BYTE HexenSpeedMuls[3] = { 5, 10, 25 }; + static const SBYTE HexenCompatSpeeds[] = {-25, 0, -10, -5, 0, 5, 10, 0, 25 }; static const SBYTE HexenScrollies[24][2] = { { 0, 1 }, { 0, 2 }, { 0, 4 }, @@ -3402,13 +3257,11 @@ void AActor::Tick () AActor *onmo; - int i; //assert (state != NULL); if (state == NULL) { - Printf("Actor of type %s at (%f,%f) left without a state\n", GetClass()->TypeName.GetChars(), - X()/65536., Y()/65536.); + Printf("Actor of type %s at (%f,%f) left without a state\n", GetClass()->TypeName.GetChars(), X(), Y()); Destroy(); return; } @@ -3440,7 +3293,7 @@ void AActor::Tick () UnlinkFromWorld (); flags |= MF_NOBLOCKMAP; - SetXYZ(Vec3Offset(vel.x, vel.y, vel.z)); + SetXYZ(Vec3Offset(Vel)); CheckPortalTransition(false); LinkToWorld (); } @@ -3488,7 +3341,7 @@ void AActor::Tick () { // add some smoke behind the rocket smokecounter = 0; - AActor *th = Spawn("RocketSmokeTrail", Vec3Offset(-vel.x, -vel.y, -vel.z), ALLOW_REPLACE); + AActor *th = Spawn("RocketSmokeTrail", Vec3Offset(-Vel), ALLOW_REPLACE); if (th) { th->tics -= pr_rockettrail()&3; @@ -3502,10 +3355,11 @@ void AActor::Tick () if (++smokecounter == 8) { smokecounter = 0; - angle_t moveangle = R_PointToAngle2(0,0,vel.x,vel.y); - fixed_t xo = -FixedMul(finecosine[(moveangle) >> ANGLETOFINESHIFT], radius * 2) + (pr_rockettrail() << 10); - fixed_t yo = -FixedMul(finesine[(moveangle) >> ANGLETOFINESHIFT], radius * 2) + (pr_rockettrail() << 10); - AActor * th = Spawn("GrenadeSmokeTrail", Vec3Offset(xo, yo, - (height>>3) * (vel.z>>16) + (2*height)/3), ALLOW_REPLACE); + DAngle moveangle = Vel.Angle(); + double xo = -moveangle.Cos() * radius * 2 + pr_rockettrail() / 64.; + double yo = -moveangle.Sin() * radius * 2 + pr_rockettrail() / 64.; + double zo = -Height * Vel.Z / 8. + Height * (2 / 3.); + AActor * th = Spawn("GrenadeSmokeTrail", Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (th) { th->tics -= pr_rockettrail()&3; @@ -3515,7 +3369,7 @@ void AActor::Tick () } } - fixed_t oldz = Z(); + double oldz = Z(); // [RH] Give the pain elemental vertical friction // This used to be in APainElemental::Tick but in order to use @@ -3524,14 +3378,14 @@ void AActor::Tick () { if (health >0) { - if (abs (vel.z) < FRACUNIT/4) + if (fabs (Vel.Z) < 0.25) { - vel.z = 0; + Vel.Z = 0; flags4 &= ~MF4_VFRICTION; } else { - vel.z = FixedMul (vel.z, 0xe800); + Vel.Z *= (0xe800 / 65536.); } } } @@ -3541,19 +3395,19 @@ void AActor::Tick () { if (visdir > 0) { - alpha += 0x800; - if (alpha >= OPAQUE) + Alpha += 1/32.; + if (Alpha >= 1.) { - alpha = OPAQUE; + Alpha = 1.; visdir = -1; } } else { - alpha -= 0x800; - if (alpha <= TRANSLUC25) + Alpha -= 1/32.; + if (Alpha <= 0.25) { - alpha = TRANSLUC25; + Alpha = 0.25; visdir = 1; } } @@ -3564,19 +3418,19 @@ void AActor::Tick () RenderStyle.Flags &= ~STYLEF_Alpha1; if (visdir > 0) { - alpha += 2*FRACUNIT/TICRATE; - if (alpha > OPAQUE) + Alpha += 2./TICRATE; + if (Alpha > 1.) { - alpha = OPAQUE; + Alpha = 1.; visdir = 0; } } else if (visdir < 0) { - alpha -= 3*FRACUNIT/TICRATE/2; - if (alpha < 0) + Alpha -= 1.5/TICRATE; + if (Alpha < 0) { - alpha = 0; + Alpha = 0; visdir = 0; } } @@ -3585,51 +3439,14 @@ void AActor::Tick () if (bglobal.botnum && !demoplayback && ((flags & (MF_SPECIAL|MF_MISSILE)) || (flags3 & MF3_ISMONSTER))) { - BotSupportCycles.Clock(); - bglobal.m_Thinking = true; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].Bot == NULL) - continue; - - if (flags3 & MF3_ISMONSTER) - { - if (health > 0 - && !players[i].Bot->enemy - && player ? !IsTeammate (players[i].mo) : true - && AproxDistance (players[i].mo) < MAX_MONSTER_TARGET_DIST - && P_CheckSight (players[i].mo, this, SF_SEEPASTBLOCKEVERYTHING)) - { //Probably a monster, so go kill it. - players[i].Bot->enemy = this; - } - } - else if (flags & MF_SPECIAL) - { //Item pickup time - //clock (BotWTG); - players[i].Bot->WhatToGet (this); - //unclock (BotWTG); - BotWTG++; - } - else if (flags & MF_MISSILE) - { - if (!players[i].Bot->missile && (flags3 & MF3_WARNBOT)) - { //warn for incoming missiles. - if (target != players[i].mo && players[i].Bot->Check_LOS (this, ANGLE_90)) - players[i].Bot->missile = this; - } - } - } - bglobal.m_Thinking = false; - BotSupportCycles.Unclock(); + bglobal.BotTick(this); } - //End of MC - // [RH] Consider carrying sectors here - fixed_t cummx = 0, cummy = 0; + DVector2 cumm(0, 0); if ((level.Scrolls != NULL || player != NULL) && !(flags & MF_NOCLIP) && !(flags & MF_NOSECTOR)) { - fixed_t height, waterheight; // killough 4/4/98: add waterheight + double height, waterheight; // killough 4/4/98: add waterheight const msecnode_t *node; int countx, county; @@ -3646,17 +3463,16 @@ void AActor::Tick () for (node = touching_sectorlist; node; node = node->m_tnext) { sector_t *sec = node->m_sector; - fixed_t scrollx, scrolly; + DVector2 scrollv; if (level.Scrolls != NULL) { const FSectorScrollValues *scroll = &level.Scrolls[sec - sectors]; - scrollx = scroll->ScrollX; - scrolly = scroll->ScrollY; + scrollv = scroll->Scroll; } else { - scrollx = scrolly = 0; + scrollv.Zero(); } if (player != NULL) @@ -3669,16 +3485,15 @@ void AActor::Tick () scrolltype -= Scroll_North_Slow; if (i_compatflags&COMPATF_RAVENSCROLL) { - angle_t fineangle = HexenScrollDirs[scrolltype / 3] * 32; - fixed_t carryspeed = DivScale32 (HexenSpeedMuls[scrolltype % 3], 32*CARRYFACTOR); - scrollx += FixedMul (carryspeed, finecosine[fineangle]); - scrolly += FixedMul (carryspeed, finesine[fineangle]); + scrollv.X -= HexenCompatSpeeds[HexenScrollies[scrolltype][0]+4] * (1. / (32 * CARRYFACTOR)); + scrollv.Y += HexenCompatSpeeds[HexenScrollies[scrolltype][1]+4] * (1. / (32 * CARRYFACTOR)); + } else { // Use speeds that actually match the scrolling textures! - scrollx -= HexenScrollies[scrolltype][0] << (FRACBITS-1); - scrolly += HexenScrollies[scrolltype][1] << (FRACBITS-1); + scrollv.X -= HexenScrollies[scrolltype][0] * 0.5; + scrollv.Y += HexenScrollies[scrolltype][1] * 0.5; } } else if (scrolltype >= Carry_East5 && @@ -3686,39 +3501,37 @@ void AActor::Tick () { // Heretic scroll special scrolltype -= Carry_East5; BYTE dir = HereticScrollDirs[scrolltype / 5]; - fixed_t carryspeed = DivScale32 (HereticSpeedMuls[scrolltype % 5], 32*CARRYFACTOR); + double carryspeed = HereticSpeedMuls[scrolltype % 5] * (1. / (32 * CARRYFACTOR)); if (scrolltype<=Carry_East35 && !(i_compatflags&COMPATF_RAVENSCROLL)) { // Use speeds that actually match the scrolling textures! - carryspeed = (1 << ((scrolltype%5) + FRACBITS-1)); + carryspeed = (1 << ((scrolltype%5) - 1)); } - scrollx += carryspeed * ((dir & 3) - 1); - scrolly += carryspeed * (((dir & 12) >> 2) - 1); + scrollv.X += carryspeed * ((dir & 3) - 1); + scrollv.Y += carryspeed * (((dir & 12) >> 2) - 1); } else if (scrolltype == dScroll_EastLavaDamage) { // Special Heretic scroll special if (i_compatflags&COMPATF_RAVENSCROLL) { - scrollx += DivScale32 (28, 32*CARRYFACTOR); + scrollv.X += 28. / (32*CARRYFACTOR); } else { // Use a speed that actually matches the scrolling texture! - scrollx += DivScale32 (12, 32*CARRYFACTOR); + scrollv.X += 12. / (32 * CARRYFACTOR); } } else if (scrolltype == Scroll_StrifeCurrent) { // Strife scroll special int anglespeed = tagManager.GetFirstSectorTag(sec) - 100; - fixed_t carryspeed = DivScale32 (anglespeed % 10, 16*CARRYFACTOR); - angle_t fineangle = (anglespeed / 10) << (32-3); - fineangle >>= ANGLETOFINESHIFT; - scrollx += FixedMul (carryspeed, finecosine[fineangle]); - scrolly += FixedMul (carryspeed, finesine[fineangle]); + double carryspeed = (anglespeed % 10) / (16 * CARRYFACTOR); + DAngle angle = ((anglespeed / 10) * 45.); + scrollv += angle.ToVector(carryspeed); } } - if ((scrollx | scrolly) == 0) + if (scrollv.isZero()) { continue; } @@ -3727,9 +3540,10 @@ void AActor::Tick () { continue; } - fixedvec3 pos = PosRelative(sec); + DVector3 pos = PosRelative(sec); height = sec->floorplane.ZatPoint (pos); - if (Z() > height) + double height2 = sec->floorplane.ZatPoint(this); + if (isAbove(height)) { if (heightsec == NULL) { @@ -3743,10 +3557,9 @@ void AActor::Tick () } } - cummx += scrollx; - cummy += scrolly; - if (scrollx) countx++; - if (scrolly) county++; + cumm += scrollv; + if (scrollv.X) countx++; + if (scrollv.Y) county++; } // Some levels designed with Boom in mind actually want things to accelerate @@ -3756,11 +3569,11 @@ void AActor::Tick () { if (countx > 1) { - cummx /= countx; + cumm.X /= countx; } if (county > 1) { - cummy /= county; + cumm.Y /= county; } } } @@ -3768,28 +3581,28 @@ void AActor::Tick () // [RH] If standing on a steep slope, fall down it if ((flags & MF_SOLID) && !(flags & (MF_NOCLIP|MF_NOGRAVITY)) && !(flags & MF_NOBLOCKMAP) && - vel.z <= 0 && + Vel.Z <= 0 && floorz == Z()) { secplane_t floorplane; // Check 3D floors as well - floorplane = P_FindFloorPlane(floorsector, X(), Y(), floorz); + floorplane = P_FindFloorPlane(floorsector, PosAtZ(floorz)); - if (floorplane.c < STEEPSLOPE && + if (floorplane.fC() < STEEPSLOPE && floorplane.ZatPoint (PosRelative(floorsector)) <= floorz) { const msecnode_t *node; bool dopush = true; - if (floorplane.c > STEEPSLOPE*2/3) + if (floorplane.fC() > STEEPSLOPE*2/3) { for (node = touching_sectorlist; node; node = node->m_tnext) { const sector_t *sec = node->m_sector; - if (sec->floorplane.c >= STEEPSLOPE) + if (sec->floorplane.fC() >= STEEPSLOPE) { - if (floorplane.ZatPoint (PosRelative(node->m_sector)) >= Z() - MaxStepHeight) + if (floorplane.ZatPoint(PosRelative(node->m_sector)) >= Z() - MaxStepHeight) { dopush = false; break; @@ -3799,8 +3612,7 @@ void AActor::Tick () } if (dopush) { - vel.x += floorplane.a; - vel.y += floorplane.b; + Vel += floorplane.Normal().XY(); } } } @@ -3810,19 +3622,19 @@ void AActor::Tick () // still have missiles that go straight up and down through actors without // damaging anything. // (for backwards compatibility this must check for lack of damage function, not for zero damage!) - if ((flags & MF_MISSILE) && (vel.x|vel.y) == 0 && Damage != NULL) + if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && Damage != NULL) { - vel.x = 1; + Vel.X = MinVel; } // Handle X and Y velocities BlockingMobj = NULL; - fixed_t oldfloorz = P_XYMovement (this, cummx, cummy); + double oldfloorz = P_XYMovement (this, cumm); if (ObjectFlags & OF_EuthanizeMe) { // actor was destroyed return; } - if ((vel.x | vel.y) == 0) // Actors at rest + if (Vel.X == 0 && Vel.Y == 0) // Actors at rest { if (flags2 & MF2_BLASTED) { // Reset to not blasted when velocities are gone @@ -3834,7 +3646,7 @@ void AActor::Tick () } } - if (vel.z || BlockingMobj || Z() != floorz) + if (Vel.Z != 0 || BlockingMobj || Z() != floorz) { // Handle Z velocity and gravity if (((flags2 & MF2_PASSMOBJ) || (flags & MF_SPECIAL)) && !(i_compatflags & COMPATF_NO_PASSMOBJ)) { @@ -3847,7 +3659,7 @@ void AActor::Tick () { if (player) { - if (vel.z < (fixed_t)(level.gravity * Sector->gravity * -655.36f) + if (Vel.Z < level.gravity * Sector->gravity * (-1./100)// -655.36f) && !(flags&MF_NOGRAVITY)) { PlayerLandedOnThing (this, onmo); @@ -3858,7 +3670,7 @@ void AActor::Tick () if (player && player->mo == this) { player->viewheight -= onmo->Top() - Z(); - fixed_t deltaview = player->GetDeltaViewHeight(); + double deltaview = player->GetDeltaViewHeight(); if (deltaview > player->deltaviewheight) { player->deltaviewheight = deltaview; @@ -3883,14 +3695,14 @@ void AActor::Tick () onmo->lastbump = level.maptime + TICRATE; } } - if (vel.z != 0 && (BounceFlags & BOUNCE_Actors)) + if (Vel.Z != 0 && (BounceFlags & BOUNCE_Actors)) { P_BounceActor(this, onmo, true); } else { flags2 |= MF2_ONMOBJ; - vel.z = 0; + Vel.Z = 0; Crash(); } } @@ -3910,7 +3722,7 @@ void AActor::Tick () CheckPortalTransition(true); - UpdateWaterLevel (oldz); + UpdateWaterLevel (); // [RH] Don't advance if predicting a player if (player && (player->cheats & CF_PREDICTING)) @@ -4034,7 +3846,7 @@ void AActor::CheckSectorTransition(sector_t *oldsec) { act |= SECSPAC_HitFloor; } - if (Z() + height >= Sector->ceilingplane.ZatPoint(this)) + if (Top() >= Sector->ceilingplane.ZatPoint(this)) { act |= SECSPAC_HitCeiling; } @@ -4063,10 +3875,10 @@ void AActor::CheckSectorTransition(sector_t *oldsec) // //========================================================================== -bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash) +bool AActor::UpdateWaterLevel (bool dosplash) { BYTE lastwaterlevel = waterlevel; - fixed_t fh = FIXED_MIN; + double fh = -FLT_MAX; bool reset=false; waterlevel = 0; @@ -4091,11 +3903,11 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash) if (Z() < fh) { waterlevel = 1; - if (Z() + height/2 < fh) + if (Center() < fh) { waterlevel = 2; if ((player && Z() + player->viewheight <= fh) || - (Z() + height <= fh)) + (Top() <= fh)) { waterlevel = 3; } @@ -4120,27 +3932,25 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash) else { // Check 3D floors as well! - for(unsigned int i=0;ie->XFloor.ffloors.Size();i++) + for(auto rover : Sector->e->XFloor.ffloors) { - F3DFloor* rover=Sector->e->XFloor.ffloors[i]; - if (!(rover->flags & FF_EXISTS)) continue; if(!(rover->flags & FF_SWIMMABLE) || rover->flags & FF_SOLID) continue; - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(this); - fixed_t ff_top=rover->top.plane->ZatPoint(this); + double ff_bottom=rover->bottom.plane->ZatPoint(this); + double ff_top=rover->top.plane->ZatPoint(this); - if(ff_top <= Z() || ff_bottom > (Z() + (height >> 1))) continue; + if(ff_top <= Z() || ff_bottom > (Center())) continue; fh=ff_top; if (Z() < fh) { waterlevel = 1; - if (Z() + height/2 < fh) + if (Center() < fh) { waterlevel = 2; if ((player && Z() + player->viewheight <= fh) || - (Z() + height <= fh)) + (Top() <= fh)) { waterlevel = 3; } @@ -4156,7 +3966,7 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash) // the water flags. if (boomwaterlevel == 0 && waterlevel != 0 && dosplash) { - P_HitWater(this, Sector, FIXED_MIN, FIXED_MIN, fh, true); + P_HitWater(this, Sector, PosAtZ(fh), true); } boomwaterlevel = waterlevel; if (reset) @@ -4173,7 +3983,7 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash) // //========================================================================== -AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t iz, replace_t allowreplacement, bool SpawningMapThing) +AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing) { if (type == NULL) { @@ -4200,12 +4010,12 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t actor->Conversation = NULL; } - actor->SetXYZ(ix, iy, iz); + actor->SetXYZ(pos); actor->picnum.SetInvalid(); actor->health = actor->SpawnHealth(); // Actors with zero gravity need the NOGRAVITY flag set. - if (actor->gravity == 0) actor->flags |= MF_NOGRAVITY; + if (actor->Gravity == 0) actor->flags |= MF_NOGRAVITY; FRandom &rng = bglobal.m_Thinking ? pr_botspawnmobj : pr_spawnmobj; @@ -4230,26 +4040,25 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | ActorRenderFlags::FromInt (st->GetFullbright()); actor->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98 if (G_SkillProperty(SKILLP_FastMonsters) && actor->GetClass()->FastSpeed >= 0) - actor->Speed = actor->GetClass()->FastSpeed; - actor->DamageMultiply = FRACUNIT; + actor->Speed = actor->GetClass()->FastSpeed; + actor->DamageMultiply = 1.; // set subsector and/or block links actor->LinkToWorld (SpawningMapThing); actor->ClearInterpolation(); - actor->dropoffz = // killough 11/98: for tracking dropoffs - actor->floorz = actor->Sector->floorplane.ZatPoint (ix, iy); - actor->ceilingz = actor->Sector->ceilingplane.ZatPoint (ix, iy); + actor->dropoffz = actor->floorz = actor->Sector->floorplane.ZatPoint(pos); + actor->ceilingz = actor->Sector->ceilingplane.ZatPoint(pos); // The z-coordinate needs to be set once before calling P_FindFloorCeiling // For FLOATRANDZ just use the floor here. - if (iz == ONFLOORZ || iz == FLOATRANDZ) + if (pos.Z == ONFLOORZ || pos.Z == FLOATRANDZ) { - actor->SetZ(actor->floorz, false); + actor->SetZ(actor->floorz); } - else if (iz == ONCEILINGZ) + else if (pos.Z == ONCEILINGZ) { - actor->SetZ(actor->ceilingz - actor->height); + actor->SetZ(actor->ceilingz - actor->Height); } if (SpawningMapThing || !type->IsDescendantOf (RUNTIME_CLASS(APlayerPawn))) @@ -4283,24 +4092,25 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t actor->ceilingsector = actor->Sector; } - actor->SpawnPoint[0] = ix; - actor->SpawnPoint[1] = iy; + actor->SpawnPoint.X = pos.X; + actor->SpawnPoint.Y = pos.Y; + // do not copy Z! - if (iz == ONFLOORZ) + if (pos.Z == ONFLOORZ) { actor->SetZ(actor->floorz); } - else if (iz == ONCEILINGZ) + else if (pos.Z == ONCEILINGZ) { - actor->SetZ(actor->ceilingz - actor->height); + actor->SetZ(actor->ceilingz - actor->Height); } - else if (iz == FLOATRANDZ) + else if (pos.Z == FLOATRANDZ) { - fixed_t space = actor->ceilingz - actor->height - actor->floorz; - if (space > 48*FRACUNIT) + double space = actor->ceilingz - actor->Height - actor->floorz; + if (space > 48) { - space -= 40*FRACUNIT; - actor->SetZ(MulScale8 (space, rng()) + actor->floorz + 40*FRACUNIT); + space -= 40; + actor->SetZ( space * rng() / 256. + actor->floorz + 40); } else { @@ -4309,7 +4119,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t } else { - actor->SpawnPoint[2] = (actor->Z() - actor->Sector->floorplane.ZatPoint(actor)); + actor->SpawnPoint.Z = (actor->Z() - actor->Sector->floorplane.ZatPoint(actor)); } if (actor->FloatBobPhase == (BYTE)-1) actor->FloatBobPhase = rng(); // Don't make everything bob in sync (unless deliberately told to do) @@ -4319,9 +4129,9 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t } else { - actor->floorclip = 0; + actor->Floorclip = 0; } - actor->UpdateWaterLevel (actor->Z(), false); + actor->UpdateWaterLevel (false); if (!SpawningMapThing) { actor->BeginPlay (); @@ -4352,20 +4162,10 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t return actor; } -AActor *Spawn (const char *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) +PClassActor *ClassForSpawn(FName classname) { - FName classname(type, true); - if (classname == NAME_None) - { - I_Error("Attempt to spawn actor of unknown type '%s'\n", type); - } - return Spawn(classname, x, y, z, allowreplacement); -} - -AActor *Spawn (FName classname, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) -{ - const PClass *cls = PClass::FindClass(classname); - if (cls == NULL) + PClass *cls = PClass::FindClass(classname); + if (cls == NULL) { I_Error("Attempt to spawn actor of unknown type '%s'\n", classname.GetChars()); } @@ -4373,7 +4173,7 @@ AActor *Spawn (FName classname, fixed_t x, fixed_t y, fixed_t z, replace_t allow { I_Error("Attempt to spawn non-actor of type '%s'\n", classname.GetChars()); } - return AActor::StaticSpawn (const_cast(static_cast(cls)), x, y, z, allowreplacement); + return static_cast(cls); } void AActor::LevelSpawned () @@ -4419,7 +4219,7 @@ void AActor::HandleSpawnFlags () { flags |= MF_SHADOW; RenderStyle = STYLE_Translucent; - alpha = TRANSLUC25; + Alpha = 0.25; } else if (SpawnFlags & MTF_ALTSHADOW) { @@ -4453,7 +4253,7 @@ void AActor::PostBeginPlay () { Renderer->StateChanged(this); } - PrevAngle = angle; + PrevAngles = Angles; flags7 |= MF7_HANDLENODELAY; } @@ -4560,40 +4360,40 @@ void AActor::AdjustFloorClip () return; } - fixed_t oldclip = floorclip; - fixed_t shallowestclip = FIXED_MAX; + double oldclip = Floorclip; + double shallowestclip = INT_MAX; const msecnode_t *m; // possibly standing on a 3D-floor - if (Sector->e->XFloor.ffloors.Size() && Z() > Sector->floorplane.ZatPoint(this)) floorclip = 0; + if (Sector->e->XFloor.ffloors.Size() && Z() > Sector->floorplane.ZatPoint(this)) Floorclip = 0; // [RH] clip based on shallowest floor player is standing on // If the sector has a deep water effect, then let that effect // do the floorclipping instead of the terrain type. for (m = touching_sectorlist; m; m = m->m_tnext) { - fixedvec3 pos = PosRelative(m->m_sector); + DVector3 pos = PosRelative(m->m_sector); sector_t *hsec = m->m_sector->GetHeightSec(); if (hsec == NULL && m->m_sector->floorplane.ZatPoint (pos) == Z()) { - fixed_t clip = Terrains[m->m_sector->GetTerrain(sector_t::floor)].FootClip; + double clip = Terrains[m->m_sector->GetTerrain(sector_t::floor)].FootClip; if (clip < shallowestclip) { shallowestclip = clip; } } } - if (shallowestclip == FIXED_MAX) + if (shallowestclip == INT_MAX) { - floorclip = 0; + Floorclip = 0; } else { - floorclip = shallowestclip; + Floorclip = shallowestclip; } - if (player && player->mo == this && oldclip != floorclip) + if (player && player->mo == this && oldclip != Floorclip) { - player->viewheight -= oldclip - floorclip; + player->viewheight -= (oldclip - Floorclip); player->deltaviewheight = player->GetDeltaViewHeight(); } } @@ -4612,8 +4412,8 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) player_t *p; APlayerPawn *mobj, *oldactor; BYTE state; - fixed_t spawn_x, spawn_y, spawn_z; - angle_t spawn_angle; + DVector3 spawn; + DAngle SpawnAngle; if (mthing == NULL) { @@ -4668,48 +4468,38 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) ( NULL != p->attacker ) && // don't respawn on damaging floors ( p->mo->Sector->damageamount < TELEFRAG_DAMAGE )) // this really should be a bit smarter... { - spawn_x = p->mo->X(); - spawn_y = p->mo->Y(); - spawn_z = p->mo->Z(); - - spawn_angle = p->mo->angle; + spawn = p->mo->Pos(); + SpawnAngle = p->mo->Angles.Yaw; } else { - spawn_x = mthing->x; - spawn_y = mthing->y; + spawn.X = mthing->pos.X; + spawn.Y = mthing->pos.Y; - // Allow full angular precision but avoid roundoff errors for multiples of 45 degrees. - if (mthing->angle % 45 != 0) - { - spawn_angle = mthing->angle * (ANG45 / 45); - } - else - { - spawn_angle = ANG45 * (mthing->angle / 45); - } + // Allow full angular precision + SpawnAngle = (double)mthing->angle; if (i_compatflags2 & COMPATF2_BADANGLES) { - spawn_angle += 1 << ANGLETOFINESHIFT; + SpawnAngle += 0.01; } if (GetDefaultByType(p->cls)->flags & MF_SPAWNCEILING) - spawn_z = ONCEILINGZ; + spawn.Z = ONCEILINGZ; else if (GetDefaultByType(p->cls)->flags2 & MF2_SPAWNFLOAT) - spawn_z = FLOATRANDZ; + spawn.Z = FLOATRANDZ; else - spawn_z = ONFLOORZ; + spawn.Z = ONFLOORZ; } mobj = static_cast - (Spawn (p->cls, spawn_x, spawn_y, spawn_z, NO_REPLACE)); + (Spawn (p->cls, spawn, NO_REPLACE)); if (level.flags & LEVEL_USEPLAYERSTARTZ) { - if (spawn_z == ONFLOORZ) - mobj->AddZ(mthing->z); - else if (spawn_z == ONCEILINGZ) - mobj->AddZ(-mthing->z); + if (spawn.Z == ONFLOORZ) + mobj->AddZ(mthing->pos.Z); + else if (spawn.Z == ONCEILINGZ) + mobj->AddZ(-mthing->pos.Z); P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); } @@ -4741,8 +4531,8 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); } - mobj->angle = spawn_angle; - mobj->pitch = mobj->roll = 0; + mobj->Angles.Yaw = SpawnAngle; + mobj->Angles.Pitch = mobj->Angles.Roll = 0.; mobj->health = p->health; // [RH] Set player sprite based on skin @@ -4773,11 +4563,11 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) p->BlendR = p->BlendG = p->BlendB = p->BlendA = 0.f; p->mo->ResetAirSupply(false); p->Uncrouch(); - p->MinPitch = p->MaxPitch = 0; // will be filled in by PostBeginPlay()/netcode + p->MinPitch = p->MaxPitch = 0.; // will be filled in by PostBeginPlay()/netcode p->MUSINFOactor = NULL; p->MUSINFOtics = -1; - p->vel.x = p->vel.y = 0; // killough 10/98: initialize bobbing to 0. + p->Vel.Zero(); // killough 10/98: initialize bobbing to 0. for (int ii = 0; ii < MAXPLAYERS; ++ii) { @@ -4829,15 +4619,14 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) if (multiplayer) { - unsigned an = mobj->angle >> ANGLETOFINESHIFT; - Spawn ("TeleportFog", mobj->Vec3Offset(20*finecosine[an], 20*finesine[an], TELEFOGHEIGHT), ALLOW_REPLACE); + Spawn ("TeleportFog", mobj->Vec3Angle(20., mobj->Angles.Yaw, TELEFOGHEIGHT), ALLOW_REPLACE); } // "Fix" for one of the starts on exec.wad MAP01: If you start inside the ceiling, // drop down below it, even if that means sinking into the floor. if (mobj->Top() > mobj->ceilingz) { - mobj->SetZ(mobj->ceilingz - mobj->height, false); + mobj->SetZ(mobj->ceilingz - mobj->Height, false); } // [BC] Do script stuff @@ -4889,7 +4678,6 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) PClassActor *i; int mask; AActor *mobj; - fixed_t x, y, z; if (mthing->EdNum == 0 || mthing->EdNum == -1) return NULL; @@ -4900,9 +4688,8 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) if (mentry == NULL) { // [RH] Don't die if the map tries to spawn an unknown thing - Printf ("Unknown type %i at (%i, %i)\n", - mthing->EdNum, - mthing->x>>FRACBITS, mthing->y>>FRACBITS); + Printf("Unknown type %i at (%.1f, %.1f)\n", + mthing->EdNum, mthing->pos.X, mthing->pos.Y); mentry = DoomEdMap.CheckKey(0); if (mentry == NULL) // we need a valid entry for the rest of this function so if we can't find a default, let's exit right away. { @@ -4943,10 +4730,9 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) { polyspawns_t *polyspawn = new polyspawns_t; polyspawn->next = polyspawns; - polyspawn->x = mthing->x; - polyspawn->y = mthing->y; + polyspawn->pos = mthing->pos; polyspawn->angle = mthing->angle; - polyspawn->type = mentry->Special; + polyspawn->type = mentry->Special; polyspawns = polyspawn; if (mentry->Special != SMT_PolyAnchor) po_NumPolyobjs++; @@ -5078,7 +4864,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) } else { - P_PointInSector (mthing->x, mthing->y)->seqType = type; + P_PointInSector (mthing->pos)->seqType = type; } return NULL; } @@ -5099,8 +4885,8 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) if (gameinfo.flags & GI_SHAREWARE) return NULL; - Printf ("%s at (%i, %i) has no frames\n", - i->TypeName.GetChars(), mthing->x>>FRACBITS, mthing->y>>FRACBITS); + Printf ("%s at (%.1f, %.1f) has no frames\n", + i->TypeName.GetChars(), mthing->pos.X, mthing->pos.Y); i = PClass::FindActor("Unknown"); assert(i->IsKindOf(RUNTIME_CLASS(PClassActor))); } @@ -5154,41 +4940,38 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) } // spawn it - x = mthing->x; - y = mthing->y; + double sz; if (info->flags & MF_SPAWNCEILING) - z = ONCEILINGZ; + sz = ONCEILINGZ; else if (info->flags2 & MF2_SPAWNFLOAT) - z = FLOATRANDZ; + sz = FLOATRANDZ; else - z = ONFLOORZ; + sz = ONFLOORZ; - mobj = AActor::StaticSpawn (i, x, y, z, NO_REPLACE, true); + mobj = AActor::StaticSpawn (i, DVector3(mthing->pos, sz), NO_REPLACE, true); - if (z == ONFLOORZ) + if (sz == ONFLOORZ) { - mobj->AddZ(mthing->z); + mobj->AddZ(mthing->pos.Z); if ((mobj->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) { - mobj->special1 = mthing->z; + mobj->specialf1 = mthing->pos.Z; } } - else if (z == ONCEILINGZ) - mobj->AddZ(-mthing->z); + else if (sz == ONCEILINGZ) + mobj->AddZ(-mthing->pos.Z); - mobj->SpawnPoint[0] = mthing->x; - mobj->SpawnPoint[1] = mthing->y; - mobj->SpawnPoint[2] = mthing->z; + mobj->SpawnPoint = mthing->pos; mobj->SpawnAngle = mthing->angle; mobj->SpawnFlags = mthing->flags; if (mthing->FloatbobPhase >= 0 && mthing->FloatbobPhase < 64) mobj->FloatBobPhase = mthing->FloatbobPhase; - if (mthing->gravity < 0) mobj->gravity = -mthing->gravity; - else if (mthing->gravity > 0) mobj->gravity = FixedMul(mobj->gravity, mthing->gravity); + if (mthing->Gravity < 0) mobj->Gravity = -mthing->Gravity; + else if (mthing->Gravity > 0) mobj->Gravity *= mthing->Gravity; else mobj->flags &= ~MF_NOGRAVITY; // For Hexen floatbob 'compatibility' we do not really want to alter the floorz. - if (mobj->special1 == 0 || !(mobj->flags2 & MF2_FLOATBOB) || !(ib_compatflags & BCOMPATF_FLOATBOB)) + if (mobj->specialf1 == 0 || !(mobj->flags2 & MF2_FLOATBOB) || !(ib_compatflags & BCOMPATF_FLOATBOB)) { P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); } @@ -5205,7 +4988,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->tid = mthing->thingid; mobj->AddToHash (); - mobj->PrevAngle = mobj->angle = (DWORD)((mthing->angle * CONST64(0x100000000)) / 360); + mobj->PrevAngles.Yaw = mobj->Angles.Yaw = (double)mthing->angle; // Check if this actor's mapthing has a conversation defined if (mthing->Conversation > 0) @@ -5220,18 +5003,18 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) } // Set various UDMF options - if (mthing->alpha != -1) - mobj->alpha = mthing->alpha; + if (mthing->Alpha >= 0) + mobj->Alpha = mthing->Alpha; if (mthing->RenderStyle != STYLE_Count) mobj->RenderStyle = (ERenderStyle)mthing->RenderStyle; - if (mthing->scaleX) - mobj->scaleX = FixedMul(mthing->scaleX, mobj->scaleX); - if (mthing->scaleY) - mobj->scaleY = FixedMul(mthing->scaleY, mobj->scaleY); + if (mthing->Scale.X != 0) + mobj->Scale.X = mthing->Scale.X * mobj->Scale.X; + if (mthing->Scale.Y != 0) + mobj->Scale.X = mthing->Scale.Y * mobj->Scale.Y; if (mthing->pitch) - mobj->pitch = ANGLE_1 * mthing->pitch; + mobj->Angles.Pitch = (double)mthing->pitch; if (mthing->roll) - mobj->roll = ANGLE_1 * mthing->roll; + mobj->Angles.Roll = (double)mthing->roll; if (mthing->score) mobj->Score = mthing->score; if (mthing->fillcolor) @@ -5266,14 +5049,15 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) // P_SpawnPuff // -AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t hitdir, angle_t particledir, int updown, int flags, AActor *vict) +AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, const DVector3 &pos, DAngle hitdir, DAngle particledir, int updown, int flags, AActor *vict) { AActor *puff; + double z = 0; if (!(flags & PF_NORANDOMZ)) - z += pr_spawnpuff.Random2 () << 10; + z = pr_spawnpuff.Random2() / 64.; - puff = Spawn (pufftype, x, y, z, ALLOW_REPLACE); + puff = Spawn(pufftype, pos + DVector3(0, 0, z), ALLOW_REPLACE); if (puff == NULL) return NULL; if ((puff->flags4 & MF4_RANDOMIZE) && puff->tics > 0) @@ -5295,7 +5079,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y puff->target = source; // Angle is the opposite of the hit direction (i.e. the puff faces the source.) - puff->angle = hitdir + ANGLE_180; + puff->Angles.Yaw = hitdir + 180; // If a puff has a crash state and an actor was not hit, // it will enter the crash state. This is used by the StrifeSpark @@ -5320,7 +5104,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y { if (cl_pufftype && updown != 3 && (puff->flags4 & MF4_ALLOWPARTICLES)) { - P_DrawSplash2 (32, x, y, z, particledir, updown, 1); + P_DrawSplash2 (32, pos, particledir, updown, 1); puff->renderflags |= RF_INVISIBLE; } @@ -5345,7 +5129,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y // //--------------------------------------------------------------------------- -void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator) +void P_SpawnBlood (const DVector3 &pos, DAngle dir, int damage, AActor *originator) { AActor *th; PalEntry bloodcolor = originator->GetBloodColor(); @@ -5358,10 +5142,10 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc if (bloodcls != NULL) { - z += pr_spawnblood.Random2 () << 10; - th = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement - th->vel.z = FRACUNIT*2; - th->angle = dir; + double z = pr_spawnblood.Random2 () / 64.; + th = Spawn(bloodcls, pos + DVector3(0, 0, z), NO_REPLACE); // GetBloodType already performed the replacement + th->Vel.Z = 2; + th->Angles.Yaw = dir; // [NG] Applying PUFFGETSOWNER to the blood will make it target the owner if (th->flags5 & MF5_PUFFGETSOWNER) th->target = originator; if (gameinfo.gametype & GAME_DoomChex) @@ -5431,7 +5215,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc } if (bloodtype >= 1) - P_DrawSplash2 (40, x, y, z, dir, 2, bloodcolor); + P_DrawSplash2 (40, pos, dir, 2, bloodcolor); } //--------------------------------------------------------------------------- @@ -5440,7 +5224,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc // //--------------------------------------------------------------------------- -void P_BloodSplatter (fixedvec3 pos, AActor *originator) +void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle) { PalEntry bloodcolor = originator->GetBloodColor(); PClassActor *bloodcls = originator->GetBloodType(1); @@ -5456,9 +5240,9 @@ void P_BloodSplatter (fixedvec3 pos, AActor *originator) mo = Spawn(bloodcls, pos, NO_REPLACE); // GetBloodType already performed the replacement mo->target = originator; - mo->vel.x = pr_splatter.Random2 () << 10; - mo->vel.y = pr_splatter.Random2 () << 10; - mo->vel.z = 3*FRACUNIT; + mo->Vel.X = pr_splatter.Random2 () / 64.; + mo->Vel.Y = pr_splatter.Random2() / 64.; + mo->Vel.Z = 3; // colorize the blood! if (bloodcolor!=0 && !(mo->flags2 & MF2_DONTTRANSLATE)) @@ -5470,7 +5254,7 @@ void P_BloodSplatter (fixedvec3 pos, AActor *originator) } if (bloodtype >= 1) { - P_DrawSplash2 (40, pos.x, pos.y, pos.z, 0u - originator->AngleTo(pos), 2, bloodcolor); + P_DrawSplash2 (40, pos, hitangle-180., 2, bloodcolor); } } @@ -5480,7 +5264,7 @@ void P_BloodSplatter (fixedvec3 pos, AActor *originator) // //=========================================================================== -void P_BloodSplatter2 (fixedvec3 pos, AActor *originator) +void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle) { PalEntry bloodcolor = originator->GetBloodColor(); PClassActor *bloodcls = originator->GetBloodType(2); @@ -5493,11 +5277,12 @@ void P_BloodSplatter2 (fixedvec3 pos, AActor *originator) if (bloodcls != NULL) { AActor *mo; - - pos.x += ((pr_splat()-128)<<11); - pos.y += ((pr_splat()-128)<<11); - mo = Spawn (bloodcls, pos, NO_REPLACE); // GetBloodType already performed the replacement + DVector2 add; + add.X = (pr_splat()-128) / 32.; + add.Y = (pr_splat()-128) / 32.; + + mo = Spawn (bloodcls, pos + add, NO_REPLACE); // GetBloodType already performed the replacement mo->target = originator; // colorize the blood! @@ -5510,7 +5295,7 @@ void P_BloodSplatter2 (fixedvec3 pos, AActor *originator) } if (bloodtype >= 1) { - P_DrawSplash2 (100, pos.x, pos.y, pos.z, 0u - originator->AngleTo(pos), 2, bloodcolor); + P_DrawSplash2(40, pos, hitangle - 180., 2, bloodcolor); } } @@ -5525,10 +5310,10 @@ void P_RipperBlood (AActor *mo, AActor *bleeder) PalEntry bloodcolor = bleeder->GetBloodColor(); PClassActor *bloodcls = bleeder->GetBloodType(); - fixed_t xo = (pr_ripperblood.Random2() << 12); - fixed_t yo = (pr_ripperblood.Random2() << 12); - fixed_t zo = (pr_ripperblood.Random2() << 12); - fixedvec3 pos = mo->Vec3Offset(xo, yo, zo); + double xo = pr_ripperblood.Random2() / 16.; + double yo = pr_ripperblood.Random2() / 16.; + double zo = pr_ripperblood.Random2() / 16.; + DVector3 pos = mo->Vec3Offset(xo, yo, zo); int bloodtype = cl_bloodtype; @@ -5543,8 +5328,8 @@ void P_RipperBlood (AActor *mo, AActor *bleeder) if (th->flags5 & MF5_PUFFGETSOWNER) th->target = bleeder; if (gameinfo.gametype == GAME_Heretic) th->flags |= MF_NOGRAVITY; - th->vel.x = mo->vel.x >> 1; - th->vel.y = mo->vel.y >> 1; + th->Vel.X = mo->Vel.X / 2; + th->Vel.Y = mo->Vel.Y / 2; th->tics += pr_ripperblood () & 3; // colorize the blood! @@ -5557,7 +5342,7 @@ void P_RipperBlood (AActor *mo, AActor *bleeder) } if (bloodtype >= 1) { - P_DrawSplash2 (28, pos.x, pos.y, pos.z, 0, 0, bloodcolor); + P_DrawSplash2(28, pos, bleeder->AngleTo(mo) + 180., 0, bloodcolor); } } @@ -5586,7 +5371,7 @@ int P_GetThingFloorType (AActor *thing) // Returns true if hit liquid and splashed, false if not. //--------------------------------------------------------------------------- -bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool checkabove, bool alert, bool force) +bool P_HitWater (AActor * thing, sector_t * sec, const DVector3 &pos, bool checkabove, bool alert, bool force) { if (thing->flags3 & MF3_DONTSPLASH) return false; @@ -5599,18 +5384,15 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z int terrainnum; sector_t *hsec = NULL; - if (x == FIXED_MIN) x = thing->X(); - if (y == FIXED_MIN) y = thing->Y(); - if (z == FIXED_MIN) z = thing->Z(); // don't splash above the object if (checkabove) { - fixed_t compare_z = thing->Z() + (thing->height >> 1); + double compare_z = thing->Center(); // Missiles are typically small and fast, so they might // end up submerged by the move that calls P_HitWater. if (thing->flags & MF_MISSILE) - compare_z -= thing->vel.z; - if (z > compare_z) + compare_z -= thing->Vel.Z; + if (pos.Z > compare_z) return false; } @@ -5621,10 +5403,10 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z // it is not guaranteed that all players have GL nodes loaded. if (!multiplayer && thing->subsector->sector != thing->subsector->render_sector) { - fixed_t zs = thing->subsector->sector->floorplane.ZatPoint(x, y); - fixed_t zr = thing->subsector->render_sector->floorplane.ZatPoint(x, y); + double zs = thing->subsector->sector->floorplane.ZatPoint(pos); + double zr = thing->subsector->render_sector->floorplane.ZatPoint(pos); - if (zs > zr && thing->z >= zs) return false; + if (zs > zr && thing->Z() >= zs) return false; } #endif @@ -5633,20 +5415,20 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z { for (unsigned int i = 0; ie->XFloor.ffloors.Size(); i++) { - F3DFloor * rover = sec->e->XFloor.ffloors[i]; - if (!(rover->flags & FF_EXISTS)) continue; - fixed_t planez = rover->top.plane->ZatPoint(x, y); - if (z > planez - FRACUNIT / 2 && z < planez + FRACUNIT / 2) // allow minor imprecisions - { - if (rover->flags & (FF_SOLID | FF_SWIMMABLE)) + F3DFloor * rover = sec->e->XFloor.ffloors[i]; + if (!(rover->flags & FF_EXISTS)) continue; + double planez = rover->top.plane->ZatPoint(pos); + if (pos.Z > planez - 0.5 && pos.Z < planez + 0.5) // allow minor imprecisions { - terrainnum = rover->model->GetTerrain(rover->top.isceiling); - goto foundone; + if (rover->flags & (FF_SOLID | FF_SWIMMABLE)) + { + terrainnum = rover->model->GetTerrain(rover->top.isceiling); + goto foundone; + } } + planez = rover->bottom.plane->ZatPoint(pos); + if (planez < pos.Z && !(planez < thing->floorz)) return false; } - planez = rover->bottom.plane->ZatPoint(x, y); - if (planez < z && !(planez < thing->floorz)) return false; - } } hsec = sec->GetHeightSec(); if (force || hsec == NULL || !(hsec->MoreFlags & SECF_CLIPFAKEPLANES)) @@ -5667,13 +5449,13 @@ foundone: return Terrains[terrainnum].IsLiquid; // don't splash when touching an underwater floor - if (thing->waterlevel>=1 && z<=thing->floorz) return Terrains[terrainnum].IsLiquid; + if (thing->waterlevel >= 1 && pos.Z <= thing->floorz) return Terrains[terrainnum].IsLiquid; plane = hsec != NULL? &sec->heightsec->floorplane : &sec->floorplane; // Don't splash for living things with small vertical velocities. // There are levels where the constant splashing from the monsters gets extremely annoying - if (((thing->flags3&MF3_ISMONSTER || thing->player) && thing->vel.z >= -6*FRACUNIT) && !force) + if (((thing->flags3&MF3_ISMONSTER || thing->player) && thing->Vel.Z >= -6) && !force) return Terrains[terrainnum].IsLiquid; splash = &Splashes[splashnum]; @@ -5684,28 +5466,28 @@ foundone: if (smallsplash && splash->SmallSplash) { - mo = Spawn (splash->SmallSplash, x, y, z, ALLOW_REPLACE); - if (mo) mo->floorclip += splash->SmallSplashClip; + mo = Spawn (splash->SmallSplash, pos, ALLOW_REPLACE); + if (mo) mo->Floorclip += splash->SmallSplashClip; } else { if (splash->SplashChunk) { - mo = Spawn (splash->SplashChunk, x, y, z, ALLOW_REPLACE); + mo = Spawn (splash->SplashChunk, pos, ALLOW_REPLACE); mo->target = thing; if (splash->ChunkXVelShift != 255) { - mo->vel.x = pr_chunk.Random2() << splash->ChunkXVelShift; + mo->Vel.X = (pr_chunk.Random2() << splash->ChunkXVelShift) / 65536.; } if (splash->ChunkYVelShift != 255) { - mo->vel.y = pr_chunk.Random2() << splash->ChunkYVelShift; + mo->Vel.Y = (pr_chunk.Random2() << splash->ChunkYVelShift) / 65536.; } - mo->vel.z = splash->ChunkBaseZVel + (pr_chunk() << splash->ChunkZVelShift); + mo->Vel.Z = splash->ChunkBaseZVel + (pr_chunk() << splash->ChunkZVelShift) / 65536.; } if (splash->SplashBase) { - mo = Spawn (splash->SplashBase, x, y, z, ALLOW_REPLACE); + mo = Spawn (splash->SplashBase, pos, ALLOW_REPLACE); } if (thing->player && !splash->NoAlert && alert) { @@ -5720,7 +5502,7 @@ foundone: } else { - S_Sound (x, y, z, CHAN_ITEM, smallsplash ? + S_Sound (pos, CHAN_ITEM, smallsplash ? splash->SmallSplashSound : splash->NormalSplashSound, 1, ATTN_IDLE); } @@ -5742,7 +5524,7 @@ bool P_HitFloor (AActor *thing) // killough 11/98: touchy objects explode on impact // Allow very short drops to be safe, so that a touchy can be summoned without exploding. - if (thing->flags6 & MF6_TOUCHY && ((thing->flags6 & MF6_ARMED) || thing->IsSentient()) && ((thing->vel.z) < (-5 * FRACUNIT))) + if (thing->flags6 & MF6_TOUCHY && ((thing->flags6 & MF6_ARMED) || thing->IsSentient()) && thing->Vel.Z < -5) { thing->flags6 &= ~MF6_ARMED; // Disarm P_DamageMobj (thing, NULL, NULL, thing->health, NAME_Crush, DMG_FORCED); // kill object @@ -5753,11 +5535,11 @@ bool P_HitFloor (AActor *thing) return false; // don't splash if landing on the edge above water/lava/etc.... - fixedvec3 pos; + DVector3 pos; for (m = thing->touching_sectorlist; m; m = m->m_tnext) { pos = thing->PosRelative(m->m_sector); - if (thing->Z() == m->m_sector->floorplane.ZatPoint(pos.x, pos.y)) + if (thing->Z() == m->m_sector->floorplane.ZatPoint(pos)) { break; } @@ -5769,7 +5551,7 @@ bool P_HitFloor (AActor *thing) if (!(rover->flags & FF_EXISTS)) continue; if (rover->flags & (FF_SOLID|FF_SWIMMABLE)) { - if (rover->top.plane->ZatPoint(pos.x, pos.y) == thing->Z()) + if (rover->top.plane->ZatPoint(pos) == thing->Z()) { return P_HitWater (thing, m->m_sector, pos); } @@ -5792,7 +5574,7 @@ bool P_HitFloor (AActor *thing) // //--------------------------------------------------------------------------- -void P_CheckSplash(AActor *self, fixed_t distance) +void P_CheckSplash(AActor *self, double distance) { sector_t *floorsec; self->Sector->LowestFloorAt(self, &floorsec); @@ -5801,8 +5583,9 @@ void P_CheckSplash(AActor *self, fixed_t distance) // Explosion splashes never alert monsters. This is because A_Explode has // a separate parameter for that so this would get in the way of proper // behavior. - fixedvec3 pos = self->PosRelative(floorsec); - P_HitWater (self, floorsec, pos.x, pos.y, self->floorz, false, false); + DVector3 pos = self->PosRelative(floorsec); + pos.Z = self->floorz; + P_HitWater (self, floorsec, pos, false, false); } } @@ -5815,7 +5598,7 @@ void P_CheckSplash(AActor *self, fixed_t distance) // //--------------------------------------------------------------------------- -bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist) +bool P_CheckMissileSpawn (AActor* th, double maxdist) { // [RH] Don't decrement tics if they are already less than 1 if ((th->flags4 & MF4_RANDOMIZE) && th->tics > 0) @@ -5828,9 +5611,8 @@ bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist) if (maxdist > 0) { // move a little forward so an angle can be computed if it immediately explodes - DVector3 advance(FIXED2DBL(th->vel.x), FIXED2DBL(th->vel.y), FIXED2DBL(th->vel.z)); - double maxsquared = FIXED2DBL(maxdist); - maxsquared *= maxsquared; + DVector3 advance = th->Vel; + double maxsquared = maxdist*maxdist; // Keep halving the advance vector until we get something less than maxdist // units away, since we still want to spawn the missile inside the shooter. @@ -5838,11 +5620,8 @@ bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist) { advance *= 0.5f; } - while (DVector2(advance).LengthSquared() >= maxsquared); - th->SetXYZ( - th->X() + FLOAT2FIXED(advance.X), - th->Y() + FLOAT2FIXED(advance.Y), - th->Z() + FLOAT2FIXED(advance.Z)); + while (advance.XY().LengthSquared() >= maxsquared); + th->SetXYZ(th->Pos() + advance); } FCheckPosition tm(!!(th->flags2 & MF2_RIP)); @@ -5866,7 +5645,7 @@ bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist) bool MBFGrenade = (!(th->flags & MF_MISSILE) || (th->BounceFlags & BOUNCE_MBF)); // killough 3/15/98: no dropoff (really = don't care for missiles) - if (!(P_TryMove (th, th->X(), th->Y(), false, NULL, tm, true))) + if (!(P_TryMove (th, th->Pos(), false, NULL, tm, true))) { // [RH] Don't explode ripping missiles that spawn inside something if (th->BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (th->BlockingMobj->flags5 & MF5_DONTRIP)) @@ -5920,12 +5699,12 @@ void P_PlaySpawnSound(AActor *missile, AActor *spawner) // If there is no spawner use the spawn position. // But not in a silenced sector. if (!(missile->Sector->Flags & SECF_SILENT)) - S_Sound (missile->X(), missile->Y(), missile->Z(), CHAN_WEAPON, missile->SeeSound, 1, ATTN_NORM); + S_Sound (missile->Pos(), CHAN_WEAPON, missile->SeeSound, 1, ATTN_NORM); } } } -static fixed_t GetDefaultSpeed(PClassActor *type) +static double GetDefaultSpeed(PClassActor *type) { if (type == NULL) return 0; @@ -5950,21 +5729,19 @@ AActor *P_SpawnMissile (AActor *source, AActor *dest, PClassActor *type, AActor { return NULL; } - return P_SpawnMissileXYZ (source->X(), source->Y(), source->Z() + 32*FRACUNIT + source->GetBobOffset(), - source, dest, type, true, owner); + return P_SpawnMissileXYZ (source->PosPlusZ(32 + source->GetBobOffset()), source, dest, type, true, owner); } -AActor *P_SpawnMissileZ (AActor *source, fixed_t z, AActor *dest, PClassActor *type) +AActor *P_SpawnMissileZ (AActor *source, double z, AActor *dest, PClassActor *type) { if (source == NULL) { return NULL; } - return P_SpawnMissileXYZ (source->X(), source->Y(), z, source, dest, type); + return P_SpawnMissileXYZ (source->PosAtZ(z), source, dest, type); } -AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, - AActor *source, AActor *dest, PClassActor *type, bool checkspawn, AActor *owner) +AActor *P_SpawnMissileXYZ (DVector3 pos, AActor *source, AActor *dest, PClassActor *type, bool checkspawn, AActor *owner) { if (source == NULL) { @@ -5978,12 +5755,12 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, return NULL; } - if (z != ONFLOORZ && z != ONCEILINGZ) + if (pos.Z != ONFLOORZ && pos.Z != ONCEILINGZ) { - z -= source->floorclip; + pos.Z -= source->Floorclip; } - AActor *th = Spawn (type, x, y, z, ALLOW_REPLACE); + AActor *th = Spawn (type, pos, ALLOW_REPLACE); P_PlaySpawnSound(th, source); @@ -5991,7 +5768,7 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, if (owner == NULL) owner = source; th->target = owner; - float speed = (float)(th->Speed); + double speed = th->Speed; // [RH] // Hexen calculates the missile velocity based on the source's location. @@ -5999,37 +5776,35 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, // missile? // Answer: No, because this way, you can set up sets of parallel missiles. - fixedvec3 fixvel = source->Vec3To(dest); - DVector3 velocity(fixvel.x, fixvel.y, fixvel.z); + DVector3 velocity = source->Vec3To(dest); // Floor and ceiling huggers should never have a vertical component to their velocity if (th->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)) { velocity.Z = 0; } // [RH] Adjust the trajectory if the missile will go over the target's head. - else if (z - source->Z() >= dest->height) + else if (pos.Z - source->Z() >= dest->Height) { - velocity.Z += (dest->height - z + source->Z()); + velocity.Z += (dest->Height - pos.Z + source->Z()); } - velocity.Resize (speed); - th->vel.x = xs_CRoundToInt(velocity.X); - th->vel.y = xs_CRoundToInt(velocity.Y); - th->vel.z = xs_CRoundToInt(velocity.Z); + th->Vel = velocity.Resized(speed); // invisible target: rotate velocity vector in 2D // [RC] Now monsters can aim at invisible player as if they were fully visible. if (dest->flags & MF_SHADOW && !(source->flags6 & MF6_SEEINVISIBLE)) { - angle_t an = pr_spawnmissile.Random2 () << 20; - an >>= ANGLETOFINESHIFT; + DAngle an = pr_spawnmissile.Random2() * (22.5 / 256); + double c = an.Cos(); + double s = an.Sin(); - fixed_t newx = DMulScale16 (th->vel.x, finecosine[an], -th->vel.y, finesine[an]); - fixed_t newy = DMulScale16 (th->vel.x, finesine[an], th->vel.y, finecosine[an]); - th->vel.x = newx; - th->vel.y = newy; + double newx = th->Vel.X * c - th->Vel.Y * s; + double newy = th->Vel.X * s + th->Vel.Y * c; + + th->Vel.X = newx; + th->Vel.Y = newy; } - th->angle = R_PointToAngle2 (0, 0, th->vel.x, th->vel.y); + th->AngleFromVel(); if (th->flags4 & MF4_SPECTRAL) { @@ -6045,25 +5820,17 @@ AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassAct { return NULL; } - angle_t an; - fixed_t dist; - AActor *th = Spawn (type, source->PosPlusZ(4*8*FRACUNIT), ALLOW_REPLACE); + AActor *th = Spawn (type, source->PosPlusZ(32.), ALLOW_REPLACE); P_PlaySpawnSound(th, source); th->target = owner; // record missile's originator - th->angle = an = source->AngleTo(dest); - an >>= ANGLETOFINESHIFT; - th->vel.x = FixedMul (th->Speed, finecosine[an]); - th->vel.y = FixedMul (th->Speed, finesine[an]); + th->Angles.Yaw = source->AngleTo(dest); + th->VelFromAngle(); - dist = source->AproxDistance (dest); - if (th->Speed) dist = dist / th->Speed; - if (dist < 1) - dist = 1; - - th->vel.z = (dest->Z() - source->Z()) / dist; + double dist = source->DistanceBySpeed(dest, MAX(1., th->Speed)); + th->Vel.Z = (dest->Z() - source->Z()) / dist; if (th->flags4 & MF4_SPECTRAL) { @@ -6083,42 +5850,38 @@ AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassAct // //--------------------------------------------------------------------------- -AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, - angle_t angle, fixed_t vz) +AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, DAngle angle, double vz) { if (source == NULL) { return NULL; } - return P_SpawnMissileAngleZSpeed (source, source->Z() + 32*FRACUNIT + source->GetBobOffset(), - type, angle, vz, GetDefaultSpeed (type)); + return P_SpawnMissileAngleZSpeed (source, source->Z() + 32 + source->GetBobOffset(), type, angle, vz, GetDefaultSpeed (type)); } -AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, - PClassActor *type, angle_t angle, fixed_t vz) +AActor *P_SpawnMissileAngleZ (AActor *source, double z, PClassActor *type, DAngle angle, double vz) { - return P_SpawnMissileAngleZSpeed (source, z, type, angle, vz, - GetDefaultSpeed (type)); + return P_SpawnMissileAngleZSpeed (source, z, type, angle, vz, GetDefaultSpeed (type)); } -AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassActor *type) +AActor *P_SpawnMissileZAimed (AActor *source, double z, AActor *dest, PClassActor *type) { if (source == NULL) { return NULL; } - angle_t an; - fixed_t dist; - fixed_t speed; - fixed_t vz; + DAngle an; + double dist; + double speed; + double vz; - an = source->angle; + an = source->Angles.Yaw; if (dest->flags & MF_SHADOW) { - an += pr_spawnmissile.Random2() << 20; + an += pr_spawnmissile.Random2() * (16. / 360.); } - dist = source->AproxDistance (dest); + dist = source->Distance2D (dest); speed = GetDefaultSpeed (type); dist /= speed; vz = dist != 0 ? (dest->Z() - source->Z())/dist : speed; @@ -6127,26 +5890,15 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassAct //--------------------------------------------------------------------------- // -// FUNC P_SpawnMissileAngleSpeed +// FUNC P_SpawnMissileAngleZSpeed // // Returns NULL if the missile exploded immediately, otherwise returns // a mobj_t pointer to the missile. // //--------------------------------------------------------------------------- -AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type, - angle_t angle, fixed_t vz, fixed_t speed) -{ - if (source == NULL) - { - return NULL; - } - return P_SpawnMissileAngleZSpeed (source, source->Z() + 32*FRACUNIT + source->GetBobOffset(), - type, angle, vz, speed); -} - -AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, - PClassActor *type, angle_t angle, fixed_t vz, fixed_t speed, AActor *owner, bool checkspawn) +AActor *P_SpawnMissileAngleZSpeed (AActor *source, double z, + PClassActor *type, DAngle angle, double vz, double speed, AActor *owner, bool checkspawn) { if (source == NULL) { @@ -6156,19 +5908,17 @@ AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, if (z != ONFLOORZ && z != ONCEILINGZ) { - z -= source->floorclip; + z -= source->Floorclip; } - mo = Spawn (type, source->X(), source->Y(), z, ALLOW_REPLACE); + mo = Spawn (type, source->PosAtZ(z), ALLOW_REPLACE); P_PlaySpawnSound(mo, source); if (owner == NULL) owner = source; mo->target = owner; - mo->angle = angle; - angle >>= ANGLETOFINESHIFT; - mo->vel.x = FixedMul (speed, finecosine[angle]); - mo->vel.y = FixedMul (speed, finesine[angle]); - mo->vel.z = vz; + mo->Angles.Yaw = angle; + mo->VelFromAngle(speed); + mo->Vel.Z = vz; if (mo->flags4 & MF4_SPECTRAL) { @@ -6193,24 +5943,25 @@ AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type) { return NULL; } - return P_SpawnPlayerMissile (source, 0, 0, 0, type, source->angle); + return P_SpawnPlayerMissile (source, 0, 0, 0, type, source->Angles.Yaw); } -AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, angle_t angle) +AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, DAngle angle) { return P_SpawnPlayerMissile (source, 0, 0, 0, type, angle); } -AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, - PClassActor *type, angle_t angle, FTranslatedLineTarget *pLineTarget, AActor **pMissileActor, +AActor *P_SpawnPlayerMissile (AActor *source, double x, double y, double z, + PClassActor *type, DAngle angle, FTranslatedLineTarget *pLineTarget, AActor **pMissileActor, bool nofreeaim, bool noautoaim, int aimflags) { + //static const double angdiff[3] = { -5.625, 5.625, 0 }; static const int angdiff[3] = { -(1<<26), 1<<26, 0 }; - angle_t an = angle; - angle_t pitch; + DAngle an = angle; + DAngle pitch; FTranslatedLineTarget scratch; AActor *defaultobject = GetDefaultByType(type); - int vrange = nofreeaim ? ANGLE_1*35 : 0; + DAngle vrange = nofreeaim ? 35. : 0.; if (source == NULL) { @@ -6221,7 +5972,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, { // Keep exactly the same angle and pitch as the player's own aim an = angle; - pitch = source->pitch; + pitch = source->Angles.Pitch; pLineTarget->linetarget = NULL; } else // see which target is to be aimed at @@ -6229,7 +5980,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, // [XA] If MaxTargetRange is defined in the spawned projectile, use this as the // maximum range for the P_AimLineAttack call later; this allows MaxTargetRange // to function as a "maximum tracer-acquisition range" for seeker missiles. - fixed_t linetargetrange = defaultobject->maxtargetrange > 0 ? defaultobject->maxtargetrange*64 : 16*64*FRACUNIT; + double linetargetrange = defaultobject->maxtargetrange > 0 ? defaultobject->maxtargetrange*64 : 16*64.; int i = 2; do @@ -6240,7 +5991,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, if (source->player != NULL && !nofreeaim && level.IsFreelookAllowed() && - source->player->userinfo.GetAimDist() <= ANGLE_1/2) + source->player->userinfo.GetAimDist() <= 0.5) { break; } @@ -6251,7 +6002,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, an = angle; if (nofreeaim || !level.IsFreelookAllowed()) { - pitch = 0; + pitch = 0.; } } } @@ -6259,14 +6010,14 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, if (z != ONFLOORZ && z != ONCEILINGZ) { // Doom spawns missiles 4 units lower than hitscan attacks for players. - z += source->Z() + (source->height>>1) - source->floorclip; + z += source->Center() - source->Floorclip; if (source->player != NULL) // Considering this is for player missiles, it better not be NULL. { - z += FixedMul (source->player->mo->AttackZOffset - 4*FRACUNIT, source->player->crouchfactor); + z += ((source->player->mo->AttackZOffset - 4) * source->player->crouchfactor); } else { - z += 4*FRACUNIT; + z += 4; } // Do not fire beneath the floor. if (z < source->floorz) @@ -6274,30 +6025,20 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, z = source->floorz; } } - fixedvec2 pos = source->Vec2Offset(x, y); - AActor *MissileActor = Spawn (type, pos.x, pos.y, z, ALLOW_REPLACE); + DVector3 pos = source->Vec2OffsetZ(x, y, z); + AActor *MissileActor = Spawn (type, pos, ALLOW_REPLACE); if (pMissileActor) *pMissileActor = MissileActor; P_PlaySpawnSound(MissileActor, source); MissileActor->target = source; - MissileActor->angle = an; - - fixed_t vx, vy, vz, speed; - - vx = FixedMul (finecosine[pitch>>ANGLETOFINESHIFT], finecosine[an>>ANGLETOFINESHIFT]); - vy = FixedMul (finecosine[pitch>>ANGLETOFINESHIFT], finesine[an>>ANGLETOFINESHIFT]); - vz = -finesine[pitch>>ANGLETOFINESHIFT]; - speed = MissileActor->Speed; - - DVector3 vec(vx, vy, vz); - - if (MissileActor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)) + MissileActor->Angles.Yaw = an; + if (MissileActor->flags3 & (MF3_FLOORHUGGER | MF3_CEILINGHUGGER)) { - vec.Z = 0; + MissileActor->VelFromAngle(); + } + else + { + MissileActor->Vel3DFromAngle(pitch, MissileActor->Speed); } - vec.Resize(speed); - MissileActor->vel.x = xs_CRoundToInt(vec.X); - MissileActor->vel.y = xs_CRoundToInt(vec.Y); - MissileActor->vel.z = xs_CRoundToInt(vec.Z); if (MissileActor->flags4 & MF4_SPECTRAL) { @@ -6552,12 +6293,12 @@ int AActor::SpawnHealth() const } else if (flags & MF_FRIENDLY) { - int adj = FixedMul(defhealth, G_SkillProperty(SKILLP_FriendlyHealth)); + int adj = int(defhealth * G_SkillProperty(SKILLP_FriendlyHealth)); return (adj <= 0) ? 1 : adj; } else { - int adj = FixedMul(defhealth, G_SkillProperty(SKILLP_MonsterHealth)); + int adj = int(defhealth * G_SkillProperty(SKILLP_MonsterHealth)); return (adj <= 0) ? 1 : adj; } } @@ -6615,13 +6356,13 @@ int AActor::GetGibHealth() const } else { - return -FixedMul(SpawnHealth(), gameinfo.gibfactor); + return -int(SpawnHealth() * gameinfo.gibfactor); } } -fixed_t AActor::GetCameraHeight() const +double AActor::GetCameraHeight() const { - return GetClass()->CameraHeight == FIXED_MIN ? height / 2 : GetClass()->CameraHeight; + return GetClass()->CameraHeight == INT_MIN ? Height / 2 : GetClass()->CameraHeight; } DDropItem *AActor::GetDropItems() const @@ -6629,10 +6370,10 @@ DDropItem *AActor::GetDropItems() const return GetClass()->DropItems; } -fixed_t AActor::GetGravity() const +double AActor::GetGravity() const { if (flags & MF_NOGRAVITY) return 0; - return fixed_t(level.gravity * Sector->gravity * FIXED2DBL(gravity) * 81.92); + return level.gravity * Sector->gravity * Gravity * 0.00125; } // killough 11/98: @@ -6705,6 +6446,17 @@ void AActor::ClearCounters() } +int AActor::ApplyDamageFactor(FName damagetype, int damage) const +{ + damage = int(damage * DamageFactor); + if (damage > 0) + { + damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, damagetype, GetClass()->DamageFactors); + } + return damage; +} + + //---------------------------------------------------------------------------- // // DropItem handling @@ -6756,13 +6508,13 @@ void PrintMiscActorInfo(AActor *query) for (flagi = 0; flagi <= 31; flagi++) if (query->flags7 & ActorFlags7::FromInt(1<BounceFlags.GetValue(), FIXED2DBL(query->bouncefactor), - FIXED2DBL(query->wallbouncefactor)); + query->BounceFlags.GetValue(), query->bouncefactor, + query->wallbouncefactor); /*for (flagi = 0; flagi < 31; flagi++) if (query->BounceFlags & 1<alpha), query->renderflags.GetValue()); + query->Alpha, query->renderflags.GetValue()); /*for (flagi = 0; flagi < 31; flagi++) if (query->renderflags & 1<args[4], query->special1, query->special2); Printf("\nTID: %d", query->tid); Printf("\nCoord= x: %f, y: %f, z:%f, floor:%f, ceiling:%f.", - FIXED2DBL(query->X()), FIXED2DBL(query->Y()), FIXED2DBL(query->Z()), - FIXED2DBL(query->floorz), FIXED2DBL(query->ceilingz)); + query->X(), query->Y(), query->Z(), + query->floorz, query->ceilingz); Printf("\nSpeed= %f, velocity= x:%f, y:%f, z:%f, combined:%f.\n", - FIXED2DBL(query->Speed), FIXED2DBL(query->vel.x), FIXED2DBL(query->vel.y), FIXED2DBL(query->vel.z), - sqrt(pow(FIXED2DBL(query->vel.x), 2) + pow(FIXED2DBL(query->vel.y), 2) + pow(FIXED2DBL(query->vel.z), 2))); + query->Speed, query->Vel.X, query->Vel.Y, query->Vel.Z, query->Vel.Length()); } } diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index b28d517e5..da939abb0 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -89,10 +89,10 @@ void DPillar::Serialize (FArchive &arc) void DPillar::Tick () { int r, s; - fixed_t oldfloor, oldceiling; + double oldfloor, oldceiling; - oldfloor = m_Sector->floorplane.d; - oldceiling = m_Sector->ceilingplane.d; + oldfloor = m_Sector->floorplane.fD(); + oldceiling = m_Sector->ceilingplane.fD(); if (m_Type == pillarBuild) { @@ -123,11 +123,11 @@ void DPillar::Tick () } } -DPillar::DPillar (sector_t *sector, EPillar type, fixed_t speed, - fixed_t floordist, fixed_t ceilingdist, int crush, bool hexencrush) +DPillar::DPillar (sector_t *sector, EPillar type, double speed, + double floordist, double ceilingdist, int crush, bool hexencrush) : DMover (sector) { - fixed_t newheight; + double newheight; vertex_t *spot; sector->floordata = sector->ceilingdata = this; @@ -190,12 +190,12 @@ DPillar::DPillar (sector_t *sector, EPillar type, fixed_t speed, if (floordist > ceilingdist) { m_FloorSpeed = speed; - m_CeilingSpeed = Scale (speed, ceilingdist, floordist); + m_CeilingSpeed = speed * ceilingdist / floordist; } else { m_CeilingSpeed = speed; - m_FloorSpeed = Scale (speed, floordist, ceilingdist); + m_FloorSpeed = speed * floordist / ceilingdist; } if (!(m_Sector->Flags & SECF_SILENTMOVE)) @@ -216,7 +216,7 @@ DPillar::DPillar (sector_t *sector, EPillar type, fixed_t speed, } bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag, - fixed_t speed, fixed_t height, fixed_t height2, int crush, bool hexencrush) + double speed, double height, double height2, int crush, bool hexencrush) { int secnum; sector_t *sec; @@ -231,7 +231,7 @@ bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag, if (sec->PlaneMoving(sector_t::floor) || sec->PlaneMoving(sector_t::ceiling)) continue; - fixed_t flor, ceil; + double flor, ceil; flor = sec->CenterFloor (); ceil = sec->CenterCeiling (); diff --git a/src/p_plats.cpp b/src/p_plats.cpp index cd474ee90..7d2754d2c 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -198,7 +198,7 @@ void DPlat::Tick () case waiting: if (m_Count > 0 && !--m_Count) { - if (m_Sector->floorplane.d == m_Low) + if (m_Sector->floorplane.fD() == m_Low) m_Status = up; else m_Status = down; @@ -225,15 +225,15 @@ DPlat::DPlat (sector_t *sector) // [RH] Changed amount to height and added delay, // lip, change, tag, and speed parameters. // -bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, - int speed, int delay, int lip, int change) +bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, double height, + double speed, int delay, int lip, int change) { DPlat *plat; int secnum; sector_t *sec; bool rtn = false; bool manual = false; - fixed_t newheight = 0; + double newheight = 0; vertex_t *spot; if (tag != 0) @@ -277,7 +277,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, //jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then //going down forever -- default lower to plat height when triggered - plat->m_Low = sec->floorplane.d; + plat->m_Low = sec->floorplane.fD(); if (change) { @@ -292,7 +292,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, case DPlat::platRaiseAndStayLockout: newheight = sec->FindNextHighestFloor (&spot); plat->m_High = sec->floorplane.PointToDist (spot, newheight); - plat->m_Low = sec->floorplane.d; + plat->m_Low = sec->floorplane.fD(); plat->m_Status = DPlat::up; plat->PlayPlatSound ("Floor"); sec->ClearSpecial(); @@ -300,30 +300,30 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, case DPlat::platUpByValue: case DPlat::platUpByValueStay: - newheight = sec->floorplane.ZatPoint (0, 0) + height; - plat->m_High = sec->floorplane.PointToDist (0, 0, newheight); - plat->m_Low = sec->floorplane.d; + newheight = sec->floorplane.ZatPoint (sec->centerspot) + height; + plat->m_High = sec->floorplane.PointToDist (sec->centerspot, newheight); + plat->m_Low = sec->floorplane.fD(); plat->m_Status = DPlat::up; plat->PlayPlatSound ("Floor"); break; case DPlat::platDownByValue: - newheight = sec->floorplane.ZatPoint (0, 0) - height; - plat->m_Low = sec->floorplane.PointToDist (0, 0, newheight); - plat->m_High = sec->floorplane.d; + newheight = sec->floorplane.ZatPoint (sec->centerspot) - height; + plat->m_Low = sec->floorplane.PointToDist (sec->centerspot, newheight); + plat->m_High = sec->floorplane.fD(); plat->m_Status = DPlat::down; plat->PlayPlatSound ("Floor"); break; case DPlat::platDownWaitUpStay: case DPlat::platDownWaitUpStayStone: - newheight = sec->FindLowestFloorSurrounding (&spot) + lip*FRACUNIT; + newheight = sec->FindLowestFloorSurrounding (&spot) + lip; plat->m_Low = sec->floorplane.PointToDist (spot, newheight); - if (plat->m_Low < sec->floorplane.d) - plat->m_Low = sec->floorplane.d; + if (plat->m_Low < sec->floorplane.fD()) + plat->m_Low = sec->floorplane.fD(); - plat->m_High = sec->floorplane.d; + plat->m_High = sec->floorplane.fD(); plat->m_Status = DPlat::down; plat->PlayPlatSound (type == DPlat::platDownWaitUpStay ? "Platform" : "Floor"); break; @@ -338,27 +338,27 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, newheight = sec->FindHighestFloorSurrounding (&spot); } plat->m_High = sec->floorplane.PointToDist (spot, newheight); - plat->m_Low = sec->floorplane.d; + plat->m_Low = sec->floorplane.fD(); - if (plat->m_High > sec->floorplane.d) - plat->m_High = sec->floorplane.d; + if (plat->m_High > sec->floorplane.fD()) + plat->m_High = sec->floorplane.fD(); plat->m_Status = DPlat::up; plat->PlayPlatSound ("Platform"); break; case DPlat::platPerpetualRaise: - newheight = sec->FindLowestFloorSurrounding (&spot) + lip*FRACUNIT; + newheight = sec->FindLowestFloorSurrounding (&spot) + lip; plat->m_Low = sec->floorplane.PointToDist (spot, newheight); - if (plat->m_Low < sec->floorplane.d) - plat->m_Low = sec->floorplane.d; + if (plat->m_Low < sec->floorplane.fD()) + plat->m_Low = sec->floorplane.fD(); newheight = sec->FindHighestFloorSurrounding (&spot); plat->m_High = sec->floorplane.PointToDist (spot, newheight); - if (plat->m_High > sec->floorplane.d) - plat->m_High = sec->floorplane.d; + if (plat->m_High > sec->floorplane.fD()) + plat->m_High = sec->floorplane.fD(); plat->m_Status = pr_doplat() & 1 ? DPlat::up : DPlat::down; @@ -371,26 +371,26 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, // set up toggling between ceiling, floor inclusive newheight = sec->FindLowestCeilingPoint (&spot); plat->m_Low = sec->floorplane.PointToDist (spot, newheight); - plat->m_High = sec->floorplane.d; + plat->m_High = sec->floorplane.fD(); plat->m_Status = DPlat::down; SN_StartSequence (sec, CHAN_FLOOR, "Silence", 0); break; case DPlat::platDownToNearestFloor: - newheight = sec->FindNextLowestFloor (&spot) + lip*FRACUNIT; + newheight = sec->FindNextLowestFloor (&spot) + lip; plat->m_Low = sec->floorplane.PointToDist (spot, newheight); plat->m_Status = DPlat::down; - plat->m_High = sec->floorplane.d; + plat->m_High = sec->floorplane.fD(); plat->PlayPlatSound ("Platform"); break; case DPlat::platDownToLowestCeiling: newheight = sec->FindLowestCeilingSurrounding (&spot); plat->m_Low = sec->floorplane.PointToDist (spot, newheight); - plat->m_High = sec->floorplane.d; + plat->m_High = sec->floorplane.fD(); - if (plat->m_Low < sec->floorplane.d) - plat->m_Low = sec->floorplane.d; + if (plat->m_Low < sec->floorplane.fD()) + plat->m_Low = sec->floorplane.fD(); plat->m_Status = DPlat::down; plat->PlayPlatSound ("Platform"); diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 60eae8731..ed4c97409 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -33,8 +33,8 @@ // MACROS ------------------------------------------------------------------ -#define LOWERSPEED FRACUNIT*6 -#define RAISESPEED FRACUNIT*6 +#define LOWERSPEED 6. +#define RAISESPEED 6. // TYPES ------------------------------------------------------------------- @@ -169,11 +169,11 @@ void P_SetPsprite (player_t *player, int position, FState *state, bool nofunctio if (state->GetMisc1()) { // Set coordinates. - psp->sx = state->GetMisc1()<sx = state->GetMisc1(); } if (state->GetMisc2()) { - psp->sy = state->GetMisc2()<sy = state->GetMisc2(); } if (!nofunction && player->mo != NULL) @@ -367,12 +367,12 @@ void P_DropWeapon (player_t *player) // //============================================================================ -void P_BobWeapon (player_t *player, pspdef_t *psp, fixed_t *x, fixed_t *y) +void P_BobWeapon (player_t *player, pspdef_t *psp, float *x, float *y) { - static fixed_t curbob; + static float curbob; AWeapon *weapon; - fixed_t bobtarget; + float bobtarget; weapon = player->ReadyWeapon; @@ -384,26 +384,26 @@ void P_BobWeapon (player_t *player, pspdef_t *psp, fixed_t *x, fixed_t *y) // [XA] Get the current weapon's bob properties. int bobstyle = weapon->BobStyle; - int bobspeed = (weapon->BobSpeed * 128) >> 16; - fixed_t rangex = weapon->BobRangeX; - fixed_t rangey = weapon->BobRangeY; + float BobSpeed = (weapon->BobSpeed * 128); + float Rangex = weapon->BobRangeX; + float Rangey = weapon->BobRangeY; // Bob the weapon based on movement speed. - int angle = (bobspeed*35/TICRATE*level.time)&FINEMASK; + FAngle angle = (BobSpeed * 35 / TICRATE*level.time) * (360.f / 8192.f); // [RH] Smooth transitions between bobbing and not-bobbing frames. // This also fixes the bug where you can "stick" a weapon off-center by // shooting it when it's at the peak of its swing. - bobtarget = (player->WeaponState & WF_WEAPONBOBBING) ? player->bob : 0; + bobtarget = float((player->WeaponState & WF_WEAPONBOBBING) ? player->bob : 0.); if (curbob != bobtarget) { - if (abs (bobtarget - curbob) <= 1*FRACUNIT) + if (fabsf (bobtarget - curbob) <= 1) { curbob = bobtarget; } else { - fixed_t zoom = MAX (1*FRACUNIT, abs (curbob - bobtarget) / 40); + float zoom = MAX (1.f, fabsf (curbob - bobtarget) / 40); if (curbob > bobtarget) { curbob -= zoom; @@ -417,38 +417,38 @@ void P_BobWeapon (player_t *player, pspdef_t *psp, fixed_t *x, fixed_t *y) if (curbob != 0) { - fixed_t bobx = FixedMul(player->bob, rangex); - fixed_t boby = FixedMul(player->bob, rangey); + float bobx = float(player->bob * Rangex); + float boby = float(player->bob * Rangey); switch (bobstyle) { case AWeapon::BobNormal: - *x = FixedMul(bobx, finecosine[angle]); - *y = FixedMul(boby, finesine[angle & (FINEANGLES/2-1)]); + *x = bobx * angle.Cos(); + *y = boby * fabsf(angle.Sin()); break; case AWeapon::BobInverse: - *x = FixedMul(bobx, finecosine[angle]); - *y = boby - FixedMul(boby, finesine[angle & (FINEANGLES/2-1)]); + *x = bobx*angle.Cos(); + *y = boby * (1.f - fabsf(angle.Sin())); break; case AWeapon::BobAlpha: - *x = FixedMul(bobx, finesine[angle]); - *y = FixedMul(boby, finesine[angle & (FINEANGLES/2-1)]); + *x = bobx * angle.Sin(); + *y = boby * fabsf(angle.Sin()); break; case AWeapon::BobInverseAlpha: - *x = FixedMul(bobx, finesine[angle]); - *y = boby - FixedMul(boby, finesine[angle & (FINEANGLES/2-1)]); + *x = bobx * angle.Sin(); + *y = boby * (1.f - fabsf(angle.Sin())); break; case AWeapon::BobSmooth: - *x = FixedMul(bobx, finecosine[angle]); - *y = (boby - FixedMul(boby, finecosine[angle*2 & (FINEANGLES-1)])) / 2; + *x = bobx*angle.Cos(); + *y = 0.5f * (boby * (1.f - fabsf((angle * 2).Cos()))); break; case AWeapon::BobInverseSmooth: - *x = FixedMul(bobx, finecosine[angle]); - *y = (FixedMul(boby, finecosine[angle*2 & (FINEANGLES-1)]) + boby) / 2; + *x = bobx*angle.Cos(); + *y = 0.5f * (boby * (1.f + fabsf((angle * 2).Cos()))); } } else @@ -919,12 +919,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) // the height of the intended target // -angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimflags) +DAngle P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimflags) { - static const int angdiff[3] = { -(1<<26), 1<<26, 0 }; + static const double angdiff[3] = { -5.625f, 5.625f, 0 }; int i; - angle_t an; - angle_t pitch; + DAngle an; + DAngle pitch; FTranslatedLineTarget scratch; if (pLineTarget == NULL) pLineTarget = &scratch; @@ -932,12 +932,12 @@ angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimfl i = 2; do { - an = mo->angle + angdiff[i]; - pitch = P_AimLineAttack (mo, an, 16*64*FRACUNIT, pLineTarget, 0, aimflags); + an = mo->Angles.Yaw + angdiff[i]; + pitch = P_AimLineAttack (mo, an, 16.*64, pLineTarget, 0., aimflags); if (mo->player != NULL && level.IsFreelookAllowed() && - mo->player->userinfo.GetAimDist() <= ANGLE_1/2) + mo->player->userinfo.GetAimDist() <= 0.5) { break; } @@ -950,17 +950,17 @@ angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimfl // // P_GunShot // -void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, angle_t pitch) +void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, DAngle pitch) { - angle_t angle; + DAngle angle; int damage; damage = 5*(pr_gunshot()%3+1); - angle = mo->angle; + angle = mo->Angles.Yaw; if (!accurate) { - angle += pr_gunshot.Random2 () << 18; + angle += pr_gunshot.Random2 () * (5.625 / 256); } P_LineAttack (mo, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, pufftype); diff --git a/src/p_pspr.h b/src/p_pspr.h index fda8cbf15..7045f96a5 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -28,12 +28,12 @@ #include "tables.h" #include "thingdef/thingdef.h" -#define WEAPONBOTTOM 128*FRACUNIT +#define WEAPONBOTTOM 128. // [RH] +0x6000 helps it meet the screen bottom // at higher resolutions while still being in // the right spot at 320x200. -#define WEAPONTOP (32*FRACUNIT+0x6000) +#define WEAPONTOP (32+6./16) // @@ -66,8 +66,8 @@ struct pspdef_t { FState* state; // a NULL state means not active int tics; - fixed_t sx; - fixed_t sy; + double sx; + double sy; int sprite; int frame; bool processPending; // true: waiting for periodic processing on this tick @@ -87,9 +87,10 @@ void P_CalcSwing (player_t *player); void P_BringUpWeapon (player_t *player); void P_FireWeapon (player_t *player); void P_DropWeapon (player_t *player); -void P_BobWeapon (player_t *player, pspdef_t *psp, fixed_t *x, fixed_t *y); -angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget = NULL, int aimflags = 0); -void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, angle_t pitch); +void P_BobWeapon (player_t *player, pspdef_t *psp, float *x, float *y); +DAngle P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget = NULL, int aimflags = 0); + +void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, DAngle pitch); void DoReadyWeapon(AActor *self); void DoReadyWeaponToBob(AActor *self); diff --git a/src/p_pusher.cpp b/src/p_pusher.cpp index 722e1dc0c..4fb3b8f1f 100644 --- a/src/p_pusher.cpp +++ b/src/p_pusher.cpp @@ -56,9 +56,8 @@ public: int CheckForSectorMatch (EPusher type, int tag); void ChangeValues (int magnitude, int angle) { - angle_t ang = ((angle_t)(angle<<24)) >> ANGLETOFINESHIFT; - m_Xmag = (magnitude * finecosine[ang]) >> FRACBITS; - m_Ymag = (magnitude * finesine[ang]) >> FRACBITS; + DAngle ang = angle * (360. / 256.); + m_PushVec = ang.ToVector(magnitude); m_Magnitude = magnitude; } @@ -67,12 +66,9 @@ public: protected: EPusher m_Type; TObjPtr m_Source;// Point source if point pusher - int m_Xmag; // X Strength - int m_Ymag; // Y Strength - int m_Magnitude; // Vector strength for point pusher - int m_Radius; // Effective radius for point pusher - int m_X; // X of point source if point pusher - int m_Y; // Y of point source if point pusher + DVector2 m_PushVec; + double m_Magnitude; // Vector strength for point pusher + double m_Radius; // Effective radius for point pusher int m_Affectee; // Number of affected sector friend bool PIT_PushThing (AActor *thing); @@ -100,12 +96,9 @@ void DPusher::Serialize (FArchive &arc) Super::Serialize (arc); arc << m_Type << m_Source - << m_Xmag - << m_Ymag + << m_PushVec << m_Magnitude << m_Radius - << m_X - << m_Y << m_Affectee; } @@ -155,7 +148,7 @@ void DPusher::Serialize (FArchive &arc) // types 1 & 2 is the sector containing the MT_PUSH/MT_PULL Thing. -#define PUSH_FACTOR 7 +#define PUSH_FACTOR 128 ///////////////////////////// // @@ -168,9 +161,8 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle, m_Type = type; if (l) { - m_Xmag = l->dx>>FRACBITS; - m_Ymag = l->dy>>FRACBITS; - m_Magnitude = P_AproxDistance (m_Xmag, m_Ymag); + m_PushVec = l->Delta(); + m_Magnitude = m_PushVec.Length(); } else { // [RH] Allow setting magnitude and angle with parameters @@ -178,9 +170,7 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle, } if (source) // point source exist? { - m_Radius = (m_Magnitude) << (FRACBITS+1); // where force goes to zero - m_X = m_Source->X(); - m_Y = m_Source->Y(); + m_Radius = m_Magnitude * 2; // where force goes to zero } m_Affectee = affectee; } @@ -204,8 +194,7 @@ void DPusher::Tick () sector_t *sec; AActor *thing; msecnode_t *node; - int xspeed,yspeed; - int ht; + double ht; if (!var_pushers) return; @@ -243,7 +232,7 @@ void DPusher::Tick () // point pusher. Crosses sectors, so use blockmap. FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); // no sector portals because this thing is utterly z-unaware. - FMultiBlockThingsIterator it(check, m_X, m_Y, 0, 0, m_Radius, false, m_Source->Sector); + FMultiBlockThingsIterator it(check, m_Source, m_Radius); FMultiBlockThingsIterator::CheckResult cres; @@ -262,22 +251,18 @@ void DPusher::Tick () if ((pusharound) ) { - int sx = m_X; - int sy = m_Y; - int dist = thing->AproxDistance (sx, sy); - int speed = (m_Magnitude - ((dist>>FRACBITS)>>1))<<(FRACBITS-PUSH_FACTOR-1); + DVector2 pos = m_Source->Vec2To(thing); + double dist = pos.Length(); + double speed = (m_Magnitude - (dist/2)) / (PUSH_FACTOR * 2); // If speed <= 0, you're outside the effective radius. You also have // to be able to see the push/pull source point. if ((speed > 0) && (P_CheckSight (thing, m_Source, SF_IGNOREVISIBILITY))) { - angle_t pushangle = thing->AngleTo(sx, sy); - if (m_Source->GetClass()->TypeName == NAME_PointPusher) - pushangle += ANG180; // away - pushangle >>= ANGLETOFINESHIFT; - thing->vel.x += FixedMul (speed, finecosine[pushangle]); - thing->vel.y += FixedMul (speed, finesine[pushangle]); + DAngle pushangle = pos.Angle(); + if (m_Source->GetClass()->TypeName == NAME_PointPuller) pushangle += 180; + thing->Thrust(pushangle, speed); } } } @@ -294,20 +279,19 @@ void DPusher::Tick () continue; sector_t *hsec = sec->GetHeightSec(); - fixedvec3 pos = thing->PosRelative(sec); + DVector3 pos = thing->PosRelative(sec); + DVector2 pushvel; if (m_Type == p_wind) { if (hsec == NULL) { // NOT special water sector if (thing->Z() > thing->floorz) // above ground { - xspeed = m_Xmag; // full force - yspeed = m_Ymag; + pushvel = m_PushVec; // full force } else // on ground { - xspeed = (m_Xmag)>>1; // half force - yspeed = (m_Ymag)>>1; + pushvel = m_PushVec / 2; // half force } } else // special water sector @@ -315,17 +299,15 @@ void DPusher::Tick () ht = hsec->floorplane.ZatPoint(pos); if (thing->Z() > ht) // above ground { - xspeed = m_Xmag; // full force - yspeed = m_Ymag; + pushvel = m_PushVec; // full force } else if (thing->player->viewz < ht) // underwater { - xspeed = yspeed = 0; // no force + pushvel.Zero(); // no force } else // wading in water { - xspeed = (m_Xmag)>>1; // half force - yspeed = (m_Ymag)>>1; + pushvel = m_PushVec / 2; // full force } } } @@ -343,16 +325,14 @@ void DPusher::Tick () } if (thing->Z() > floor->ZatPoint(pos)) { // above ground - xspeed = yspeed = 0; // no force + pushvel.Zero(); // no force } else { // on ground/underwater - xspeed = m_Xmag; // full force - yspeed = m_Ymag; + pushvel = m_PushVec; // full force } } - thing->vel.x += xspeed<<(FRACBITS-PUSH_FACTOR); - thing->vel.y += yspeed<<(FRACBITS-PUSH_FACTOR); + thing->Vel += pushvel / PUSH_FACTOR; } } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index f6e023392..38122b977 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -341,22 +341,8 @@ void P_SerializeWorld (FArchive &arc) { arc << sec->floorplane << sec->ceilingplane; - if (SaveVersion < 3223) - { - BYTE bytelight; - arc << bytelight; - sec->lightlevel = bytelight; - } - else - { - arc << sec->lightlevel; - } + arc << sec->lightlevel; arc << sec->special; - if (SaveVersion < 4523) - { - short tag; - arc << tag; - } arc << sec->soundtraversed << sec->seqType << sec->friction @@ -372,49 +358,12 @@ void P_SerializeWorld (FArchive &arc) << sec->heightsec << sec->bottommap << sec->midmap << sec->topmap << sec->gravity; - if (SaveVersion >= 4530) - { - P_SerializeTerrain(arc, sec->terrainnum[0]); - P_SerializeTerrain(arc, sec->terrainnum[1]); - } - if (SaveVersion >= 4529) - { - arc << sec->damageamount; - } - else - { - short dmg; - arc << dmg; - sec->damageamount = dmg; - } - if (SaveVersion >= 4528) - { - arc << sec->damageinterval - << sec->leakydamage - << sec->damagetype; - } - else - { - short damagemod; - arc << damagemod; - sec->damagetype = MODtoDamageType(damagemod); - if (sec->damageamount < 20) - { - sec->leakydamage = 0; - sec->damageinterval = 32; - } - else if (sec->damageamount < 50) - { - sec->leakydamage = 5; - sec->damageinterval = 32; - } - else - { - sec->leakydamage = 256; - sec->damageinterval = 1; - } - } - + P_SerializeTerrain(arc, sec->terrainnum[0]); + P_SerializeTerrain(arc, sec->terrainnum[1]); + arc << sec->damageamount; + arc << sec->damageinterval + << sec->leakydamage + << sec->damagetype; arc << sec->SoundTarget << sec->SecActTarget << sec->sky @@ -422,13 +371,6 @@ void P_SerializeWorld (FArchive &arc) << sec->Flags << sec->SkyBoxes[sector_t::floor] << sec->SkyBoxes[sector_t::ceiling] << sec->ZoneNumber; - if (SaveVersion < 4529) - { - short secretsector; - arc << secretsector; - if (secretsector) sec->Flags |= SECF_WASSECRET; - P_InitSectorSpecial(sec, sec->special, true); - } arc << sec->interpolations[0] << sec->interpolations[1] << sec->interpolations[2] @@ -461,11 +403,6 @@ void P_SerializeWorld (FArchive &arc) << li->special << li->Alpha; - if (SaveVersion < 4523) - { - int id; - arc << id; - } if (P_IsACSSpecial(li->special)) { P_SerializeACSScriptNumber(arc, li->args[0], false); @@ -476,12 +413,7 @@ void P_SerializeWorld (FArchive &arc) } arc << li->args[1] << li->args[2] << li->args[3] << li->args[4]; - if (SaveVersion >= 4532) - { - arc << li->portalindex; - } - else li->portalindex = UINT_MAX; - + arc << li->portalindex; for (j = 0; j < 2; j++) { if (li->sidedef[j] == NULL) @@ -517,14 +449,7 @@ void P_SerializeWorld (FArchive &arc) arc << zn->Environment; } - if (SaveVersion >= 4532) - { - arc << linePortals; - } - else - { - linePortals.Clear(); - } + arc << linePortals; P_CollectLinkedPortals(); } @@ -614,15 +539,14 @@ void P_SerializePolyobjs (FArchive &arc) arc << seg << po_NumPolyobjs; for(i = 0, po = polyobjs; i < po_NumPolyobjs; i++, po++) { - arc << po->tag << po->angle << po->StartSpot.x << - po->StartSpot.y << po->interpolation; + arc << po->tag << po->Angle << po->StartSpot.pos << po->interpolation; } } else { int data; - angle_t angle; - fixed_t deltaX, deltaY; + DAngle angle; + DVector2 delta; arc << data; if (data != ASEG_POLYOBJS) @@ -640,12 +564,10 @@ void P_SerializePolyobjs (FArchive &arc) { I_Error ("UnarchivePolyobjs: Invalid polyobj tag"); } - arc << angle; + arc << angle << delta << po->interpolation; po->RotatePolyobj (angle, true); - arc << deltaX << deltaY << po->interpolation; - deltaX -= po->StartSpot.x; - deltaY -= po->StartSpot.y; - po->MovePolyobj (deltaX, deltaY, true); + delta -= po->StartSpot.pos; + po->MovePolyobj (delta, true); } } } diff --git a/src/p_scroll.cpp b/src/p_scroll.cpp index 96889b624..01fbba3c5 100644 --- a/src/p_scroll.cpp +++ b/src/p_scroll.cpp @@ -42,8 +42,8 @@ class DScroller : public DThinker HAS_OBJECT_POINTERS public: - DScroller (EScroll type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all); - DScroller (fixed_t dx, fixed_t dy, const line_t *l, int control, int accel, EScrollPos scrollpos = EScrollPos::scw_all); + DScroller (EScroll type, double dx, double dy, int control, int affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all); + DScroller (double dx, double dy, const line_t *l, int control, int accel, EScrollPos scrollpos = EScrollPos::scw_all); void Destroy(); void Serialize (FArchive &arc); @@ -51,18 +51,18 @@ public: bool AffectsWall (int wallnum) const { return m_Type == EScroll::sc_side && m_Affectee == wallnum; } int GetWallNum () const { return m_Type == EScroll::sc_side ? m_Affectee : -1; } - void SetRate (fixed_t dx, fixed_t dy) { m_dx = dx; m_dy = dy; } + void SetRate (double dx, double dy) { m_dx = dx; m_dy = dy; } bool IsType (EScroll type) const { return type == m_Type; } int GetAffectee () const { return m_Affectee; } EScrollPos GetScrollParts() const { return m_Parts; } protected: EScroll m_Type; // Type of scroll effect - fixed_t m_dx, m_dy; // (dx,dy) scroll speeds + double m_dx, m_dy; // (dx,dy) scroll speeds int m_Affectee; // Number of affected sidedef, sector, tag, or whatever int m_Control; // Control sector (-1 if none) used to control scrolling - fixed_t m_LastHeight; // Last known height of control sector - fixed_t m_vdx, m_vdy; // Accumulated velocity if accelerative + double m_LastHeight; // Last known height of control sector + double m_vdx, m_vdy; // Accumulated velocity if accelerative int m_Accel; // Whether it's accelerative EScrollPos m_Parts; // Which parts of a sidedef are being scrolled? TObjPtr m_Interpolations[3]; @@ -137,9 +137,9 @@ void DScroller::Serialize (FArchive &arc) // //----------------------------------------------------------------------------- -static void RotationComp(const sector_t *sec, int which, fixed_t dx, fixed_t dy, fixed_t &tdx, fixed_t &tdy) +static void RotationComp(const sector_t *sec, int which, double dx, double dy, double &tdx, double &tdy) { - angle_t an = sec->GetAngle(which); + DAngle an = sec->GetAngleF(which); if (an == 0) { tdx = dx; @@ -147,11 +147,10 @@ static void RotationComp(const sector_t *sec, int which, fixed_t dx, fixed_t dy, } else { - an = an >> ANGLETOFINESHIFT; - fixed_t ca = -finecosine[an]; - fixed_t sa = -finesine[an]; - tdx = DMulScale16(dx, ca, -dy, sa); - tdy = DMulScale16(dy, ca, dx, sa); + double ca = an.Cos(); + double sa = an.Sin(); + tdx = dx*ca - dy*sa; + tdy = dy*ca + dx*sa; } } @@ -180,16 +179,16 @@ static void RotationComp(const sector_t *sec, int which, fixed_t dx, fixed_t dy, void DScroller::Tick () { - fixed_t dx = m_dx, dy = m_dy, tdx, tdy; + double dx = m_dx, dy = m_dy, tdx, tdy; if (m_Control != -1) { // compute scroll amounts based on a sector's height changes - fixed_t height = sectors[m_Control].CenterFloor () + + double height = sectors[m_Control].CenterFloor () + sectors[m_Control].CenterCeiling (); - fixed_t delta = height - m_LastHeight; + double delta = height - m_LastHeight; m_LastHeight = height; - dx = FixedMul(dx, delta); - dy = FixedMul(dy, delta); + dx *= delta; + dy *= delta; } // killough 3/14/98: Add acceleration @@ -199,7 +198,7 @@ void DScroller::Tick () m_vdy = dy += m_vdy; } - if (!(dx | dy)) // no-op if both (x,y) offsets are 0 + if (dx == 0 && dy == 0) return; switch (m_Type) @@ -237,8 +236,8 @@ void DScroller::Tick () // [RH] Don't actually carry anything here. That happens later. case EScroll::sc_carry: - level.Scrolls[m_Affectee].ScrollX += dx; - level.Scrolls[m_Affectee].ScrollY += dy; + level.Scrolls[m_Affectee].Scroll.X += dx; + level.Scrolls[m_Affectee].Scroll.Y += dy; break; case EScroll::sc_carry_ceiling: // to be added later @@ -266,7 +265,7 @@ void DScroller::Tick () // //----------------------------------------------------------------------------- -DScroller::DScroller (EScroll type, fixed_t dx, fixed_t dy, +DScroller::DScroller (EScroll type, double dx, double dy, int control, int affectee, int accel, EScrollPos scrollpos) : DThinker (STAT_SCROLLER) { @@ -342,17 +341,16 @@ void DScroller::Destroy () // //----------------------------------------------------------------------------- -DScroller::DScroller (fixed_t dx, fixed_t dy, const line_t *l, +DScroller::DScroller (double dx, double dy, const line_t *l, int control, int accel, EScrollPos scrollpos) : DThinker (STAT_SCROLLER) { - fixed_t x = abs(l->dx), y = abs(l->dy), d; - if (y > x) - d = x, x = y, y = d; - d = FixedDiv (x, finesine[(tantoangle[FixedDiv(y,x) >> DBITS] + ANG90) - >> ANGLETOFINESHIFT]); - x = -FixedDiv (FixedMul(dy, l->dy) + FixedMul(dx, l->dx), d); - y = -FixedDiv (FixedMul(dx, l->dy) - FixedMul(dy, l->dx), d); + double x = fabs(l->Delta().X), y = fabs(l->Delta().Y), d; + if (y > x) d = x, x = y, y = d; + + d = x / g_sin(g_atan2(y, x) + M_PI / 2); + x = (-dy * l->Delta().Y + dx * l->Delta().X) / d; + y = (-dx * l->Delta().Y - dy * l->Delta().Y) / d; m_Type = EScroll::sc_side; m_dx = x; @@ -412,8 +410,8 @@ void P_SpawnScrollers(void) for (i = 0; i < numlines; i++, l++) { - fixed_t dx; // direction and speed of scrolling - fixed_t dy; + double dx; // direction and speed of scrolling + double dy; int control = -1, accel = 0; // no control sector or acceleration int special = l->special; @@ -463,14 +461,14 @@ void P_SpawnScrollers(void) { // The line housing the special controls the // direction and speed of scrolling. - dx = l->dx >> SCROLL_SHIFT; - dy = l->dy >> SCROLL_SHIFT; + dx = l->Delta().X / 32.; + dy = l->Delta().Y / 32.; } else { // The speed and direction are parameters to the special. - dx = (l->args[3] - 128) * (FRACUNIT / 32); - dy = (l->args[4] - 128) * (FRACUNIT / 32); + dx = (l->args[3] - 128) / 32.; + dy = (l->args[4] - 128) / 32.; } } @@ -558,36 +556,36 @@ void P_SpawnScrollers(void) case Scroll_Texture_Left: l->special = special; // Restore the special, for compat_useblocking's benefit. s = int(lines[i].sidedef[0] - sides); - new DScroller (EScroll::sc_side, l->args[0] * (FRACUNIT/64), 0, + new DScroller (EScroll::sc_side, l->args[0] / 64., 0, -1, s, accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Right: l->special = special; s = int(lines[i].sidedef[0] - sides); - new DScroller (EScroll::sc_side, l->args[0] * (-FRACUNIT/64), 0, + new DScroller (EScroll::sc_side, -l->args[0] / 64., 0, -1, s, accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Up: l->special = special; s = int(lines[i].sidedef[0] - sides); - new DScroller (EScroll::sc_side, 0, l->args[0] * (FRACUNIT/64), + new DScroller (EScroll::sc_side, 0, l->args[0] / 64., -1, s, accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Down: l->special = special; s = int(lines[i].sidedef[0] - sides); - new DScroller (EScroll::sc_side, 0, l->args[0] * (-FRACUNIT/64), + new DScroller (EScroll::sc_side, 0, -l->args[0] / 64., -1, s, accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Both: s = int(lines[i].sidedef[0] - sides); if (l->args[0] == 0) { - dx = (l->args[1] - l->args[2]) * (FRACUNIT/64); - dy = (l->args[4] - l->args[3]) * (FRACUNIT/64); + dx = (l->args[1] - l->args[2]) / 64.; + dy = (l->args[4] - l->args[3]) / 64.; new DScroller (EScroll::sc_side, dx, dy, -1, s, accel); } break; @@ -606,12 +604,12 @@ void P_SpawnScrollers(void) // //----------------------------------------------------------------------------- -void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, EScrollPos Where) +void SetWallScroller (int id, int sidechoice, double dx, double dy, EScrollPos Where) { Where = Where & scw_all; if (Where == 0) return; - if ((dx | dy) == 0) + if (dx == 0 && dy == 0) { // Special case: Remove the scroller, because the deltas are both 0. TThinkerIterator iterator (STAT_SCROLLER); @@ -676,7 +674,7 @@ void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, EScrollPos } } -void SetScroller (int tag, EScroll type, fixed_t dx, fixed_t dy) +void SetScroller (int tag, EScroll type, double dx, double dy) { TThinkerIterator iterator (STAT_SCROLLER); DScroller *scroller; @@ -700,7 +698,7 @@ void SetScroller (int tag, EScroll type, fixed_t dx, fixed_t dy) } } - if (i > 0 || (dx|dy) == 0) + if (i > 0 || (dx == 0 && dy == 0)) { return; } @@ -713,7 +711,7 @@ void SetScroller (int tag, EScroll type, fixed_t dx, fixed_t dy) } } -void P_CreateScroller(EScroll type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, EScrollPos scrollpos) +void P_CreateScroller(EScroll type, double dx, double dy, int control, int affectee, int accel, EScrollPos scrollpos) { new DScroller(type, dx, dy, control, affectee, accel, scrollpos); } diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 25cd0ead8..357b60872 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -63,19 +63,19 @@ sector_t *sector_t::NextSpecialSector (int type, sector_t *nogood) const // P_FindLowestFloorSurrounding() // FIND LOWEST FLOOR HEIGHT IN SURROUNDING SECTORS // -fixed_t sector_t::FindLowestFloorSurrounding (vertex_t **v) const +double sector_t::FindLowestFloorSurrounding (vertex_t **v) const { int i; sector_t *other; line_t *check; - fixed_t floor; - fixed_t ofloor; + double floor; + double ofloor; vertex_t *spot; - if (linecount == 0) return GetPlaneTexZ(sector_t::floor); + if (linecount == 0) return GetPlaneTexZF(sector_t::floor); spot = lines[0]->v1; - floor = floorplane.ZatPoint (spot); + floor = floorplane.ZatPoint(spot); for (i = 0; i < linecount; i++) { @@ -107,19 +107,19 @@ fixed_t sector_t::FindLowestFloorSurrounding (vertex_t **v) const // P_FindHighestFloorSurrounding() // FIND HIGHEST FLOOR HEIGHT IN SURROUNDING SECTORS // -fixed_t sector_t::FindHighestFloorSurrounding (vertex_t **v) const +double sector_t::FindHighestFloorSurrounding (vertex_t **v) const { int i; line_t *check; sector_t *other; - fixed_t floor; - fixed_t ofloor; + double floor; + double ofloor; vertex_t *spot; - if (linecount == 0) return GetPlaneTexZ(sector_t::floor); + if (linecount == 0) return GetPlaneTexZF(sector_t::floor); spot = lines[0]->v1; - floor = FIXED_MIN; + floor = -FLT_MAX; for (i = 0; i < linecount; i++) { @@ -157,21 +157,21 @@ fixed_t sector_t::FindHighestFloorSurrounding (vertex_t **v) const // // Rewritten by Lee Killough to avoid fixed array and to be faster // -fixed_t sector_t::FindNextHighestFloor (vertex_t **v) const +double sector_t::FindNextHighestFloor (vertex_t **v) const { - fixed_t height; - fixed_t heightdiff; - fixed_t ofloor, floor; + double height; + double heightdiff; + double ofloor, floor; sector_t *other; vertex_t *spot; line_t *check; int i; - if (linecount == 0) return GetPlaneTexZ(sector_t::floor); + if (linecount == 0) return GetPlaneTexZF(sector_t::floor); spot = lines[0]->v1; - height = floorplane.ZatPoint (spot); - heightdiff = FIXED_MAX; + height = floorplane.ZatPoint(spot); + heightdiff = FLT_MAX; for (i = 0; i < linecount; i++) { @@ -212,21 +212,21 @@ fixed_t sector_t::FindNextHighestFloor (vertex_t **v) const // // jff 02/03/98 Twiddled Lee's P_FindNextHighestFloor to make this // -fixed_t sector_t::FindNextLowestFloor (vertex_t **v) const +double sector_t::FindNextLowestFloor (vertex_t **v) const { - fixed_t height; - fixed_t heightdiff; - fixed_t ofloor, floor; + double height; + double heightdiff; + double ofloor, floor; sector_t *other; vertex_t *spot; line_t *check; int i; - if (linecount == 0) return GetPlaneTexZ(sector_t::floor); + if (linecount == 0) return GetPlaneTexZF(sector_t::floor); spot = lines[0]->v1; height = floorplane.ZatPoint (spot); - heightdiff = FIXED_MAX; + heightdiff = FLT_MAX; for (i = 0; i < linecount; i++) { @@ -242,7 +242,7 @@ fixed_t sector_t::FindNextLowestFloor (vertex_t **v) const spot = check->v1; } ofloor = other->floorplane.ZatPoint (check->v2); - floor = floorplane.ZatPoint (check->v2); + floor = floorplane.ZatPoint(check->v2); if (ofloor < floor && floor - ofloor < heightdiff && !IsLinked(other, false)) { heightdiff = floor - ofloor; @@ -266,38 +266,38 @@ fixed_t sector_t::FindNextLowestFloor (vertex_t **v) const // // jff 02/03/98 Twiddled Lee's P_FindNextHighestFloor to make this // -fixed_t sector_t::FindNextLowestCeiling (vertex_t **v) const +double sector_t::FindNextLowestCeiling (vertex_t **v) const { - fixed_t height; - fixed_t heightdiff; - fixed_t oceil, ceil; + double height; + double heightdiff; + double oceil, ceil; sector_t *other; vertex_t *spot; line_t *check; int i; - if (linecount == 0) return GetPlaneTexZ(sector_t::ceiling); + if (linecount == 0) return GetPlaneTexZF(sector_t::ceiling); spot = lines[0]->v1; - height = ceilingplane.ZatPoint (spot); - heightdiff = FIXED_MAX; + height = ceilingplane.ZatPoint(spot); + heightdiff = FLT_MAX; for (i = 0; i < linecount; i++) { check = lines[i]; if (NULL != (other = getNextSector (check, this))) { - oceil = other->ceilingplane.ZatPoint (check->v1); - ceil = ceilingplane.ZatPoint (check->v1); + oceil = other->ceilingplane.ZatPoint(check->v1); + ceil = ceilingplane.ZatPoint(check->v1); if (oceil < ceil && ceil - oceil < heightdiff && !IsLinked(other, true)) { heightdiff = ceil - oceil; height = oceil; spot = check->v1; } - oceil = other->ceilingplane.ZatPoint (check->v2); - ceil = ceilingplane.ZatPoint (check->v2); + oceil = other->ceilingplane.ZatPoint(check->v2); + ceil = ceilingplane.ZatPoint(check->v2); if (oceil < ceil && ceil - oceil < heightdiff && !IsLinked(other, true)) { heightdiff = ceil - oceil; @@ -321,37 +321,37 @@ fixed_t sector_t::FindNextLowestCeiling (vertex_t **v) const // // jff 02/03/98 Twiddled Lee's P_FindNextHighestFloor to make this // -fixed_t sector_t::FindNextHighestCeiling (vertex_t **v) const +double sector_t::FindNextHighestCeiling (vertex_t **v) const { - fixed_t height; - fixed_t heightdiff; - fixed_t oceil, ceil; + double height; + double heightdiff; + double oceil, ceil; sector_t *other; vertex_t *spot; line_t *check; int i; - if (linecount == 0) return GetPlaneTexZ(sector_t::ceiling); + if (linecount == 0) return GetPlaneTexZF(sector_t::ceiling); spot = lines[0]->v1; - height = ceilingplane.ZatPoint (spot); - heightdiff = FIXED_MAX; + height = ceilingplane.ZatPoint(spot); + heightdiff = FLT_MAX; for (i = 0; i < linecount; i++) { check = lines[i]; if (NULL != (other = getNextSector (check, this))) { - oceil = other->ceilingplane.ZatPoint (check->v1); - ceil = ceilingplane.ZatPoint (check->v1); + oceil = other->ceilingplane.ZatPoint(check->v1); + ceil = ceilingplane.ZatPoint(check->v1); if (oceil > ceil && oceil - ceil < heightdiff && !IsLinked(other, true)) { heightdiff = oceil - ceil; height = oceil; spot = check->v1; } - oceil = other->ceilingplane.ZatPoint (check->v2); - ceil = ceilingplane.ZatPoint (check->v2); + oceil = other->ceilingplane.ZatPoint(check->v2); + ceil = ceilingplane.ZatPoint(check->v2); if (oceil > ceil && oceil - ceil < heightdiff && !IsLinked(other, true)) { heightdiff = oceil - ceil; @@ -368,32 +368,32 @@ fixed_t sector_t::FindNextHighestCeiling (vertex_t **v) const // // FIND LOWEST CEILING IN THE SURROUNDING SECTORS // -fixed_t sector_t::FindLowestCeilingSurrounding (vertex_t **v) const +double sector_t::FindLowestCeilingSurrounding (vertex_t **v) const { - fixed_t height; - fixed_t oceil; + double height; + double oceil; sector_t *other; vertex_t *spot; line_t *check; int i; - if (linecount == 0) return GetPlaneTexZ(sector_t::ceiling); + if (linecount == 0) return GetPlaneTexZF(sector_t::ceiling); spot = lines[0]->v1; - height = FIXED_MAX; + height = FLT_MAX; for (i = 0; i < linecount; i++) { check = lines[i]; if (NULL != (other = getNextSector (check, this))) { - oceil = other->ceilingplane.ZatPoint (check->v1); + oceil = other->ceilingplane.ZatPoint(check->v1); if (oceil < height) { height = oceil; spot = check->v1; } - oceil = other->ceilingplane.ZatPoint (check->v2); + oceil = other->ceilingplane.ZatPoint(check->v2); if (oceil < height) { height = oceil; @@ -410,32 +410,32 @@ fixed_t sector_t::FindLowestCeilingSurrounding (vertex_t **v) const // // FIND HIGHEST CEILING IN THE SURROUNDING SECTORS // -fixed_t sector_t::FindHighestCeilingSurrounding (vertex_t **v) const +double sector_t::FindHighestCeilingSurrounding (vertex_t **v) const { - fixed_t height; - fixed_t oceil; + double height; + double oceil; sector_t *other; vertex_t *spot; line_t *check; int i; - if (linecount == 0) return GetPlaneTexZ(sector_t::ceiling); + if (linecount == 0) return GetPlaneTexZF(sector_t::ceiling); spot = lines[0]->v1; - height = FIXED_MIN; + height = -FLT_MAX; for (i = 0; i < linecount; i++) { check = lines[i]; if (NULL != (other = getNextSector (check, this))) { - oceil = other->ceilingplane.ZatPoint (check->v1); + oceil = other->ceilingplane.ZatPoint(check->v1); if (oceil > height) { height = oceil; spot = check->v1; } - oceil = other->ceilingplane.ZatPoint (check->v2); + oceil = other->ceilingplane.ZatPoint(check->v2); if (oceil > height) { height = oceil; @@ -457,14 +457,14 @@ fixed_t sector_t::FindHighestCeilingSurrounding (vertex_t **v) const // jff 02/03/98 Add routine to find shortest lower texture // -static inline void CheckShortestTex (FTextureID texnum, fixed_t &minsize) +static inline void CheckShortestTex (FTextureID texnum, double &minsize) { if (texnum.isValid() || (texnum.isNull() && (i_compatflags & COMPATF_SHORTTEX))) { FTexture *tex = TexMan[texnum]; if (tex != NULL) { - fixed_t h = tex->GetScaledHeight()<GetScaledHeight(); if (h < minsize) { minsize = h; @@ -473,9 +473,9 @@ static inline void CheckShortestTex (FTextureID texnum, fixed_t &minsize) } } -fixed_t sector_t::FindShortestTextureAround () const +double sector_t::FindShortestTextureAround () const { - fixed_t minsize = FIXED_MAX; + double minsize = FLT_MAX; for (int i = 0; i < linecount; i++) { @@ -485,7 +485,7 @@ fixed_t sector_t::FindShortestTextureAround () const CheckShortestTex (lines[i]->sidedef[1]->GetTexture(side_t::bottom), minsize); } } - return minsize < FIXED_MAX ? minsize : TexMan[0]->GetHeight() * FRACUNIT; + return minsize < FLT_MAX ? minsize : TexMan[0]->GetHeight(); } @@ -499,9 +499,9 @@ fixed_t sector_t::FindShortestTextureAround () const // // jff 03/20/98 Add routine to find shortest upper texture // -fixed_t sector_t::FindShortestUpperAround () const +double sector_t::FindShortestUpperAround () const { - fixed_t minsize = FIXED_MAX; + double minsize = FLT_MAX; for (int i = 0; i < linecount; i++) { @@ -511,7 +511,7 @@ fixed_t sector_t::FindShortestUpperAround () const CheckShortestTex (lines[i]->sidedef[1]->GetTexture(side_t::top), minsize); } } - return minsize < FIXED_MAX ? minsize : TexMan[0]->GetHeight() * FRACUNIT; + return minsize < FLT_MAX ? minsize : TexMan[0]->GetHeight(); } @@ -529,7 +529,7 @@ fixed_t sector_t::FindShortestUpperAround () const // jff 3/14/98 change first parameter to plain height to allow call // from routine not using floormove_t // -sector_t *sector_t::FindModelFloorSector (fixed_t floordestheight) const +sector_t *sector_t::FindModelFloorSector (double floordestheight) const { int i; sector_t *sec; @@ -540,8 +540,8 @@ sector_t *sector_t::FindModelFloorSector (fixed_t floordestheight) const { sec = getNextSector (lines[i], this); if (sec != NULL && - (sec->floorplane.ZatPoint (lines[i]->v1) == floordestheight || - sec->floorplane.ZatPoint (lines[i]->v2) == floordestheight)) + (sec->floorplane.ZatPoint(lines[i]->v1) == floordestheight || + sec->floorplane.ZatPoint(lines[i]->v2) == floordestheight)) { return sec; } @@ -565,7 +565,7 @@ sector_t *sector_t::FindModelFloorSector (fixed_t floordestheight) const // jff 3/14/98 change first parameter to plain height to allow call // from routine not using ceiling_t // -sector_t *sector_t::FindModelCeilingSector (fixed_t floordestheight) const +sector_t *sector_t::FindModelCeilingSector (double floordestheight) const { int i; sector_t *sec; @@ -576,8 +576,8 @@ sector_t *sector_t::FindModelCeilingSector (fixed_t floordestheight) const { sec = getNextSector (lines[i], this); if (sec != NULL && - (sec->ceilingplane.ZatPoint (lines[i]->v1) == floordestheight || - sec->ceilingplane.ZatPoint (lines[i]->v2) == floordestheight)) + (sec->ceilingplane.ZatPoint(lines[i]->v1) == floordestheight || + sec->ceilingplane.ZatPoint(lines[i]->v2) == floordestheight)) { return sec; } @@ -609,34 +609,34 @@ int sector_t::FindMinSurroundingLight (int min) const // // Find the highest point on the floor of the sector // -fixed_t sector_t::FindHighestFloorPoint (vertex_t **v) const +double sector_t::FindHighestFloorPoint (vertex_t **v) const { int i; line_t *line; - fixed_t height = FIXED_MIN; - fixed_t probeheight; + double height = -FLT_MAX; + double probeheight; vertex_t *spot = NULL; - if ((floorplane.a | floorplane.b) == 0) + if (!floorplane.isSlope()) { if (v != NULL) { if (linecount == 0) *v = &vertexes[0]; else *v = lines[0]->v1; } - return -floorplane.d; + return -floorplane.fD(); } for (i = 0; i < linecount; i++) { line = lines[i]; - probeheight = floorplane.ZatPoint (line->v1); + probeheight = floorplane.ZatPoint(line->v1); if (probeheight > height) { height = probeheight; spot = line->v1; } - probeheight = floorplane.ZatPoint (line->v2); + probeheight = floorplane.ZatPoint(line->v2); if (probeheight > height) { height = probeheight; @@ -651,34 +651,34 @@ fixed_t sector_t::FindHighestFloorPoint (vertex_t **v) const // // Find the lowest point on the ceiling of the sector // -fixed_t sector_t::FindLowestCeilingPoint (vertex_t **v) const +double sector_t::FindLowestCeilingPoint (vertex_t **v) const { int i; line_t *line; - fixed_t height = FIXED_MAX; - fixed_t probeheight; + double height = FLT_MAX; + double probeheight; vertex_t *spot = NULL; - if ((ceilingplane.a | ceilingplane.b) == 0) + if (!ceilingplane.isSlope()) { if (v != NULL) { if (linecount == 0) *v = &vertexes[0]; else *v = lines[0]->v1; } - return ceilingplane.d; + return ceilingplane.fD(); } for (i = 0; i < linecount; i++) { line = lines[i]; - probeheight = ceilingplane.ZatPoint (line->v1); + probeheight = ceilingplane.ZatPoint(line->v1); if (probeheight < height) { height = probeheight; spot = line->v1; } - probeheight = ceilingplane.ZatPoint (line->v2); + probeheight = ceilingplane.ZatPoint(line->v2); if (probeheight < height) { height = probeheight; @@ -714,10 +714,10 @@ void sector_t::SetFade(int r, int g, int b) // //=========================================================================== -void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) const +void sector_t::ClosestPoint(const DVector2 &in, DVector2 &out) const { int i; - double x = fx, y = fy; + double x = in.X, y = in.Y; double bestdist = HUGE_VAL; double bestx = 0, besty = 0; @@ -725,34 +725,34 @@ void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) co { vertex_t *v1 = lines[i]->v1; vertex_t *v2 = lines[i]->v2; - double a = v2->x - v1->x; - double b = v2->y - v1->y; + double a = v2->fX() - v1->fX(); + double b = v2->fY() - v1->fY(); double den = a*a + b*b; double ix, iy, dist; if (den == 0) { // Line is actually a point! - ix = v1->x; - iy = v1->y; + ix = v1->fX(); + iy = v1->fY(); } else { - double num = (x - v1->x) * a + (y - v1->y) * b; + double num = (x - v1->fX()) * a + (y - v1->fY()) * b; double u = num / den; if (u <= 0) { - ix = v1->x; - iy = v1->y; + ix = v1->fX(); + iy = v1->fY(); } else if (u >= 1) { - ix = v2->x; - iy = v2->y; + ix = v2->fX(); + iy = v2->fY(); } else { - ix = v1->x + u * a; - iy = v1->y + u * b; + ix = v1->fX() + u * a; + iy = v1->fY() + u * b; } } a = (ix - x); @@ -765,8 +765,7 @@ void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) co besty = iy; } } - ox = fixed_t(bestx); - oy = fixed_t(besty); + out = { bestx, besty }; } @@ -877,9 +876,9 @@ void sector_t::CheckPortalPlane(int plane) AActor *portal = SkyBoxes[plane]; if (!portal || portal->special1 != SKYBOX_LINKEDPORTAL) return; - fixed_t planeh = planes[plane].TexZ; + double planeh = GetPlaneTexZF(plane); int obstructed = PLANEF_OBSTRUCTED * (plane == sector_t::floor ? - planeh > portal->threshold : planeh < portal->threshold); + planeh > portal->specialf1 : planeh < portal->specialf1); planes[plane].Flags = (planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed; } @@ -889,22 +888,21 @@ void sector_t::CheckPortalPlane(int plane) // //=========================================================================== -fixed_t sector_t::HighestCeilingAt(fixed_t x, fixed_t y, sector_t **resultsec) +double sector_t::HighestCeilingAt(const DVector2 &p, sector_t **resultsec) { sector_t *check = this; - fixed_t planeheight = FIXED_MIN; + double planeheight = -FLT_MAX; + DVector2 pos = p; // Continue until we find a blocking portal or a portal below where we actually are. - while (!check->PortalBlocksMovement(ceiling) && planeheight < check->SkyBoxes[ceiling]->threshold) + while (!check->PortalBlocksMovement(ceiling) && planeheight < check->SkyBoxes[ceiling]->specialf1) { - fixedvec2 pos = check->CeilingDisplacement(); - x += pos.x; - y += pos.y; - planeheight = check->SkyBoxes[ceiling]->threshold; - check = P_PointInSector(x, y); + pos += check->CeilingDisplacement(); + planeheight = check->SkyBoxes[ceiling]->specialf1; + check = P_PointInSector(pos); } if (resultsec) *resultsec = check; - return check->ceilingplane.ZatPoint(x, y); + return check->ceilingplane.ZatPoint(pos); } //=========================================================================== @@ -913,53 +911,52 @@ fixed_t sector_t::HighestCeilingAt(fixed_t x, fixed_t y, sector_t **resultsec) // //=========================================================================== -fixed_t sector_t::LowestFloorAt(fixed_t x, fixed_t y, sector_t **resultsec) +double sector_t::LowestFloorAt(const DVector2 &p, sector_t **resultsec) { sector_t *check = this; - fixed_t planeheight = FIXED_MAX; + double planeheight = FLT_MAX; + DVector2 pos = p; // Continue until we find a blocking portal or a portal above where we actually are. - while (!check->PortalBlocksMovement(floor) && planeheight > check->SkyBoxes[floor]->threshold) + while (!check->PortalBlocksMovement(floor) && planeheight > check->SkyBoxes[floor]->specialf1) { - fixedvec2 pos = check->FloorDisplacement(); - x += pos.x; - y += pos.y; - planeheight = check->SkyBoxes[floor]->threshold; - check = P_PointInSector(x, y); + pos += check->FloorDisplacement(); + planeheight = check->SkyBoxes[floor]->specialf1; + check = P_PointInSector(pos); } if (resultsec) *resultsec = check; - return check->floorplane.ZatPoint(x, y); + return check->floorplane.ZatPoint(pos); } -fixed_t sector_t::NextHighestCeilingAt(fixed_t x, fixed_t y, fixed_t bottomz, fixed_t topz, int flags, sector_t **resultsec, F3DFloor **resultffloor) +double sector_t::NextHighestCeilingAt(double x, double y, double bottomz, double topz, int flags, sector_t **resultsec, F3DFloor **resultffloor) { sector_t *sec = this; - fixed_t planeheight = FIXED_MIN; + double planeheight = -FLT_MAX; while (true) { // Looking through planes from bottom to top - fixed_t realceil = sec->ceilingplane.ZatPoint(x, y); + double realceil = sec->ceilingplane.ZatPoint(x, y); for (int i = sec->e->XFloor.ffloors.Size() - 1; i >= 0; --i) { F3DFloor *rover = sec->e->XFloor.ffloors[i]; if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - fixed_t ff_bottom = rover->bottom.plane->ZatPoint(x, y); - fixed_t ff_top = rover->top.plane->ZatPoint(x, y); + double ff_bottom = rover->bottom.plane->ZatPoint(x, y); + double ff_top = rover->top.plane->ZatPoint(x, y); - fixed_t delta1 = bottomz - (ff_bottom + ((ff_top - ff_bottom) / 2)); - fixed_t delta2 = topz - (ff_bottom + ((ff_top - ff_bottom) / 2)); + double delta1 = bottomz - (ff_bottom + ((ff_top - ff_bottom) / 2)); + double delta2 = topz - (ff_bottom + ((ff_top - ff_bottom) / 2)); - if (ff_bottom < realceil && abs(delta1) > abs(delta2)) + if (ff_bottom < realceil && fabs(delta1) > fabs(delta2)) { if (resultsec) *resultsec = sec; if (resultffloor) *resultffloor = rover; return ff_bottom; } } - if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(ceiling) || planeheight >= sec->SkyBoxes[ceiling]->threshold) + if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(ceiling) || planeheight >= sec->SkyBoxes[ceiling]->specialf1) { // Use sector's floor if (resultffloor) *resultffloor = NULL; if (resultsec) *resultsec = sec; @@ -967,24 +964,24 @@ fixed_t sector_t::NextHighestCeilingAt(fixed_t x, fixed_t y, fixed_t bottomz, fi } else { - fixedvec2 pos = sec->CeilingDisplacement(); - x += pos.x; - y += pos.y; - planeheight = sec->SkyBoxes[ceiling]->threshold; + DVector2 pos = sec->CeilingDisplacement(); + x += pos.X; + y += pos.Y; + planeheight = sec->SkyBoxes[ceiling]->specialf1; sec = P_PointInSector(x, y); } } } -fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags, fixed_t steph, sector_t **resultsec, F3DFloor **resultffloor) +double sector_t::NextLowestFloorAt(double x, double y, double z, int flags, double steph, sector_t **resultsec, F3DFloor **resultffloor) { sector_t *sec = this; - fixed_t planeheight = FIXED_MAX; + double planeheight = FLT_MAX; while (true) { // Looking through planes from top to bottom unsigned numff = sec->e->XFloor.ffloors.Size(); - fixed_t realfloor = sec->floorplane.ZatPoint(x, y); + double realfloor = sec->floorplane.ZatPoint(x, y); for (unsigned i = 0; i < numff; ++i) { F3DFloor *ff = sec->e->XFloor.ffloors[i]; @@ -993,8 +990,8 @@ fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags, // either with feet above the 3D floor or feet with less than 'stepheight' map units inside if ((ff->flags & (FF_EXISTS | FF_SOLID)) == (FF_EXISTS | FF_SOLID)) { - fixed_t ffz = ff->top.plane->ZatPoint(x, y); - fixed_t ffb = ff->bottom.plane->ZatPoint(x, y); + double ffz = ff->top.plane->ZatPoint(x, y); + double ffb = ff->bottom.plane->ZatPoint(x, y); if (ffz > realfloor && (z >= ffz || (!(flags & FFCF_3DRESTRICT) && (ffb < z && ffz < z + steph)))) { // This floor is beneath our feet. @@ -1004,7 +1001,7 @@ fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags, } } } - if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(sector_t::floor) || planeheight <= sec->SkyBoxes[floor]->threshold) + if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(sector_t::floor) || planeheight <= sec->SkyBoxes[floor]->specialf1) { // Use sector's floor if (resultffloor) *resultffloor = NULL; if (resultsec) *resultsec = sec; @@ -1012,10 +1009,10 @@ fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags, } else { - fixedvec2 pos = sec->FloorDisplacement(); - x += pos.x; - y += pos.y; - planeheight = sec->SkyBoxes[floor]->threshold; + DVector2 pos = sec->FloorDisplacement(); + x += pos.X; + y += pos.Y; + planeheight = sec->SkyBoxes[floor]->specialf1; sec = P_PointInSector(x, y); } } @@ -1027,26 +1024,40 @@ fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags, // //=========================================================================== -FArchive &operator<< (FArchive &arc, secspecial_t &p) + double sector_t::GetFriction(int plane, double *pMoveFac) const { - if (SaveVersion < 4529) + if (Flags & SECF_FRICTION) + { + if (pMoveFac) *pMoveFac = movefactor; + return friction; + } + FTerrainDef *terrain = &Terrains[GetTerrain(plane)]; + if (terrain->Friction != 0) { - int special; - arc << special; - sector_t sec; - memset(&sec, 0, sizeof(sec)); - P_InitSectorSpecial(&sec, special, true); - sec.GetSpecial(&p); + if (pMoveFac) *pMoveFac = terrain->MoveFactor; + return terrain->Friction; } else { - arc << p.special - << p.damageamount - << p.damagetype - << p.damageinterval - << p.leakydamage - << p.Flags; + if (pMoveFac) *pMoveFac = ORIG_FRICTION_FACTOR; + return ORIG_FRICTION; } +} + +//=========================================================================== +// +// +// +//=========================================================================== + +FArchive &operator<< (FArchive &arc, secspecial_t &p) +{ + arc << p.special + << p.damageamount + << p.damagetype + << p.damageinterval + << p.leakydamage + << p.Flags; return arc; } @@ -1063,18 +1074,18 @@ bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) cons // If the planes do not have matching slopes, then always copy them // because clipping would require creating new sectors. - if (a != dest->a || b != dest->b || c != dest->c) + if (Normal() != dest->Normal()) { copy = true; } - else if (opp->a != -dest->a || opp->b != -dest->b || opp->c != -dest->c) + else if (opp->Normal() != -dest->Normal()) { - if (d < dest->d) + if (fD() < dest->fD()) { copy = true; } } - else if (d < dest->d && d > -opp->d) + else if (fD() < dest->fD() && fD() > -opp->fD()) { copy = true; } @@ -1089,11 +1100,11 @@ bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) cons FArchive &operator<< (FArchive &arc, secplane_t &plane) { - arc << plane.a << plane.b << plane.c << plane.d; - //if (plane.c != 0) + arc << plane.normal << plane.D; + if (plane.normal.Z != 0) { // plane.c should always be non-0. Otherwise, the plane - // would be perfectly vertical. - plane.ic = DivScale32 (1, plane.c); + // would be perfectly vertical. (But then, don't let this crash on a broken savegame...) + plane.negiC = -1 / plane.normal.Z; } return arc; } @@ -1112,21 +1123,19 @@ bool P_AlignFlat (int linenum, int side, int fc) if (!sec) return false; - fixed_t x = line->v1->x; - fixed_t y = line->v1->y; - - angle_t angle = R_PointToAngle2 (x, y, line->v2->x, line->v2->y); - angle_t norm = (angle-ANGLE_90) >> ANGLETOFINESHIFT; - - fixed_t dist = -DMulScale16 (finecosine[norm], x, finesine[norm], y); + DVector2 pos = line->v1->fPos(); + DVector2 pos2 = line->v2->fPos(); + DAngle angle = (pos2 - pos).Angle(); + DAngle norm = angle - 90; + double dist = norm.Cos() * pos.X + norm.Sin() * pos.Y; if (side) { - angle = angle + ANGLE_180; + angle += 180.; dist = -dist; } - sec->SetBase(fc, dist & ((1<<(FRACBITS+8))-1), 0-angle); + sec->SetBase(fc, dist, -angle); return true; } @@ -1201,21 +1210,22 @@ int side_t::GetLightLevel (bool foggy, int baselight, bool is3dlight, int *pfake { if (!(Flags & WALLF_NOFAKECONTRAST) && r_fakecontrast != 0) { + DVector2 delta = linedef->Delta(); int rel; if (((level.flags2 & LEVEL2_SMOOTHLIGHTING) || (Flags & WALLF_SMOOTHLIGHTING) || r_fakecontrast == 2) && - linedef->dx != 0) + delta.X != 0) { rel = xs_RoundToInt // OMG LEE KILLOUGH LIVES! :/ ( level.WallHorizLight - + fabs(atan(double(linedef->dy) / linedef->dx) / 1.57079) + + fabs(atan(delta.Y / delta.X) / 1.57079) * (level.WallVertLight - level.WallHorizLight) ); } else { - rel = linedef->dx == 0 ? level.WallVertLight : - linedef->dy == 0 ? level.WallHorizLight : 0; + rel = delta.X == 0 ? level.WallVertLight : + delta.Y == 0 ? level.WallHorizLight : 0; } if (pfakecontrast != NULL) { diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 5232ab37f..c7395208e 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -24,6 +24,7 @@ #include +#include #ifdef _MSC_VER #include // for alloca() #endif @@ -170,10 +171,8 @@ int bmapheight; // size in mapblocks int *blockmap; // int for larger maps ([RH] Made int because BOOM does) int *blockmaplump; // offsets in blockmap are from here -fixed_t bmaporgx; // origin of block map -fixed_t bmaporgy; -int bmapnegx; // min negs of block map before wrapping -int bmapnegy; +double bmaporgx; // origin of block map +double bmaporgy; FBlockNode** blocklinks; // for thing chains @@ -863,8 +862,7 @@ void P_LoadVertexes (MapData * map) SWORD x, y; (*map->file) >> x >> y; - vertexes[i].x = x << FRACBITS; - vertexes[i].y = y << FRACBITS; + vertexes[i].set(x << FRACBITS, y << FRACBITS); } } @@ -1002,7 +1000,9 @@ void LoadZNodes(FileReaderBase &data, int glnodes) } for (i = 0; i < newVerts; ++i) { - data >> newvertarray[i + orgVerts].x >> newvertarray[i + orgVerts].y; + fixed_t x, y; + data >> x >> y; + newvertarray[i + orgVerts].set(x, y); } if (vertexes != newvertarray) { @@ -1220,10 +1220,8 @@ void P_LoadSegs (MapData * map) BYTE *vertchanged = new BYTE[numvertexes]; // phares 10/4/98 DWORD segangle; line_t* line; // phares 10/4/98 - int ptp_angle; // phares 10/4/98 - int delta_angle; // phares 10/4/98 - int dis; // phares 10/4/98 - int dx,dy; // phares 10/4/98 + //int ptp_angle; // phares 10/4/98 + //int delta_angle; // phares 10/4/98 int vnum1,vnum2; // phares 10/4/98 int lumplen = map->Size(ML_SEGS); @@ -1315,28 +1313,26 @@ void P_LoadSegs (MapData * map) // off, then move one vertex. This may seem insignificant, but one degree // errors _can_ cause firelines. - ptp_angle = R_PointToAngle2 (li->v1->x, li->v1->y, li->v2->x, li->v2->y); - dis = 0; - delta_angle = (absangle(ptp_angle-(segangle<<16))>>ANGLETOFINESHIFT)*360/FINEANGLES; + DAngle ptp_angle = (li->v2->fPos() - li->v1->fPos()).Angle(); + DAngle seg_angle = AngleToFloat(segangle); + DAngle delta_angle = absangle(ptp_angle, seg_angle); - if (delta_angle != 0) + if (delta_angle >= 1.) { - segangle >>= (ANGLETOFINESHIFT-16); - dx = (li->v1->x - li->v2->x)>>FRACBITS; - dy = (li->v1->y - li->v2->y)>>FRACBITS; - dis = ((int) sqrt((double)(dx*dx + dy*dy)))<v2->fPos() - li->v1->fPos()).Length(); + DVector2 delta = seg_angle.ToVector(); if ((vnum2 > vnum1) && (vertchanged[vnum2] == 0)) { - li->v2->x = li->v1->x + FixedMul(dis,dx); - li->v2->y = li->v1->y + FixedMul(dis,dy); + li->v2->set( + li->v1->fX() + dis * delta.X, + li->v1->fY() + dis * delta.Y); vertchanged[vnum2] = 1; // this was changed } else if (vertchanged[vnum1] == 0) { - li->v1->x = li->v2->x - FixedMul(dis,dx); - li->v1->y = li->v2->y - FixedMul(dis,dy); + li->v1->set( + li->v2->fX() - dis * delta.X, + li->v2->fY() - dis * delta.Y); vertchanged[vnum1] = 1; // this was changed } } @@ -1504,14 +1500,10 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) { ss->e = §ors[0].e[i]; if (!map->HasBehavior) ss->Flags |= SECF_FLOORDROP; - ss->SetPlaneTexZ(sector_t::floor, LittleShort(ms->floorheight)<floorplane.d = -ss->GetPlaneTexZ(sector_t::floor); - ss->floorplane.c = FRACUNIT; - ss->floorplane.ic = FRACUNIT; - ss->SetPlaneTexZ(sector_t::ceiling, LittleShort(ms->ceilingheight)<ceilingplane.d = ss->GetPlaneTexZ(sector_t::ceiling); - ss->ceilingplane.c = -FRACUNIT; - ss->ceilingplane.ic = -FRACUNIT; + ss->SetPlaneTexZ(sector_t::floor, (double)LittleShort(ms->floorheight)); + ss->floorplane.set(0, 0, 1., -ss->GetPlaneTexZF(sector_t::floor)); + ss->SetPlaneTexZ(sector_t::ceiling, (double)LittleShort(ms->ceilingheight)); + ss->ceilingplane.set(0, 0, -1., ss->GetPlaneTexZF(sector_t::ceiling)); SetTexture(ss, i, sector_t::floor, ms->floorpic, missingtex, true); SetTexture(ss, i, sector_t::ceiling, ms->ceilingpic, missingtex, true); ss->lightlevel = LittleShort(ms->lightlevel); @@ -1527,12 +1519,12 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) ss->nextsec = -1; //jff 2/26/98 add fields to support locking out ss->prevsec = -1; // stair retriggering until build completes - ss->SetAlpha(sector_t::floor, FRACUNIT); - ss->SetAlpha(sector_t::ceiling, FRACUNIT); - ss->SetXScale(sector_t::floor, FRACUNIT); // [RH] floor and ceiling scaling - ss->SetYScale(sector_t::floor, FRACUNIT); - ss->SetXScale(sector_t::ceiling, FRACUNIT); - ss->SetYScale(sector_t::ceiling, FRACUNIT); + ss->SetAlpha(sector_t::floor, 1.); + ss->SetAlpha(sector_t::ceiling, 1.); + ss->SetXScale(sector_t::floor, 1.); // [RH] floor and ceiling scaling + ss->SetYScale(sector_t::floor, 1.); + ss->SetXScale(sector_t::ceiling, 1.); + ss->SetYScale(sector_t::ceiling, 1.); ss->heightsec = NULL; // sector used to get floor and ceiling height // killough 3/7/98: end changes @@ -1670,8 +1662,8 @@ AActor *SpawnMapThing(int index, FMapThing *mt, int position) AActor *spawned = P_SpawnMapThing(mt, position); if (dumpspawnedthings) { - Printf("%5d: (%5d, %5d, %5d), doomednum = %5d, flags = %04x, type = %s\n", - index, mt->x>>FRACBITS, mt->y>>FRACBITS, mt->z>>FRACBITS, mt->EdNum, mt->flags, + Printf("%5d: (%5f, %5f, %5f), doomednum = %5d, flags = %04x, type = %s\n", + index, mt->pos.X, mt->pos.Y, mt->pos.Z, mt->EdNum, mt->flags, spawned? spawned->GetClass()->TypeName.GetChars() : "(none)"); } T_AddSpawnedThing(spawned); @@ -1755,17 +1747,17 @@ void P_LoadThings (MapData * map) memset (&mti[i], 0, sizeof(mti[i])); - mti[i].gravity = FRACUNIT; + mti[i].Gravity = 1; mti[i].Conversation = 0; mti[i].SkillFilter = MakeSkill(flags); mti[i].ClassFilter = 0xffff; // Doom map format doesn't have class flags so spawn for all player classes mti[i].RenderStyle = STYLE_Count; - mti[i].alpha = -1; + mti[i].Alpha = -1; mti[i].health = 1; mti[i].FloatbobPhase = -1; - mti[i].x = LittleShort(mt->x) << FRACBITS; - mti[i].y = LittleShort(mt->y) << FRACBITS; + mti[i].pos.X = LittleShort(mt->x); + mti[i].pos.Y = LittleShort(mt->y); mti[i].angle = LittleShort(mt->angle); mti[i].EdNum = LittleShort(mt->type); mti[i].info = DoomEdMap.CheckKey(mti[i].EdNum); @@ -1837,9 +1829,9 @@ void P_LoadThings2 (MapData * map) memset (&mti[i], 0, sizeof(mti[i])); mti[i].thingid = LittleShort(mth[i].thingid); - mti[i].x = LittleShort(mth[i].x)<v1; v2 = ld->v2; - ld->dx = v2->x - v1->x; - ld->dy = v2->y - v1->y; + ld->setDelta(v2->fX() - v1->fX(), v2->fY() - v1->fY()); - if (v1->x < v2->x) + if (v1->fX() < v2->fX()) { - ld->bbox[BOXLEFT] = v1->x; - ld->bbox[BOXRIGHT] = v2->x; + ld->bbox[BOXLEFT] = v1->fX(); + ld->bbox[BOXRIGHT] = v2->fX(); } else { - ld->bbox[BOXLEFT] = v2->x; - ld->bbox[BOXRIGHT] = v1->x; + ld->bbox[BOXLEFT] = v2->fX(); + ld->bbox[BOXRIGHT] = v1->fX(); } - if (v1->y < v2->y) + if (v1->fY() < v2->fY()) { - ld->bbox[BOXBOTTOM] = v1->y; - ld->bbox[BOXTOP] = v2->y; + ld->bbox[BOXBOTTOM] = v1->fY(); + ld->bbox[BOXTOP] = v2->fY(); } else { - ld->bbox[BOXBOTTOM] = v2->y; - ld->bbox[BOXTOP] = v1->y; + ld->bbox[BOXBOTTOM] = v2->fY(); + ld->bbox[BOXTOP] = v1->fY(); } } @@ -2014,8 +2005,8 @@ void P_FinishLoadingLineDef(line_t *ld, int alpha) ld->frontsector = ld->sidedef[0] != NULL ? ld->sidedef[0]->sector : NULL; ld->backsector = ld->sidedef[1] != NULL ? ld->sidedef[1]->sector : NULL; - double dx = FIXED2DBL(ld->v2->x - ld->v1->x); - double dy = FIXED2DBL(ld->v2->y - ld->v1->y); + double dx = (ld->v2->fX() - ld->v1->fX()); + double dy = (ld->v2->fY() - ld->v1->fY()); int linenum = int(ld-lines); if (ld->frontsector == NULL) @@ -2024,7 +2015,7 @@ void P_FinishLoadingLineDef(line_t *ld, int alpha) } // [RH] Set some new sidedef properties - int len = (int)(sqrt (dx*dx + dy*dy) + 0.5f); + int len = (int)(g_sqrt (dx*dx + dy*dy) + 0.5f); if (ld->sidedef[0] != NULL) { @@ -2055,7 +2046,7 @@ void P_FinishLoadingLineDef(line_t *ld, int alpha) additive = true; } - alpha = Scale(alpha, FRACUNIT, 255); + alpha = Scale(alpha, OPAQUE, 255); if (!ld->args[0]) { ld->Alpha = alpha; @@ -2140,8 +2131,8 @@ void P_LoadLineDefs (MapData * map) I_Error ("Line %d has invalid vertices: %d and/or %d.\nThe map only contains %d vertices.", i+skipped, v1, v2, numvertexes); } else if (v1 == v2 || - (vertexes[LittleShort(mld->v1)].x == vertexes[LittleShort(mld->v2)].x && - vertexes[LittleShort(mld->v1)].y == vertexes[LittleShort(mld->v2)].y)) + (vertexes[LittleShort(mld->v1)].fX() == vertexes[LittleShort(mld->v2)].fX() && + vertexes[LittleShort(mld->v1)].fY() == vertexes[LittleShort(mld->v2)].fY())) { Printf ("Removing 0-length line %d\n", i+skipped); memmove (mld, mld+1, sizeof(*mld)*(numlines-i-1)); @@ -2172,7 +2163,7 @@ void P_LoadLineDefs (MapData * map) ld = lines; for (i = 0; i < numlines; i++, mld++, ld++) { - ld->Alpha = FRACUNIT; // [RH] Opaque by default + ld->Alpha = OPAQUE; // [RH] Opaque by default ld->portalindex = UINT_MAX; // [RH] Translate old linedef special and flags to be @@ -2229,8 +2220,8 @@ void P_LoadLineDefs2 (MapData * map) mld = ((maplinedef2_t*)mldf) + i; if (mld->v1 == mld->v2 || - (vertexes[LittleShort(mld->v1)].x == vertexes[LittleShort(mld->v2)].x && - vertexes[LittleShort(mld->v1)].y == vertexes[LittleShort(mld->v2)].y)) + (vertexes[LittleShort(mld->v1)].fX() == vertexes[LittleShort(mld->v2)].fX() && + vertexes[LittleShort(mld->v1)].fY() == vertexes[LittleShort(mld->v2)].fY())) { Printf ("Removing 0-length line %d\n", i+skipped); memmove (mld, mld+1, sizeof(*mld)*(numlines-i-1)); @@ -2276,7 +2267,7 @@ void P_LoadLineDefs2 (MapData * map) ld->v1 = &vertexes[LittleShort(mld->v1)]; ld->v2 = &vertexes[LittleShort(mld->v2)]; - ld->Alpha = FRACUNIT; // [RH] Opaque by default + ld->Alpha = OPAQUE; // [RH] Opaque by default P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0])); P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1])); @@ -2423,15 +2414,15 @@ static void P_LoopSidedefs (bool firstloop) if (sidetemp[right].b.next != NO_SIDE) { int bestright = right; // Shut up, GCC - angle_t bestang = ANGLE_MAX; + DAngle bestang = 360.; line_t *leftline, *rightline; - angle_t ang1, ang2, ang; + DAngle ang1, ang2, ang; leftline = sides[i].linedef; - ang1 = R_PointToAngle2 (0, 0, leftline->dx, leftline->dy); + ang1 = leftline->Delta().Angle(); if (!sidetemp[i].b.lineside) { - ang1 += ANGLE_180; + ang1 += 180; } while (right != NO_SIDE) @@ -2441,13 +2432,13 @@ static void P_LoopSidedefs (bool firstloop) rightline = sides[right].linedef; if (rightline->frontsector != rightline->backsector) { - ang2 = R_PointToAngle2 (0, 0, rightline->dx, rightline->dy); + ang2 = rightline->Delta().Angle(); if (sidetemp[right].b.lineside) { - ang2 += ANGLE_180; + ang2 += 180; } - ang = ang2 - ang1; + ang = (ang2 - ang1).Normalized360(); if (ang != 0 && ang <= bestang) { @@ -2785,6 +2776,7 @@ static void P_CreateBlockMap () TArray *BlockLists, *block, *endblock; int adder; int bmapwidth, bmapheight; + double dminx, dmaxx, dminy, dmaxy; int minx, maxx, miny, maxy; int i; int line; @@ -2793,21 +2785,21 @@ static void P_CreateBlockMap () return; // Find map extents for the blockmap - minx = maxx = vertexes[0].x; - miny = maxy = vertexes[0].y; + dminx = dmaxx = vertexes[0].fX(); + dminy = dmaxy = vertexes[0].fY(); for (i = 1; i < numvertexes; ++i) { - if (vertexes[i].x < minx) minx = vertexes[i].x; - else if (vertexes[i].x > maxx) maxx = vertexes[i].x; - if (vertexes[i].y < miny) miny = vertexes[i].y; - else if (vertexes[i].y > maxy) maxy = vertexes[i].y; + if (vertexes[i].fX() < dminx) dminx = vertexes[i].fX(); + else if (vertexes[i].fX() > dmaxx) dmaxx = vertexes[i].fX(); + if (vertexes[i].fY() < dminy) dminy = vertexes[i].fY(); + else if (vertexes[i].fY() > dmaxy) dmaxy = vertexes[i].fY(); } - maxx >>= FRACBITS; - minx >>= FRACBITS; - maxy >>= FRACBITS; - miny >>= FRACBITS; + minx = int(dminx); + miny = int(dminy); + maxx = int(dmaxx); + maxy = int(dmaxy); bmapwidth = ((maxx - minx) >> BLOCKBITS) + 1; bmapheight = ((maxy - miny) >> BLOCKBITS) + 1; @@ -2823,10 +2815,10 @@ static void P_CreateBlockMap () for (line = 0; line < numlines; ++line) { - int x1 = lines[line].v1->x >> FRACBITS; - int y1 = lines[line].v1->y >> FRACBITS; - int x2 = lines[line].v2->x >> FRACBITS; - int y2 = lines[line].v2->y >> FRACBITS; + int x1 = int(lines[line].v1->fX()); + int y1 = int(lines[line].v1->fY()); + int x2 = int(lines[line].v2->fX()); + int y2 = int(lines[line].v2->fY()); int dx = x2 - x1; int dy = y2 - y1; int bx = (x1 - minx) >> BLOCKBITS; @@ -3077,15 +3069,10 @@ void P_LoadBlockMap (MapData * map) } - bmaporgx = blockmaplump[0] << FRACBITS; - bmaporgy = blockmaplump[1] << FRACBITS; + bmaporgx = blockmaplump[0]; + bmaporgy = blockmaplump[1]; bmapwidth = blockmaplump[2]; bmapheight = blockmaplump[3]; - // MAES: set blockmapxneg and blockmapyneg - // E.g. for a full 512x512 map, they should be both - // -1. For a 257*257, they should be both -255 etc. - bmapnegx = bmapwidth > 255 ? bmapwidth - 512 : -257; - bmapnegy = bmapheight > 255 ? bmapheight - 512 : -257; // clear out mobj chains count = bmapwidth*bmapheight; @@ -3216,14 +3203,14 @@ static void P_GroupLines (bool buildmap) for (j = 0; j < sector->linecount; ++j) { li = sector->lines[j]; - bbox.AddToBox (li->v1->x, li->v1->y); - bbox.AddToBox (li->v2->x, li->v2->y); + bbox.AddToBox (li->v1->fPos()); + bbox.AddToBox (li->v2->fPos()); } } // set the center to the middle of the bounding box - sector->centerspot.x = bbox.Right()/2 + bbox.Left()/2; - sector->centerspot.y = bbox.Top()/2 + bbox.Bottom()/2; + sector->centerspot.X = (bbox.Right() + bbox.Left()/2); + sector->centerspot.Y = (bbox.Top() + bbox.Bottom()/2); // For triangular sectors the above does not calculate good points unless the longest of the triangle's lines is perfectly horizontal and vertical if (sector->linecount == 3) @@ -3233,8 +3220,8 @@ static void P_GroupLines (bool buildmap) Triangle[1] = sector->lines[0]->v2; if (sector->linecount > 1) { - fixed_t dx = Triangle[1]->x - Triangle[0]->x; - fixed_t dy = Triangle[1]->y - Triangle[0]->y; + double dx = Triangle[1]->fX() - Triangle[0]->fX(); + double dy = Triangle[1]->fY() - Triangle[0]->fY(); // Find another point in the sector that does not lie // on the same line as the first two points. for (j = 0; j < 2; ++j) @@ -3242,11 +3229,10 @@ static void P_GroupLines (bool buildmap) vertex_t *v; v = (j == 1) ? sector->lines[1]->v1 : sector->lines[1]->v2; - if (DMulScale32 (v->y - Triangle[0]->y, dx, - Triangle[0]->x - v->x, dy) != 0) + if ( (v->fY() - Triangle[0]->fY()) * dx + (Triangle[0]->fX() - v->fX() * dy) != 0) { - sector->centerspot.x = Triangle[0]->x / 3 + Triangle[1]->x / 3 + v->x / 3; - sector->centerspot.y = Triangle[0]->y / 3 + Triangle[1]->y / 3 + v->y / 3; + sector->centerspot.X = (Triangle[0]->fX() / 3 + Triangle[1]->fX() / 3 + v->fX() / 3); + sector->centerspot.Y = (Triangle[0]->fY() / 3 + Triangle[1]->fY() / 3 + v->fY() / 3); break; } } @@ -3367,8 +3353,8 @@ void P_GetPolySpots (MapData * map, TArray &spots, TAr if (mentry != NULL && mentry->Type == NULL && mentry->Special >= SMT_PolyAnchor && mentry->Special <= SMT_PolySpawnHurt) { FNodeBuilder::FPolyStart newvert; - newvert.x = MapThingsConverted[i].x; - newvert.y = MapThingsConverted[i].y; + newvert.x = FLOAT2FIXED(MapThingsConverted[i].pos.X); + newvert.y = FLOAT2FIXED(MapThingsConverted[i].pos.Y); newvert.polynum = MapThingsConverted[i].angle; if (mentry->Special == SMT_PolyAnchor) { @@ -3608,7 +3594,7 @@ void P_SetupLevel (const char *lumpname, int position) translationtables[TRANSLATION_LevelScripted].Clear(); // Initial height of PointOfView will be set by player think. - players[consoleplayer].viewz = 1; + players[consoleplayer].viewz = NO_VALUE; // Make sure all sounds are stopped before Z_FreeTags. S_Start (); @@ -3925,8 +3911,8 @@ void P_SetupLevel (const char *lumpname, int position) seg_t * seg=&segs[i]; if (seg->backsector == seg->frontsector && seg->linedef) { - fixed_t d1=P_AproxDistance(seg->v1->x-seg->linedef->v1->x,seg->v1->y-seg->linedef->v1->y); - fixed_t d2=P_AproxDistance(seg->v2->x-seg->linedef->v1->x,seg->v2->y-seg->linedef->v1->y); + double d1 = (seg->v1->fPos() - seg->linedef->v1->fPos()).LengthSquared(); + double d2 = (seg->v2->fPos() - seg->linedef->v1->fPos()).LengthSquared(); if (d2 (%d,%d)\n", lines[linenum].v1->x >> FRACBITS, - lines[linenum].v1->y >> FRACBITS, - lines[linenum].v2->x >> FRACBITS, - lines[linenum].v2->y >> FRACBITS); + Printf ("(%f,%f) -> (%f,%f)\n", lines[linenum].v1->fX(), + lines[linenum].v1->fY(), + lines[linenum].v2->fX(), + lines[linenum].v2->fY()); } #endif diff --git a/src/p_setup.h b/src/p_setup.h index 321e0bc11..38d61c1eb 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -119,7 +119,7 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineindexforid = -1) int P_TranslateSectorSpecial (int); int GetUDMFInt(int type, int index, const char *key); -fixed_t GetUDMFFixed(int type, int index, const char *key); +double GetUDMFFloat(int type, int index, const char *key); bool P_LoadGLNodes(MapData * map); bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime); diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 7669ac888..57106b2cf 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -59,8 +59,8 @@ enum struct SightOpening { - fixed_t top; - fixed_t bottom; + double top; + double bottom; int range; int portalflags; @@ -72,9 +72,9 @@ struct SightOpening struct SightTask { - fixed_t frac; - fixed_t topslope; - fixed_t bottomslope; + double Frac; + double topslope; + double bottomslope; int direction; int portalgroup; }; @@ -85,23 +85,23 @@ static TArray portals(32); class SightCheck { - fixedvec3 sightstart; - fixedvec2 sightend; - fixed_t startfrac; + DVector3 sightstart; + DVector2 sightend; + double Startfrac; AActor * seeingthing; - fixed_t lastztop; // z at last line - fixed_t lastzbottom; // z at last line + double Lastztop; // z at last line + double Lastzbottom; // z at last line sector_t * lastsector; // last sector being entered by trace - fixed_t topslope, bottomslope; // slopes to top and bottom of target + double topslope, bottomslope; // slopes to top and bottom of target int Flags; - divline_t trace; + divline_t Trace; int portaldir; int portalgroup; bool portalfound; unsigned int myseethrough; - void P_SightOpening(SightOpening &open, const line_t *linedef, fixed_t x, fixed_t y); + void P_SightOpening(SightOpening &open, const line_t *linedef, double x, double y); bool PTR_SightTraverse (intercept_t *in); bool P_SightCheckLine (line_t *ld); int P_SightBlockLinesIterator (int x, int y); @@ -114,11 +114,11 @@ public: { sightstart = t1->PosRelative(task->portalgroup); sightend = t2->PosRelative(task->portalgroup); - sightstart.z += t1->height - (t1->height >> 2); + sightstart.Z += t1->Height / 2; - startfrac = task->frac; - trace = { sightstart.x, sightstart.y, sightend.x - sightstart.x, sightend.y - sightstart.y }; - lastztop = lastzbottom = sightstart.z; + Startfrac = task->Frac; + Trace = { sightstart.X, sightstart.Y, sightend.X - sightstart.X, sightend.Y - sightstart.Y }; + Lastztop = Lastzbottom = sightstart.Z; lastsector = startsector; seeingthing=t2; topslope = task->topslope; @@ -139,7 +139,7 @@ public: // //========================================================================== -void SightCheck::P_SightOpening(SightOpening &open, const line_t *linedef, fixed_t x, fixed_t y) +void SightCheck::P_SightOpening(SightOpening &open, const line_t *linedef, double x, double y) { open.portalflags = 0; sector_t *front = linedef->frontsector; @@ -159,14 +159,14 @@ void SightCheck::P_SightOpening(SightOpening &open, const line_t *linedef, fixed } - fixed_t fc = 0, ff = 0, bc = 0, bf = 0; + double fc = 0, ff = 0, bc = 0, bf = 0; if (linedef->flags & ML_PORTALCONNECT) { - if (!front->PortalBlocksSight(sector_t::ceiling)) fc = FIXED_MAX, open.portalflags |= SO_TOPFRONT; - if (!back->PortalBlocksSight(sector_t::ceiling)) bc = FIXED_MAX, open.portalflags |= SO_TOPBACK; - if (!front->PortalBlocksSight(sector_t::floor)) ff = FIXED_MIN, open.portalflags |= SO_BOTTOMFRONT; - if (!back->PortalBlocksSight(sector_t::floor)) bf = FIXED_MIN, open.portalflags |= SO_BOTTOMBACK; + if (!front->PortalBlocksSight(sector_t::ceiling)) fc = LINEOPEN_MAX, open.portalflags |= SO_TOPFRONT; + if (!back->PortalBlocksSight(sector_t::ceiling)) bc = LINEOPEN_MAX, open.portalflags |= SO_TOPBACK; + if (!front->PortalBlocksSight(sector_t::floor)) ff = LINEOPEN_MIN, open.portalflags |= SO_BOTTOMFRONT; + if (!back->PortalBlocksSight(sector_t::floor)) bf = LINEOPEN_MIN, open.portalflags |= SO_BOTTOMBACK; } if (fc == 0) fc = front->ceilingplane.ZatPoint(x, y); @@ -178,7 +178,7 @@ void SightCheck::P_SightOpening(SightOpening &open, const line_t *linedef, fixed open.top = MIN(fc, bc); // we only want to know if there is an opening, not how large it is. - open.range = open.bottom >= open.top ? 0 : 1; + open.range = open.bottom < open.top; } @@ -193,7 +193,7 @@ void SightCheck::P_SightOpening(SightOpening &open, const line_t *linedef, fixed bool SightCheck::PTR_SightTraverse (intercept_t *in) { line_t *li; - fixed_t slope; + double slope; SightOpening open; int frontflag = -1; @@ -207,8 +207,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) if ((i_compatflags & COMPATF_TRACE) && li->frontsector == li->backsector) return true; - fixed_t trX=trace.x + FixedMul (trace.dx, in->frac); - fixed_t trY=trace.y + FixedMul (trace.dy, in->frac); + double trX = Trace.x + Trace.dx * in->frac; + double trY = Trace.y + Trace.dy * in->frac; P_SightOpening (open, li, trX, trY); FLinePortal *lport = li->getPortal(); @@ -217,17 +217,17 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) return false; // stop // check bottom - if (open.bottom > FIXED_MIN) + if (open.bottom > LINEOPEN_MIN) { - slope = FixedDiv(open.bottom - sightstart.z, in->frac); + slope = (open.bottom - sightstart.Z) / in->frac; if (slope > bottomslope) bottomslope = slope; } // check top - if (open.top < FIXED_MAX) + if (open.top < LINEOPEN_MAX) { - slope = FixedDiv(open.top - sightstart.z, in->frac); + slope = (open.top - sightstart.Z) / in->frac; if (slope < topslope) topslope = slope; } @@ -235,7 +235,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) if (open.portalflags) { sector_t *frontsec, *backsec; - frontflag = P_PointOnLineSidePrecise(sightstart.x, sightstart.y, li); + frontflag = P_PointOnLineSidePrecise(sightstart, li); if (!frontflag) { frontsec = li->frontsector; @@ -270,41 +270,39 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) // now handle 3D-floors if(li->frontsector->e->XFloor.ffloors.Size() || li->backsector->e->XFloor.ffloors.Size()) { - if (frontflag == -1) frontflag = P_PointOnLineSidePrecise(sightstart.x, sightstart.y, li); + if (frontflag == -1) frontflag = P_PointOnLineSidePrecise(sightstart, li); //Check 3D FLOORS! for(int i=1;i<=2;i++) { sector_t * s=i==1? li->frontsector:li->backsector; - fixed_t highslope, lowslope; + double highslope, lowslope; - fixed_t topz= FixedMul (topslope, in->frac) + sightstart.z; - fixed_t bottomz= FixedMul (bottomslope, in->frac) + sightstart.z; + double topz= topslope * in->frac + sightstart.Z; + double bottomz= bottomslope * in->frac + sightstart.Z; - for(unsigned int j=0;je->XFloor.ffloors.Size();j++) + for (auto rover : s->e->XFloor.ffloors) { - F3DFloor* rover=s->e->XFloor.ffloors[j]; - - if((rover->flags & FF_SEETHROUGH) == myseethrough || !(rover->flags & FF_EXISTS)) continue; + if ((rover->flags & FF_SEETHROUGH) == myseethrough || !(rover->flags & FF_EXISTS)) continue; if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue; - - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(trX, trY); - fixed_t ff_top=rover->top.plane->ZatPoint(trX, trY); - highslope = FixedDiv (ff_top - sightstart.z, in->frac); - lowslope = FixedDiv (ff_bottom - sightstart.z, in->frac); + double ff_bottom = rover->bottom.plane->ZatPoint(trX, trY); + double ff_top = rover->top.plane->ZatPoint(trX, trY); - if (highslope>=topslope) + highslope = (ff_top - sightstart.Z) / in->frac; + lowslope = (ff_bottom - sightstart.Z) / in->frac; + + if (highslope >= topslope) { // blocks completely - if (lowslope<=bottomslope) return false; + if (lowslope <= bottomslope) return false; // blocks upper edge of view - if (lowslopebottomslope) bottomslope=highslope; + if (highslope > bottomslope) bottomslope = highslope; } else { @@ -312,39 +310,37 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) // itself it can't be view blocking. // However, if there's a 3D-floor on the other side that obstructs the same vertical range // the 2 together will block sight. - sector_t * sb=i==2? li->frontsector:li->backsector; + sector_t * sb = i == 2 ? li->frontsector : li->backsector; - for(unsigned int k=0;ke->XFloor.ffloors.Size();k++) + for (auto rover2 : sb->e->XFloor.ffloors) { - F3DFloor* rover2=sb->e->XFloor.ffloors[k]; - - if((rover2->flags & FF_SEETHROUGH) == myseethrough || !(rover2->flags & FF_EXISTS)) continue; + if ((rover2->flags & FF_SEETHROUGH) == myseethrough || !(rover2->flags & FF_EXISTS)) continue; if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue; - - fixed_t ffb_bottom=rover2->bottom.plane->ZatPoint(trX, trY); - fixed_t ffb_top=rover2->top.plane->ZatPoint(trX, trY); - if ( (ffb_bottom >= ff_bottom && ffb_bottom<=ff_top) || + double ffb_bottom = rover2->bottom.plane->ZatPoint(trX, trY); + double ffb_top = rover2->top.plane->ZatPoint(trX, trY); + + if ((ffb_bottom >= ff_bottom && ffb_bottom <= ff_top) || (ffb_top <= ff_top && ffb_top >= ff_bottom) || (ffb_top >= ff_top && ffb_bottom <= ff_bottom) || - (ffb_top <= ff_top && ffb_bottom >= ff_bottom) ) + (ffb_top <= ff_top && ffb_bottom >= ff_bottom)) { return false; } } } // trace is leaving a sector with a 3d-floor - if (s==lastsector && frontflag==i-1) + if (s == lastsector && frontflag == i - 1) { // upper slope intersects with this 3d-floor - if (lastztop<=ff_bottom && topz>ff_top) + if (Lastztop <= ff_bottom && topz > ff_top) { - topslope=lowslope; + topslope = lowslope; } // lower slope intersects with this 3d-floor - if (lastzbottom>=ff_top && bottomz= ff_top && bottomz < ff_top) { - bottomslope=highslope; + bottomslope = highslope; } } if (topslope <= bottomslope) return false; // stop @@ -354,8 +350,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) } else lastsector=NULL; // don't need it if there are no 3D-floors - lastztop= FixedMul (topslope, in->frac) + sightstart.z; - lastzbottom= FixedMul (bottomslope, in->frac) + sightstart.z; + Lastztop = (topslope * in->frac) + sightstart.Z; + Lastzbottom = (bottomslope * in->frac) + sightstart.Z; return true; // keep going } @@ -379,14 +375,14 @@ bool SightCheck::P_SightCheckLine (line_t *ld) return true; } ld->validcount = validcount; - if (P_PointOnDivlineSidePrecise (ld->v1->x, ld->v1->y, &trace) == - P_PointOnDivlineSidePrecise (ld->v2->x, ld->v2->y, &trace)) + if (P_PointOnDivlineSide (ld->v1->fPos(), &Trace) == + P_PointOnDivlineSide (ld->v2->fPos(), &Trace)) { return true; // line isn't crossed } P_MakeDivline (ld, &dl); - if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &dl) == - P_PointOnDivlineSidePrecise (trace.x+trace.dx, trace.y+trace.dy, &dl)) + if (P_PointOnDivlineSide (Trace.x, Trace.y, &dl) == + P_PointOnDivlineSide (Trace.x+Trace.dx, Trace.y+Trace.dy, &dl)) { return true; // line isn't crossed } @@ -505,7 +501,7 @@ int SightCheck::P_SightBlockLinesIterator (int x, int y) bool SightCheck::P_SightTraverseIntercepts () { unsigned count; - fixed_t dist; + double dist; intercept_t *scan, *in; unsigned scanpos; divline_t dl; @@ -518,10 +514,10 @@ bool SightCheck::P_SightTraverseIntercepts () { scan = &intercepts[scanpos]; P_MakeDivline (scan->d.line, &dl); - scan->frac = P_InterceptVector (&trace, &dl); - if (scan->frac < startfrac) + scan->frac = P_InterceptVector (&Trace, &dl); + if (scan->frac < Startfrac) { - scan->frac = FIXED_MAX; + scan->frac = INT_MAX; count--; } } @@ -534,7 +530,7 @@ bool SightCheck::P_SightTraverseIntercepts () while (count--) { - dist = FIXED_MAX; + dist = INT_MAX; for (scanpos = 0; scanpos < intercepts.Size (); scanpos++) { scan = &intercepts[scanpos]; @@ -549,31 +545,28 @@ bool SightCheck::P_SightTraverseIntercepts () { if (!PTR_SightTraverse (in)) return false; // don't bother going farther - in->frac = FIXED_MAX; + in->frac = INT_MAX; } } - if (lastsector==seeingthing->Sector && lastsector->e->XFloor.ffloors.Size()) + if (lastsector == seeingthing->Sector && lastsector->e->XFloor.ffloors.Size()) { // we must do one last check whether the trace has crossed a 3D floor in the last sector - fixed_t topz= topslope + sightstart.z; - fixed_t bottomz= bottomslope + sightstart.z; - - for(unsigned int i=0;ie->XFloor.ffloors.Size();i++) + double topz = topslope + sightstart.Z; + double bottomz = bottomslope + sightstart.Z; + + for (auto rover : lastsector->e->XFloor.ffloors) { - F3DFloor* rover = lastsector->e->XFloor.ffloors[i]; - - if((rover->flags & FF_SOLID) == myseethrough || !(rover->flags & FF_EXISTS)) continue; + if ((rover->flags & FF_SOLID) == myseethrough || !(rover->flags & FF_EXISTS)) continue; if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue; - - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(seeingthing); - fixed_t ff_top=rover->top.plane->ZatPoint(seeingthing); - if (lastztop<=ff_bottom && topz>ff_bottom && lastzbottom<=ff_bottom && bottomz>ff_bottom) return false; - if (lastzbottom>=ff_top && bottomz=ff_top && topzbottom.plane->ZatPoint(seeingthing); + double ff_top = rover->top.plane->ZatPoint(seeingthing); + + if (Lastztop <= ff_bottom && topz > ff_bottom && Lastzbottom <= ff_bottom && bottomz > ff_bottom) return false; + if (Lastzbottom >= ff_top && bottomz < ff_top && Lastztop >= ff_top && topz < ff_top) return false; } - } return true; // everything was traversed } @@ -592,40 +585,37 @@ bool SightCheck::P_SightTraverseIntercepts () bool SightCheck::P_SightPathTraverse () { - fixed_t x1, x2, y1, y2; - fixed_t xt1,yt1,xt2,yt2; - long long _x1,_y1,_x2,_y2; - fixed_t xstep,ystep; - fixed_t partialx, partialy; - fixed_t xintercept, yintercept; + double x1, x2, y1, y2; + double xt1,yt1,xt2,yt2; + double xstep,ystep; + double partialx, partialy; + double xintercept, yintercept; int mapx, mapy, mapxstep, mapystep; int count; validcount++; intercepts.Clear (); - x1 = sightstart.x + FixedMul(startfrac, trace.dx); - y1 = sightstart.y + FixedMul(startfrac, trace.dy); - x2 = sightend.x; - y2 = sightend.y; + x1 = sightstart.X + Startfrac * Trace.dx; + y1 = sightstart.Y + Startfrac * Trace.dy; + x2 = sightend.X; + y2 = sightend.Y; if (lastsector == NULL) lastsector = P_PointInSector(x1, y1); // for FF_SEETHROUGH the following rule applies: // If the viewer is in an area without FF_SEETHROUGH he can only see into areas without this flag // If the viewer is in an area with FF_SEETHROUGH he can only see into areas with this flag bool checkfloor = true, checkceiling = true; - for(unsigned int i=0;ie->XFloor.ffloors.Size();i++) + for(auto rover : lastsector->e->XFloor.ffloors) { - F3DFloor* rover = lastsector->e->XFloor.ffloors[i]; - if(!(rover->flags & FF_EXISTS)) continue; - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(sightstart); - fixed_t ff_top=rover->top.plane->ZatPoint(sightstart); + double ff_bottom=rover->bottom.plane->ZatPoint(sightstart); + double ff_top=rover->top.plane->ZatPoint(sightstart); - if (sightstart.z < ff_top) checkceiling = false; - if (sightstart.z >= ff_bottom) checkfloor = false; + if (sightstart.Z < ff_top) checkceiling = false; + if (sightstart.Z >= ff_bottom) checkfloor = false; - if (sightstart.z < ff_top && sightstart.z >= ff_bottom) + if (sightstart.Z < ff_top && sightstart.Z >= ff_bottom) { myseethrough = rover->flags & FF_SEETHROUGH; break; @@ -642,94 +632,88 @@ bool SightCheck::P_SightPathTraverse () portals.Push({ 0, topslope, bottomslope, sector_t::floor, lastsector->SkyBoxes[sector_t::floor]->Sector->PortalGroup }); } - if ( ((x1-bmaporgx)&(MAPBLOCKSIZE-1)) == 0) - x1 += FRACUNIT; // don't side exactly on a line - if ( ((y1-bmaporgy)&(MAPBLOCKSIZE-1)) == 0) - y1 += FRACUNIT; // don't side exactly on a line - - _x1 = (long long)x1 - bmaporgx; - _y1 = (long long)y1 - bmaporgy; x1 -= bmaporgx; y1 -= bmaporgy; - xt1 = int(_x1 >> MAPBLOCKSHIFT); - yt1 = int(_y1 >> MAPBLOCKSHIFT); + xt1 = x1 / MAPBLOCKUNITS; + yt1 = y1 / MAPBLOCKUNITS; - _x2 = (long long)x2 - bmaporgx; - _y2 = (long long)y2 - bmaporgy; x2 -= bmaporgx; y2 -= bmaporgy; - xt2 = int(_x2 >> MAPBLOCKSHIFT); - yt2 = int(_y2 >> MAPBLOCKSHIFT); + xt2 = x2 / MAPBLOCKUNITS; + yt2 = y2 / MAPBLOCKUNITS; - if (xt2 > xt1) + mapx = xs_FloorToInt(xt1); + mapy = xs_FloorToInt(yt1); + int mapex = xs_FloorToInt(xt2); + int mapey = xs_FloorToInt(yt2); + + + if (mapex > mapx) { mapxstep = 1; - partialx = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1)); - ystep = FixedDiv (y2-y1,abs(x2-x1)); + partialx = xs_CeilToInt(xt1) - xt1; + ystep = (y2 - y1) / fabs(x2 - x1); } - else if (xt2 < xt1) + else if (mapex < mapx) { mapxstep = -1; - partialx = (x1>>MAPBTOFRAC)&(FRACUNIT-1); - ystep = FixedDiv (y2-y1,abs(x2-x1)); + partialx = xt1 - xs_FloorToInt(xt1); + ystep = (y2 - y1) / fabs(x2 - x1); } else { mapxstep = 0; - partialx = FRACUNIT; - ystep = 256*FRACUNIT; + partialx = 1.; + ystep = 256; } - yintercept = int(_y1>>MAPBTOFRAC) + FixedMul (partialx, ystep); + yintercept = yt1 + partialx * ystep; - - if (yt2 > yt1) + if (mapey > mapy) { mapystep = 1; - partialy = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1)); - xstep = FixedDiv (x2-x1,abs(y2-y1)); + partialy = xs_CeilToInt(yt1) - yt1; + xstep = (x2 - x1) / fabs(y2 - y1); } - else if (yt2 < yt1) + else if (mapey < mapy) { mapystep = -1; - partialy = (y1>>MAPBTOFRAC)&(FRACUNIT-1); - xstep = FixedDiv (x2-x1,abs(y2-y1)); + partialy = yt1 - xs_FloorToInt(yt1); + xstep = (x2 - x1) / fabs(y2 - y1); } else { mapystep = 0; - partialy = FRACUNIT; - xstep = 256*FRACUNIT; + partialy = 1; + 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, // xintercept and yintercept can both be set ahead of mapx and mapy, so the // for loop would never advance anywhere. - if (abs(xstep) == FRACUNIT && abs(ystep) == FRACUNIT) + if (fabs(xstep) == 1. && fabs(ystep) == 1.) { if (ystep < 0) { - partialx = FRACUNIT - partialx; + partialx = 1. - partialx; } if (xstep < 0) { - partialy = FRACUNIT - partialy; + partialy = 1. - partialy; } if (partialx == partialy) { - xintercept = xt1 << FRACBITS; - yintercept = yt1 << FRACBITS; + xintercept = xt1; + yintercept = yt1; } } // // step through map blocks // Count is present to prevent a round off error from skipping the break - mapx = xt1; - mapy = yt1; - for (count = 0 ; count < 100 ; count++) + for (count = 0 ; count < 1000 ; count++) { // end traversing when reaching the end of the blockmap // an early out is not possible because with portals a trace can easily land outside the map's bounds. @@ -748,25 +732,25 @@ bool SightCheck::P_SightPathTraverse () if (res == -1 || (mapxstep | mapystep) == 0) break; - switch ((((yintercept >> FRACBITS) == mapy) << 1) | ((xintercept >> FRACBITS) == mapx)) + switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx)) { case 0: // neither xintercept nor yintercept match! sightcounts[5]++; // Continuing won't make things any better, so we might as well stop right here - count = 100; + count = 1000; break; case 1: // xintercept matches xintercept += xstep; mapy += mapystep; - if (mapy == yt2) + if (mapy == mapey) mapystep = 0; break; case 2: // yintercept matches yintercept += ystep; mapx += mapxstep; - if (mapx == xt2) + if (mapx == mapex) mapxstep = 0; break; @@ -786,9 +770,9 @@ sightcounts[1]++; yintercept += ystep; mapx += mapxstep; mapy += mapystep; - if (mapx == xt2) + if (mapx == mapex) mapxstep = 0; - if (mapy == yt2) + if (mapy == mapey) mapystep = 0; break; } @@ -849,7 +833,7 @@ sightcounts[0]++; // // [RH] Andy Baker's stealth monsters: // Cannot see an invisible object - if ((flags & SF_IGNOREVISIBILITY) == 0 && ((t2->renderflags & RF_INVISIBLE) || !t2->RenderStyle.IsVisible(t2->alpha))) + if ((flags & SF_IGNOREVISIBILITY) == 0 && ((t2->renderflags & RF_INVISIBLE) || !t2->RenderStyle.IsVisible(t2->Alpha))) { // small chance of an attack being made anyway if ((bglobal.m_Thinking ? pr_botchecksight() : pr_checksight()) > 50) { @@ -863,16 +847,16 @@ sightcounts[0]++; if (!(flags & SF_IGNOREWATERBOUNDARY)) { if ((s1->GetHeightSec() && - ((t1->Z() + t1->height <= s1->heightsec->floorplane.ZatPoint(t1) && + ((t1->Top() <= s1->heightsec->floorplane.ZatPoint(t1) && t2->Z() >= s1->heightsec->floorplane.ZatPoint(t2)) || (t1->Z() >= s1->heightsec->ceilingplane.ZatPoint(t1) && - t2->Z() + t1->height <= s1->heightsec->ceilingplane.ZatPoint(t2)))) + t2->Top() <= s1->heightsec->ceilingplane.ZatPoint(t2)))) || (s2->GetHeightSec() && - ((t2->Z() + t2->height <= s2->heightsec->floorplane.ZatPoint(t2) && + ((t2->Top() <= s2->heightsec->floorplane.ZatPoint(t2) && t1->Z() >= s2->heightsec->floorplane.ZatPoint(t1)) || (t2->Z() >= s2->heightsec->ceilingplane.ZatPoint(t2) && - t1->Z() + t2->height <= s2->heightsec->ceilingplane.ZatPoint(t1))))) + t1->Top() <= s2->heightsec->ceilingplane.ZatPoint(t1))))) { res = false; goto done; @@ -886,11 +870,11 @@ sightcounts[0]++; portals.Clear(); { sector_t *sec; - fixed_t lookheight = t1->height - (t1->height >> 2); + double lookheight = t1->Center(); t1->GetPortalTransition(lookheight, &sec); - fixed_t bottomslope = t2->Z() - (t1->Z() + lookheight); - fixed_t topslope = bottomslope + t2->height; + double bottomslope = t2->Z() - lookheight; + double topslope = bottomslope + t2->Height; SightTask task = { 0, topslope, bottomslope, -1, sec->PortalGroup }; @@ -899,10 +883,10 @@ sightcounts[0]++; res = s.P_SightPathTraverse (); if (!res) { - fixed_t dist = t1->AproxDistance(t2); + double dist = t1->Distance2D(t2); for (unsigned i = 0; i < portals.Size(); i++) { - portals[i].frac += FixedDiv(FRACUNIT, dist); + portals[i].Frac += 1 / dist; s.init(t1, t2, NULL, &portals[i], flags); if (s.P_SightPathTraverse()) { @@ -940,5 +924,3 @@ void P_ResetSightCounters (bool full) SightCycles.Reset(); memset (sightcounts, 0, sizeof(sightcounts)); } - - diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 97cf2fb57..1ee992d5e 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -45,7 +45,7 @@ // //=========================================================================== -static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, bool slopeCeil) +static void P_SlopeLineToPoint (int lineid, const DVector3 &pos, bool slopeCeil) { int linenum; @@ -56,7 +56,7 @@ static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, boo sector_t *sec; secplane_t *plane; - if (P_PointOnLineSidePrecise (x, y, line) == 0) + if (P_PointOnLineSidePrecise (pos, line) == 0) { sec = line->frontsector; } @@ -79,21 +79,21 @@ static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, boo DVector3 p, v1, v2, cross; - p[0] = FIXED2DBL (line->v1->x); - p[1] = FIXED2DBL (line->v1->y); - p[2] = FIXED2DBL (plane->ZatPoint (line->v1->x, line->v1->y)); - v1[0] = FIXED2DBL (line->dx); - v1[1] = FIXED2DBL (line->dy); - v1[2] = FIXED2DBL (plane->ZatPoint (line->v2->x, line->v2->y)) - p[2]; - v2[0] = FIXED2DBL (x - line->v1->x); - v2[1] = FIXED2DBL (y - line->v1->y); - v2[2] = FIXED2DBL (z) - p[2]; + p[0] = line->v1->fX(); + p[1] = line->v1->fY(); + p[2] = plane->ZatPoint (line->v1); + v1[0] = line->Delta().X; + v1[1] = line->Delta().Y; + v1[2] = plane->ZatPoint (line->v2) - p[2]; + v2[0] = pos.X - p[0]; + v2[1] = pos.Y - p[1]; + v2[2] = pos.Z - p[2]; cross = v1 ^ v2; double len = cross.Length(); if (len == 0) { - Printf ("Slope thing at (%d,%d) lies directly on its target line.\n", int(x>>16), int(y>>16)); + Printf ("Slope thing at (%f,%f) lies directly on its target line.\n", pos.X, pos.Y); return; } cross /= len; @@ -103,14 +103,8 @@ static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, boo cross = -cross; } - plane->a = FLOAT2FIXED (cross[0]); - plane->b = FLOAT2FIXED (cross[1]); - plane->c = FLOAT2FIXED (cross[2]); - //plane->ic = FLOAT2FIXED (1.f/cross[2]); - plane->ic = DivScale32 (1, plane->c); - plane->d = -TMulScale16 (plane->a, x, - plane->b, y, - plane->c, z); + double dist = -cross[0] * pos.X - cross[1] * pos.Y - cross[2] * pos.Z; + plane->set(cross[0], cross[1], cross[2], dist); } } @@ -124,7 +118,6 @@ static void P_CopyPlane (int tag, sector_t *dest, bool copyCeil) { sector_t *source; int secnum; - size_t planeofs; secnum = P_FindFirstSectorFromTag (tag); if (secnum == -1) @@ -136,18 +129,17 @@ static void P_CopyPlane (int tag, sector_t *dest, bool copyCeil) if (copyCeil) { - planeofs = myoffsetof(sector_t, ceilingplane); + dest->ceilingplane = source->ceilingplane; } else { - planeofs = myoffsetof(sector_t, floorplane); + dest->floorplane = source->floorplane; } - *(secplane_t *)((BYTE *)dest + planeofs) = *(secplane_t *)((BYTE *)source + planeofs); } -static void P_CopyPlane (int tag, fixed_t x, fixed_t y, bool copyCeil) +static void P_CopyPlane (int tag, const DVector2 &pos, bool copyCeil) { - sector_t *dest = P_PointInSector (x, y); + sector_t *dest = P_PointInSector (pos); P_CopyPlane(tag, dest, copyCeil); } @@ -157,60 +149,47 @@ static void P_CopyPlane (int tag, fixed_t x, fixed_t y, bool copyCeil) // //=========================================================================== -void P_SetSlope (secplane_t *plane, bool setCeil, int xyangi, int zangi, - fixed_t x, fixed_t y, fixed_t z) +void P_SetSlope (secplane_t *plane, bool setCeil, int xyangi, int zangi, const DVector3 &pos) { - angle_t xyang; - angle_t zang; + DAngle xyang; + DAngle zang; if (zangi >= 180) { - zang = ANGLE_180-ANGLE_1; + zang = 179.; } else if (zangi <= 0) { - zang = ANGLE_1; + zang = 1.; } else { - zang = Scale (zangi, ANGLE_90, 90); + zang = (double)zangi; } if (setCeil) { - zang += ANGLE_180; + zang += 180.; } - zang >>= ANGLETOFINESHIFT; - // Sanitize xyangi to [0,360) range - xyangi = xyangi % 360; - if (xyangi < 0) - { - xyangi = 360 + xyangi; - } - xyang = (angle_t)Scale (xyangi, ANGLE_90, 90 << ANGLETOFINESHIFT); + xyang = (double)xyangi; DVector3 norm; if (ib_compatflags & BCOMPATF_SETSLOPEOVERFLOW) { - norm[0] = double(finecosine[zang] * finecosine[xyang]); - norm[1] = double(finecosine[zang] * finesine[xyang]); + // We have to consider an integer multiplication overflow here. + norm[0] = FixedToFloat(FloatToFixed(zang.Cos()) * FloatToFixed(xyang.Cos())); + norm[1] = FixedToFloat(FloatToFixed(zang.Cos()) * FloatToFixed(xyang.Sin())); } else { - norm[0] = double(finecosine[zang]) * double(finecosine[xyang]); - norm[1] = double(finecosine[zang]) * double(finesine[xyang]); + norm[0] = zang.Cos() * xyang.Cos(); + norm[1] = zang.Cos() * xyang.Sin(); } - norm[2] = double(finesine[zang]) * 65536.f; + norm[2] = zang.Sin(); norm.MakeUnit(); - plane->a = FLOAT2FIXED(norm[0]); - plane->b = FLOAT2FIXED(norm[1]); - plane->c = FLOAT2FIXED(norm[2]); - //plane->ic = (int)(65536.f / norm[2]); - plane->ic = DivScale32 (1, plane->c); - plane->d = -TMulScale16 (plane->a, x, - plane->b, y, - plane->c, z); + double dist = -norm[0] * pos.X - norm[1] * pos.Y - norm[2] * pos.Z; + plane->set(norm[0], norm[1], norm[2], dist); } @@ -220,7 +199,7 @@ void P_SetSlope (secplane_t *plane, bool setCeil, int xyangi, int zangi, // //=========================================================================== -void P_VavoomSlope(sector_t * sec, int id, fixed_t x, fixed_t y, fixed_t z, int which) +void P_VavoomSlope(sector_t * sec, int id, const DVector3 &pos, int which) { for (int i=0;ilinecount;i++) { @@ -230,21 +209,21 @@ void P_VavoomSlope(sector_t * sec, int id, fixed_t x, fixed_t y, fixed_t z, int { DVector3 v1, v2, cross; secplane_t *srcplane = (which == 0) ? &sec->floorplane : &sec->ceilingplane; - fixed_t srcheight = (which == 0) ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); + double srcheight = (which == 0) ? sec->GetPlaneTexZF(sector_t::floor) : sec->GetPlaneTexZF(sector_t::ceiling); - v1[0] = FIXED2DBL (x - l->v2->x); - v1[1] = FIXED2DBL (y - l->v2->y); - v1[2] = FIXED2DBL (z - srcheight); + v1[0] = pos.X - l->v2->fX(); + v1[1] = pos.Y - l->v2->fY(); + v1[2] = pos.Z - srcheight; - v2[0] = FIXED2DBL (x - l->v1->x); - v2[1] = FIXED2DBL (y - l->v1->y); - v2[2] = FIXED2DBL (z - srcheight); + v2[0] = pos.X - l->v1->fX(); + v2[1] = pos.Y - l->v1->fY(); + v2[2] = pos.Z - srcheight; cross = v1 ^ v2; double len = cross.Length(); if (len == 0) { - Printf ("Slope thing at (%d,%d) lies directly on its target line.\n", int(x>>16), int(y>>16)); + Printf ("Slope thing at (%f,%f) lies directly on its target line.\n", pos.X, pos.Y); return; } cross /= len; @@ -255,15 +234,8 @@ void P_VavoomSlope(sector_t * sec, int id, fixed_t x, fixed_t y, fixed_t z, int cross = -cross; } - - srcplane->a = FLOAT2FIXED (cross[0]); - srcplane->b = FLOAT2FIXED (cross[1]); - srcplane->c = FLOAT2FIXED (cross[2]); - //plane->ic = FLOAT2FIXED (1.f/cross[2]); - srcplane->ic = DivScale32 (1, srcplane->c); - srcplane->d = -TMulScale16 (srcplane->a, x, - srcplane->b, y, - srcplane->c, z); + double dist = -cross[0] * pos.X - cross[1] * pos.Y - cross[2] * pos.Z; + srcplane->set(cross[0], cross[1], cross[2], dist); return; } } @@ -277,7 +249,7 @@ void P_VavoomSlope(sector_t * sec, int id, fixed_t x, fixed_t y, fixed_t z, int static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, const int *oldvertextable) { - TMap vt_heights[2]; + TMap vt_heights[2]; FMapThing *mt; bool vt_found = false; @@ -289,15 +261,15 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, { for (int i = 0; i < numvertexes; i++) { - if (vertexes[i].x == mt->x && vertexes[i].y == mt->y) + if (vertexes[i].fX() == mt->pos.X && vertexes[i].fY() == mt->pos.Y) { if (mt->info->Special == SMT_VertexFloorZ) { - vt_heights[0][i] = mt->z; + vt_heights[0][i] = mt->pos.Z; } else { - vt_heights[1][i] = mt->z; + vt_heights[1][i] = mt->pos.Z; } vt_found = true; } @@ -345,27 +317,22 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)? int(sec->lines[1]->v2 - vertexes) : int(sec->lines[1]->v1 - vertexes); - vt1.X = FIXED2DBL(vertexes[vi1].x); - vt1.Y = FIXED2DBL(vertexes[vi1].y); - vt2.X = FIXED2DBL(vertexes[vi2].x); - vt2.Y = FIXED2DBL(vertexes[vi2].y); - vt3.X = FIXED2DBL(vertexes[vi3].x); - vt3.Y = FIXED2DBL(vertexes[vi3].y); + vt1 = DVector3(vertexes[vi1].fPos(), 0); + vt2 = DVector3(vertexes[vi2].fPos(), 0); + vt3 = DVector3(vertexes[vi3].fPos(), 0); for(int j=0; j<2; j++) { - fixed_t *h1 = vt_heights[j].CheckKey(vi1); - fixed_t *h2 = vt_heights[j].CheckKey(vi2); - fixed_t *h3 = vt_heights[j].CheckKey(vi3); - fixed_t z3; - if (h1==NULL && h2==NULL && h3==NULL) continue; + double *h1 = vt_heights[j].CheckKey(vi1); + double *h2 = vt_heights[j].CheckKey(vi2); + double *h3 = vt_heights[j].CheckKey(vi3); + if (h1 == NULL && h2 == NULL && h3 == NULL) continue; - vt1.Z = FIXED2DBL(h1? *h1 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling)); - vt2.Z = FIXED2DBL(h2? *h2 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling)); - z3 = h3? *h3 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); - vt3.Z = FIXED2DBL(z3); + vt1.Z = h1? *h1 : j==0? sec->GetPlaneTexZF(sector_t::floor) : sec->GetPlaneTexZF(sector_t::ceiling); + vt2.Z = h2? *h2 : j==0? sec->GetPlaneTexZF(sector_t::floor) : sec->GetPlaneTexZF(sector_t::ceiling); + vt3.Z = h3? *h3 : j==0? sec->GetPlaneTexZF(sector_t::floor) : sec->GetPlaneTexZF(sector_t::ceiling); - if (P_PointOnLineSidePrecise(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0) + if (P_PointOnLineSidePrecise(vertexes[vi3].fX(), vertexes[vi3].fY(), sec->lines[0]) == 0) { vec1 = vt2 - vt3; vec2 = vt1 - vt3; @@ -393,15 +360,10 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, cross = -cross; } - secplane_t *srcplane = j==0? &sec->floorplane : &sec->ceilingplane; + secplane_t *plane = j==0? &sec->floorplane : &sec->ceilingplane; - srcplane->a = FLOAT2FIXED (cross[0]); - srcplane->b = FLOAT2FIXED (cross[1]); - srcplane->c = FLOAT2FIXED (cross[2]); - srcplane->ic = DivScale32 (1, srcplane->c); - srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x, - srcplane->b, vertexes[vi3].y, - srcplane->c, z3); + double dist = -cross[0] * vertexes[vi3].fX() - cross[1] * vertexes[vi3].fY() - cross[2] * vt3.Z; + plane->set(cross[0], cross[1], cross[2], dist); } } } @@ -422,14 +384,12 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve if (mt->info != NULL && mt->info->Type == NULL && (mt->info->Special >= SMT_SlopeFloorPointLine && mt->info->Special <= SMT_VavoomCeiling)) { - fixed_t x, y, z; + DVector3 pos = mt->pos; secplane_t *refplane; sector_t *sec; bool ceiling; - x = mt->x; - y = mt->y; - sec = P_PointInSector (x, y); + sec = P_PointInSector (mt->pos); if (mt->info->Special == SMT_SlopeCeilingPointLine || mt->info->Special == SMT_VavoomCeiling || mt->info->Special == SMT_SetCeilingSlope) { refplane = &sec->ceilingplane; @@ -440,18 +400,19 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve refplane = &sec->floorplane; ceiling = false; } - z = refplane->ZatPoint (x, y) + (mt->z); + pos.Z = refplane->ZatPoint (mt->pos) + mt->pos.Z; + if (mt->info->Special <= SMT_SlopeCeilingPointLine) { // SlopeFloorPointLine and SlopCeilingPointLine - P_SlopeLineToPoint (mt->args[0], x, y, z, ceiling); + P_SlopeLineToPoint (mt->args[0], pos, ceiling); } else if (mt->info->Special <= SMT_SetCeilingSlope) { // SetFloorSlope and SetCeilingSlope - P_SetSlope (refplane, ceiling, mt->angle, mt->args[0], x, y, z); + P_SetSlope (refplane, ceiling, mt->angle, mt->args[0], pos); } else - { // VavoomFloor and VavoomCeiling - P_VavoomSlope(sec, mt->thingid, x, y, mt->z, ceiling); + { // VavoomFloor and VavoomCeiling (these do not perform any sector height adjustment - z is absolute) + P_VavoomSlope(sec, mt->thingid, mt->pos, ceiling); } mt->EdNum = 0; } @@ -462,7 +423,7 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve if (mt->info != NULL && mt->info->Type == NULL && (mt->info->Special == SMT_CopyFloorPlane || mt->info->Special == SMT_CopyCeilingPlane)) { - P_CopyPlane (mt->args[0], mt->x, mt->y, mt->info->Special == SMT_CopyCeilingPlane); + P_CopyPlane (mt->args[0], mt->pos, mt->info->Special == SMT_CopyCeilingPlane); mt->EdNum = 0; } } @@ -486,7 +447,7 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve // //=========================================================================== -static void P_AlignPlane (sector_t *sec, line_t *line, int which) +static void P_AlignPlane(sector_t *sec, line_t *line, int which) { sector_t *refsec; double bestdist; @@ -500,7 +461,7 @@ static void P_AlignPlane (sector_t *sec, line_t *line, int which) // Find furthest vertex from the reference line. It, along with the two ends // of the line, will define the plane. bestdist = 0; - for (i = sec->linecount*2, probe = sec->lines; i > 0; i--) + for (i = sec->linecount * 2, probe = sec->lines; i > 0; i--) { double dist; vertex_t *vert; @@ -509,8 +470,8 @@ static void P_AlignPlane (sector_t *sec, line_t *line, int which) vert = (*probe++)->v2; else vert = (*probe)->v1; - dist = fabs((double(line->v1->y) - vert->y) * line->dx - - (double(line->v1->x) - vert->x) * line->dy); + dist = fabs((line->v1->fY() - vert->fY()) * line->Delta().X - + (line->v1->fX() - vert->fX()) * line->Delta().Y); if (dist > bestdist) { @@ -524,21 +485,21 @@ static void P_AlignPlane (sector_t *sec, line_t *line, int which) DVector3 p, v1, v2, cross; secplane_t *srcplane; - fixed_t srcheight, destheight; + double srcheight, destheight; srcplane = (which == 0) ? &sec->floorplane : &sec->ceilingplane; - srcheight = (which == 0) ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); - destheight = (which == 0) ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); + srcheight = (which == 0) ? sec->GetPlaneTexZF(sector_t::floor) : sec->GetPlaneTexZF(sector_t::ceiling); + destheight = (which == 0) ? refsec->GetPlaneTexZF(sector_t::floor) : refsec->GetPlaneTexZF(sector_t::ceiling); - p[0] = FIXED2DBL (line->v1->x); - p[1] = FIXED2DBL(line->v1->y); - p[2] = FIXED2DBL(destheight); - v1[0] = FIXED2DBL(line->dx); - v1[1] = FIXED2DBL(line->dy); + p[0] = line->v1->fX(); + p[1] = line->v1->fY(); + p[2] = destheight; + v1[0] = line->Delta().X; + v1[1] = line->Delta().Y; v1[2] = 0; - v2[0] = FIXED2DBL(refvert->x - line->v1->x); - v2[1] = FIXED2DBL(refvert->y - line->v1->y); - v2[2] = FIXED2DBL(srcheight - destheight); + v2[0] = refvert->fX() - line->v1->fX(); + v2[1] = refvert->fY() - line->v1->fY(); + v2[2] = srcheight - destheight; cross = (v1 ^ v2).Unit(); @@ -548,14 +509,8 @@ static void P_AlignPlane (sector_t *sec, line_t *line, int which) cross = -cross; } - srcplane->a = FLOAT2FIXED (cross[0]); - srcplane->b = FLOAT2FIXED (cross[1]); - srcplane->c = FLOAT2FIXED (cross[2]); - //srcplane->ic = FLOAT2FIXED (1.f/cross[2]); - srcplane->ic = DivScale32 (1, srcplane->c); - srcplane->d = -TMulScale16 (srcplane->a, line->v1->x, - srcplane->b, line->v1->y, - srcplane->c, destheight); + double dist = -cross[0] * line->v1->fX() - cross[1] * line->v1->fY() - cross[2] * destheight; + srcplane->set(cross[0], cross[1], cross[2], dist); } //=========================================================================== @@ -644,4 +599,3 @@ void P_CopySlopes() } } } - diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 834df5956..c39b3ba69 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -138,7 +138,7 @@ bool CheckIfExitIsGood (AActor *self, level_info_t *info) // //============================================================================ -bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, fixedvec3 *optpos) +bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, DVector3 *optpos) { int lineActivation; INTBOOL repeat; @@ -199,7 +199,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, fix // //============================================================================ -bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType, fixedvec3 *optpos) +bool P_TestActivateLine (line_t *line, AActor *mo, int side, int activationType, DVector3 *optpos) { int lineActivation = line->activation; @@ -376,7 +376,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) { // Falling, not all the way down yet? sector = player->mo->Sector; - if (player->mo->Z() != sector->LowestFloorAt(player->mo) + if (!player->mo->isAtZ(sector->LowestFloorAt(player->mo)) && !player->mo->waterlevel) { return; @@ -416,7 +416,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) } if (sector->Flags & SECF_DMGTERRAINFX) { - P_HitWater(player->mo, player->mo->Sector, INT_MIN, INT_MIN, INT_MIN, false, true, true); + P_HitWater(player->mo, player->mo->Sector, player->mo->Pos(), false, true, true); } } } @@ -453,7 +453,7 @@ static void DoSectorDamage(AActor *actor, sector_t *sec, int amount, FName type, if (!(flags & DAMAGE_PLAYERS) && actor->player != NULL) return; - if (!(flags & DAMAGE_IN_AIR) && actor->Z() != sec->floorplane.ZatPoint(actor) && !actor->waterlevel) + if (!(flags & DAMAGE_IN_AIR) && !actor->isAtZ(sec->floorplane.ZatPoint(actor)) && !actor->waterlevel) return; if (protectClass != NULL) @@ -490,21 +490,21 @@ void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, { next = actor->snext; // Only affect actors touching the 3D floor - fixed_t z1 = sec->floorplane.ZatPoint(actor); - fixed_t z2 = sec->ceilingplane.ZatPoint(actor); + double z1 = sec->floorplane.ZatPoint(actor); + double z2 = sec->ceilingplane.ZatPoint(actor); if (z2 < z1) { // Account for Vavoom-style 3D floors - fixed_t zz = z1; + double zz = z1; z1 = z2; z2 = zz; } - if (actor->Z() + actor->height > z1) + if (actor->Top() > z1) { // If DAMAGE_IN_AIR is used, anything not beneath the 3D floor will be // damaged (so, anything touching it or above it). Other 3D floors between // the actor and this one will not stop this effect. - if ((flags & DAMAGE_IN_AIR) || actor->Z() <= z2) + if ((flags & DAMAGE_IN_AIR) || !actor->isAbove(z2)) { // Here we pass the DAMAGE_IN_AIR flag to disable the floor check, since it // only works with the real sector's floor. We did the appropriate height checks @@ -665,16 +665,7 @@ IMPLEMENT_CLASS (DLightTransfer) void DLightTransfer::Serialize (FArchive &arc) { Super::Serialize (arc); - if (SaveVersion < 3223) - { - BYTE bytelight; - arc << bytelight; - LastLight = bytelight; - } - else - { - arc << LastLight; - } + arc << LastLight; arc << Source << TargetTag << CopyFloor; } @@ -762,16 +753,7 @@ IMPLEMENT_CLASS (DWallLightTransfer) void DWallLightTransfer::Serialize (FArchive &arc) { Super::Serialize (arc); - if (SaveVersion < 3223) - { - BYTE bytelight; - arc << bytelight; - LastLight = bytelight; - } - else - { - arc << LastLight; - } + arc << LastLight; arc << Source << TargetID << Flags; } @@ -860,8 +842,8 @@ static void SetupFloorPortal (AStackPoint *point) if (skyv != NULL && skyv->bAlways) { skyv->Mate = point; - if (Sector->GetAlpha(sector_t::floor) == OPAQUE) - Sector->SetAlpha(sector_t::floor, Scale (point->args[0], OPAQUE, 255)); + if (Sector->GetAlphaF(sector_t::floor) == 1.) + Sector->SetAlpha(sector_t::floor, clamp(point->args[0], 0, 255) / 255.); } } @@ -874,8 +856,8 @@ static void SetupCeilingPortal (AStackPoint *point) if (skyv != NULL && skyv->bAlways) { skyv->Mate = point; - if (Sector->GetAlpha(sector_t::ceiling) == OPAQUE) - Sector->SetAlpha(sector_t::ceiling, Scale(point->args[0], OPAQUE, 255)); + if (Sector->GetAlphaF(sector_t::ceiling) == 1.) + Sector->SetAlpha(sector_t::ceiling, clamp(point->args[0], 0, 255) / 255.); } } @@ -901,7 +883,7 @@ void P_SetupPortals() } } -static void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, fixed_t alpha) +static void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, double alpha) { // plane: 0=floor, 1=ceiling, 2=both if (plane > 0) @@ -909,7 +891,7 @@ static void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, fixed_ if (sector->SkyBoxes[sector_t::ceiling] == NULL || !barrier_cast(sector->SkyBoxes[sector_t::ceiling])->bAlways) { sector->SkyBoxes[sector_t::ceiling] = portal; - if (sector->GetAlpha(sector_t::ceiling) == OPAQUE) + if (sector->GetAlphaF(sector_t::ceiling) == 1.) sector->SetAlpha(sector_t::ceiling, alpha); if (!portal->bAlways) sector->SetTexture(sector_t::ceiling, skyflatnum); @@ -921,14 +903,14 @@ static void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, fixed_ { sector->SkyBoxes[sector_t::floor] = portal; } - if (sector->GetAlpha(sector_t::floor) == OPAQUE) + if (sector->GetAlphaF(sector_t::floor) == 1.) sector->SetAlpha(sector_t::floor, alpha); if (!portal->bAlways) sector->SetTexture(sector_t::floor, skyflatnum); } } -static void CopyPortal(int sectortag, int plane, ASkyViewpoint *origin, fixed_t alpha, bool tolines) +static void CopyPortal(int sectortag, int plane, ASkyViewpoint *origin, double alpha, bool tolines) { int s; FSectorTagIterator itr(sectortag); @@ -962,7 +944,7 @@ static void CopyPortal(int sectortag, int plane, ASkyViewpoint *origin, fixed_t } } -void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha, int linked) +void P_SpawnPortal(line_t *line, int sectortag, int plane, int bytealpha, int linked) { if (plane < 0 || plane > 2 || (linked && plane == 2)) return; for (int i=0;iv1->x) + SQWORD(line->v2->x)) >> 1); - fixed_t y1 = fixed_t((SQWORD(line->v1->y) + SQWORD(line->v2->y)) >> 1); - fixed_t x2 = fixed_t((SQWORD(lines[i].v1->x) + SQWORD(lines[i].v2->x)) >> 1); - fixed_t y2 = fixed_t((SQWORD(lines[i].v1->y) + SQWORD(lines[i].v2->y)) >> 1); - fixed_t z = linked ? line->frontsector->planes[plane].TexZ : 0; // the map's sector height defines the portal plane for linked portals + DVector3 pos1((line->v1->fX() + line->v2->fX()) / 2, (line->v1->fY() + line->v2->fY()) / 2, 0); + DVector3 pos2((lines[i].v1->fX() + lines[i].v2->fX()) / 2, (lines[i].v1->fY() + lines[i].v2->fY()) / 2, 0); + double z = linked ? line->frontsector->GetPlaneTexZF(plane) : 0; // the map's sector height defines the portal plane for linked portals - fixed_t alpha = Scale (lines[i].args[4], OPAQUE, 255); + double alpha = bytealpha / 255.; - AStackPoint *anchor = Spawn(x1, y1, 0, NO_REPLACE); - AStackPoint *reference = Spawn(x2, y2, 0, NO_REPLACE); + AStackPoint *anchor = Spawn(pos1, NO_REPLACE); + AStackPoint *reference = Spawn(pos2, NO_REPLACE); reference->special1 = linked ? SKYBOX_LINKEDPORTAL : SKYBOX_PORTAL; anchor->special1 = SKYBOX_ANCHOR; // store the portal displacement in the unused scaleX/Y members of the portal reference actor. - anchor->scaleX = -(reference->scaleX = x2 - x1); - anchor->scaleY = -(reference->scaleY = y2 - y1); - anchor->threshold = reference->threshold = z; + anchor->Scale = -(reference->Scale = pos2 - pos1); + anchor->specialf1 = reference->specialf1 = z; reference->Mate = anchor; anchor->Mate = reference; @@ -1015,7 +994,7 @@ void P_SpawnSkybox(ASkyViewpoint *origin) if (Sector == NULL) { Printf("Sector not initialized for SkyCamCompat\n"); - origin->Sector = Sector = P_PointInSector(origin->X(), origin->Y()); + origin->Sector = Sector = P_PointInSector(origin->Pos()); } if (Sector) { @@ -1061,7 +1040,7 @@ static void P_SetupSectorDamage(sector_t *sector, int damage, int interval, int // ('fromload' is necessary to allow conversion upon savegame load.) // -void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) +void P_InitSectorSpecial(sector_t *sector, int special) { // [RH] All secret sectors are marked with a BOOM-ish bitfield if (sector->special & SECRET_MASK) @@ -1096,28 +1075,28 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) switch (sector->special) { case Light_Phased: - if (!nothinkers) new DPhased (sector, 48, 63 - (sector->lightlevel & 63)); + new DPhased (sector, 48, 63 - (sector->lightlevel & 63)); break; // [RH] Hexen-like phased lighting case LightSequenceStart: - if (!nothinkers) new DPhased (sector); + new DPhased (sector); break; case dLight_Flicker: - if (!nothinkers) new DLightFlash (sector); + new DLightFlash (sector); break; case dLight_StrobeFast: - if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); + new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); break; case dLight_StrobeSlow: - if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, SLOWDARK, false); + new DStrobe (sector, STROBEBRIGHT, SLOWDARK, false); break; case dLight_Strobe_Hurt: - if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); + new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); P_SetupSectorDamage(sector, 20, 32, 5, NAME_Slime, 0); break; @@ -1130,11 +1109,11 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) break; case dLight_Glow: - if (!nothinkers) new DGlow (sector); + new DGlow (sector); break; case dSector_DoorCloseIn30: - new DDoor(sector, DDoor::doorWaitClose, FRACUNIT * 2, 0, 0, 30 * TICRATE); + new DDoor(sector, DDoor::doorWaitClose, 2, 0, 0, 30 * TICRATE); break; case dDamage_End: @@ -1142,20 +1121,20 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) break; case dLight_StrobeSlowSync: - if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, SLOWDARK, true); + new DStrobe (sector, STROBEBRIGHT, SLOWDARK, true); break; case dLight_StrobeFastSync: - if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, true); + new DStrobe (sector, STROBEBRIGHT, FASTDARK, true); break; case dSector_DoorRaiseIn5Mins: - new DDoor (sector, DDoor::doorWaitRaise, 2*FRACUNIT, TICRATE*30/7, 0, 5*60*TICRATE); + new DDoor (sector, DDoor::doorWaitRaise, 2, TICRATE*30/7, 0, 5*60*TICRATE); break; case dFriction_Low: sector->friction = FRICTION_LOW; - sector->movefactor = 0x269; + sector->movefactor = 0x269/65536.; sector->Flags |= SECF_FRICTION; break; @@ -1164,7 +1143,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) break; case dLight_FireFlicker: - if (!nothinkers) new DFireFlicker (sector); + new DFireFlicker (sector); break; case dDamage_LavaWimpy: @@ -1177,12 +1156,8 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) case dScroll_EastLavaDamage: P_SetupSectorDamage(sector, 5, 32, 256, NAME_Fire, SECF_DMGTERRAINFX); - if (!nothinkers) - { - new DStrobe(sector, STROBEBRIGHT, FASTDARK, false); - P_CreateScroller(EScroll::sc_floor, -((FRACUNIT / 2) << 3), - 0, -1, int(sector - sectors), 0); - } + new DStrobe(sector, STROBEBRIGHT, FASTDARK, false); + P_CreateScroller(EScroll::sc_floor, -4., 0, -1, int(sector - sectors), 0); keepspecial = true; break; @@ -1192,7 +1167,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) case sLight_Strobe_Hurt: P_SetupSectorDamage(sector, 5, 32, 0, NAME_Slime, 0); - if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); + new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); break; case sDamage_Hellslime: @@ -1225,7 +1200,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) if (sector->special >= Scroll_North_Slow && sector->special <= Scroll_SouthWest_Fast) { // Hexen scroll special - static const char hexenScrollies[24][2] = + static const SBYTE hexenScrollies[24][2] = { { 0, 1 }, { 0, 2 }, { 0, 4 }, { -1, 0 }, { -2, 0 }, { -4, 0 }, @@ -1239,17 +1214,16 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) int i = sector->special - Scroll_North_Slow; - fixed_t dx = hexenScrollies[i][0] * (FRACUNIT/2); - fixed_t dy = hexenScrollies[i][1] * (FRACUNIT/2); - if (!nothinkers) P_CreateScroller(EScroll::sc_floor, dx, dy, -1, int(sector-sectors), 0); + double dx = hexenScrollies[i][0] / 2.; + double dy = hexenScrollies[i][1] / 2.; + P_CreateScroller(EScroll::sc_floor, dx, dy, -1, int(sector-sectors), 0); } else if (sector->special >= Carry_East5 && sector->special <= Carry_East35) { // Heretic scroll special // Only east scrollers also scroll the texture - if (!nothinkers) P_CreateScroller(EScroll::sc_floor, - (-FRACUNIT/2)<<(sector->special - Carry_East5), - 0, -1, int(sector-sectors), 0); + P_CreateScroller(EScroll::sc_floor, + -0.5 * (1 << ((sector->special & 0xff) - Carry_East5)), 0, -1, int(sector-sectors), 0); } keepspecial = true; break; @@ -1277,7 +1251,7 @@ void P_SpawnSpecials (void) if (sector->special == 0) continue; - P_InitSectorSpecial(sector, sector->special, false); + P_InitSectorSpecial(sector, sector->special); } #ifndef NO_EDATA @@ -1403,7 +1377,7 @@ void P_SpawnSpecials (void) { case Init_Gravity: { - float grav = ((float)P_AproxDistance (lines[i].dx, lines[i].dy)) / (FRACUNIT * 100.0f); + double grav = lines[i].Delta().Length() / 100.; FSectorTagIterator itr(lines[i].args[0]); while ((s = itr.Next()) >= 0) sectors[s].gravity = grav; @@ -1415,7 +1389,7 @@ void P_SpawnSpecials (void) case Init_Damage: { - int damage = P_AproxDistance (lines[i].dx, lines[i].dy) >> FRACBITS; + int damage = int(lines[i].Delta().Length()); FSectorTagIterator itr(lines[i].args[0]); while ((s = itr.Next()) >= 0) { @@ -1540,7 +1514,7 @@ static void P_SpawnFriction(void) } else { - length = P_AproxDistance(l->dx,l->dy)>>FRACBITS; + length = int(l->Delta().Length()); } P_SetSectorFriction (l->args[0], length, false); @@ -1552,14 +1526,14 @@ static void P_SpawnFriction(void) void P_SetSectorFriction (int tag, int amount, bool alterFlag) { int s; - fixed_t friction, movefactor; + double friction, movefactor; // An amount of 100 should result in a friction of // ORIG_FRICTION (0xE800) - friction = (0x1EB8*amount)/0x80 + 0xD001; + friction = ((0x1EB8 * amount) / 0x80 + 0xD001) / 65536.; // killough 8/28/98: prevent odd situations - friction = clamp(friction, 0, FRACUNIT); + friction = clamp(friction, 0., 1.); // The following check might seem odd. At the time of movement, // the move distance is multiplied by 'friction/0x10000', so a @@ -1597,6 +1571,26 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag) } } +double FrictionToMoveFactor(double friction) +{ + double movefactor; + + // [RH] Twiddled these values so that velocity on ice (with + // friction 0xf900) is the same as in Heretic/Hexen. + if (friction >= ORIG_FRICTION) // ice + //movefactor = ((0x10092 - friction)*(0x70))/0x158; + movefactor = (((0x10092 - friction * 65536) * 1024) / 4352 + 568) / 65536.; + else + movefactor = (((friction*65536. - 0xDB34)*(0xA)) / 0x80) / 65536.; + + // killough 8/28/98: prevent odd situations + if (movefactor < 1 / 2048.) + movefactor = 1 / 2048.; + + return movefactor; +} + + // // phares 3/12/98: End of friction effects // diff --git a/src/p_spec.h b/src/p_spec.h index 73f913a00..c934d7312 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -40,11 +40,11 @@ struct FThinkerCollection enum class EScroll : int { - sc_side, - sc_floor, - sc_ceiling, - sc_carry, - sc_carry_ceiling, // killough 4/11/98: carry objects hanging on ceilings + sc_side, + sc_floor, + sc_ceiling, + sc_carry, + sc_carry_ceiling, // killough 4/11/98: carry objects hanging on ceilings }; enum EScrollPos : int @@ -55,7 +55,7 @@ enum EScrollPos : int scw_all = 7, }; -void P_CreateScroller(EScroll type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all); +void P_CreateScroller(EScroll type, double dx, double dy, int control, int affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all); //jff 2/23/98 identify the special classes that can share sectors @@ -69,7 +69,7 @@ typedef enum // Factor to scale scrolling effect into mobj-carrying properties = 3/32. // (This is so scrolling floors and objects on them can move at same speed.) -enum { CARRYFACTOR = (3*FRACUNIT >> 5) }; +const double CARRYFACTOR = 3 / 32.; // Define values for map objects #define MO_TELEPORTMAN 14 @@ -87,41 +87,22 @@ enum { CARRYFACTOR = (3*FRACUNIT >> 5) }; bool CheckIfExitIsGood (AActor *self, level_info_t *info); // at map load -void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers); +void P_InitSectorSpecial(sector_t *sector, int special); void P_SpawnSpecials (void); // every tic void P_UpdateSpecials (void); // when needed -bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType, fixedvec3 *optpos = NULL); -bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType, fixedvec3 *optpos = NULL); +bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType, DVector3 *optpos = NULL); +bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType, DVector3 *optpos = NULL); bool P_PredictLine (line_t *ld, AActor *mo, int side, int activationType); void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL); void P_PlayerOnSpecialFlat (player_t *player, int floorType); void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, int flags); void P_SetSectorFriction (int tag, int amount, bool alterFlag); - -inline fixed_t FrictionToMoveFactor(fixed_t friction) -{ - fixed_t movefactor; - - // [RH] Twiddled these values so that velocity on ice (with - // friction 0xf900) is the same as in Heretic/Hexen. - if (friction >= ORIG_FRICTION) // ice -// movefactor = ((0x10092 - friction)*(0x70))/0x158; - movefactor = ((0x10092 - friction) * 1024) / 4352 + 568; - else - movefactor = ((friction - 0xDB34)*(0xA))/0x80; - - // killough 8/28/98: prevent odd situations - if (movefactor < 32) - movefactor = 32; - - return movefactor; -} - +double FrictionToMoveFactor(double friction); void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum); // @@ -316,7 +297,7 @@ void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics) void EV_StartLightStrobing (int tag, int utics, int ltics); void EV_TurnTagLightsOff (int tag); void EV_LightTurnOn (int tag, int bright); -void EV_LightTurnOnPartway (int tag, fixed_t frac); // killough 10/98 +void EV_LightTurnOnPartway (int tag, double frac); // killough 10/98 void EV_LightChange (int tag, int value); void EV_StopLightEffect (int tag); @@ -333,7 +314,7 @@ void EV_StartLightFading (int tag, int value, int tics); #define BUTTONTIME TICRATE // 1 second, in ticks. bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest=NULL); -bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpos = NULL); +bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, const DVector3 *optpos = NULL); // // P_PLATS @@ -375,9 +356,9 @@ public: protected: DPlat (sector_t *sector); - fixed_t m_Speed; - fixed_t m_Low; - fixed_t m_High; + double m_Speed; + double m_Low; + double m_High; int m_Wait; int m_Count; EPlatState m_Status; @@ -394,13 +375,13 @@ private: DPlat (); friend bool EV_DoPlat (int tag, line_t *line, EPlatType type, - int height, int speed, int delay, int lip, int change); + double height, double speed, int delay, int lip, int change); friend void EV_StopPlat (int tag); friend void P_ActivateInStasis (int tag); }; bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, - int height, int speed, int delay, int lip, int change); + double height, double speed, int delay, int lip, int change); void EV_StopPlat (int tag); void P_ActivateInStasis (int tag); @@ -421,8 +402,8 @@ public: }; - DPillar (sector_t *sector, EPillar type, fixed_t speed, fixed_t height, - fixed_t height2, int crush, bool hexencrush); + DPillar (sector_t *sector, EPillar type, double speed, double height, + double height2, int crush, bool hexencrush); void Serialize (FArchive &arc); void Tick (); @@ -430,10 +411,10 @@ public: protected: EPillar m_Type; - fixed_t m_FloorSpeed; - fixed_t m_CeilingSpeed; - fixed_t m_FloorTarget; - fixed_t m_CeilingTarget; + double m_FloorSpeed; + double m_CeilingSpeed; + double m_FloorTarget; + double m_CeilingTarget; int m_Crush; bool m_Hexencrush; TObjPtr m_Interp_Ceiling; @@ -444,7 +425,7 @@ private: }; bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag, - fixed_t speed, fixed_t height, fixed_t height2, int crush, bool hexencrush); + double speed, double height, double height2, int crush, bool hexencrush); // // P_DOORS @@ -464,16 +445,16 @@ public: }; DDoor (sector_t *sector); - DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTag, int topcountdown); + DDoor (sector_t *sec, EVlDoor type, double speed, int delay, int lightTag, int topcountdown); void Serialize (FArchive &arc); void Tick (); protected: EVlDoor m_Type; - fixed_t m_TopDist; - fixed_t m_BotDist, m_OldFloorDist; + double m_TopDist; + double m_BotDist, m_OldFloorDist; vertex_t *m_BotSpot; - fixed_t m_Speed; + double m_Speed; // 1 = up, 0 = waiting at top, -1 = down int m_Direction; @@ -489,7 +470,7 @@ protected: void DoorSound (bool raise, class DSeqNode *curseq=NULL) const; friend bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, - int tag, int speed, int delay, int lock, + int tag, double speed, int delay, int lock, int lightTag, bool boomgen, int topcountdown); private: DDoor (); @@ -497,9 +478,10 @@ private: }; bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, - int tag, int speed, int delay, int lock, + int tag, double speed, int delay, int lock, int lightTag, bool boomgen = false, int topcountdown = 0); + class DAnimatedDoor : public DMovingCeiling { DECLARE_CLASS (DAnimatedDoor, DMovingCeiling) @@ -516,7 +498,7 @@ protected: int m_Frame; FDoorAnimation *m_DoorAnim; int m_Timer; - fixed_t m_BotDist; + double m_BotDist; int m_Status; enum { @@ -585,22 +567,22 @@ public: DCeiling (sector_t *sec); - DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent); + DCeiling (sector_t *sec, double speed1, double speed2, int silent); void Serialize (FArchive &arc); void Tick (); static DCeiling *Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, int tag, - fixed_t speed, fixed_t speed2, fixed_t height, + double speed, double speed2, double height, int crush, int silent, int change, ECrushMode hexencrush); protected: ECeiling m_Type; - fixed_t m_BottomHeight; - fixed_t m_TopHeight; - fixed_t m_Speed; - fixed_t m_Speed1; // [RH] dnspeed of crushers - fixed_t m_Speed2; // [RH] upspeed of crushers + double m_BottomHeight; + double m_TopHeight; + double m_Speed; + double m_Speed1; // [RH] dnspeed of crushers + double m_Speed2; // [RH] upspeed of crushers int m_Crush; ECrushMode m_CrushMode; int m_Silent; @@ -624,8 +606,9 @@ private: }; bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, - int tag, fixed_t speed, fixed_t speed2, fixed_t height, + int tag, double speed, double speed2, double height, int crush, int silent, int change, DCeiling::ECrushMode hexencrush = DCeiling::ECrushMode::crushDoom); + bool EV_CeilingCrushStop (int tag); void P_ActivateInStasisCeiling (int tag); @@ -696,19 +679,19 @@ public: void Serialize (FArchive &arc); void Tick (); -protected: +//protected: EFloor m_Type; int m_Crush; bool m_Hexencrush; int m_Direction; secspecial_t m_NewSpecial; FTextureID m_Texture; - fixed_t m_FloorDestDist; - fixed_t m_Speed; + double m_FloorDestDist; + double m_Speed; // [RH] New parameters used to reset and delay stairs + double m_OrgDist; int m_ResetCount; - int m_OrgDist; int m_Delay; int m_PauseTime; int m_StepTime; @@ -718,23 +701,24 @@ protected: void SetFloorChangeType (sector_t *sec, int change); friend bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, - fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, + double stairsize, double speed, int delay, int reset, int igntxt, int usespecials); friend bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, - fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower); + double speed, double height, int crush, int change, bool hexencrush, bool hereticlower); friend bool EV_FloorCrushStop (int tag); - friend bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed); + friend bool EV_DoDonut (int tag, line_t *line, double pillarspeed, double slimespeed); private: DFloor (); }; bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, - fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, + double stairsize, double speed, int delay, int reset, int igntxt, int usespecials); -bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, - fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower=false); +bool EV_DoFloor(DFloor::EFloor floortype, line_t *line, int tag, + double speed, double height, int crush, int change, bool hexencrush, bool hereticlower = false); + bool EV_FloorCrushStop (int tag); -bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed); +bool EV_DoDonut (int tag, line_t *line, double pillarspeed, double slimespeed); class DElevator : public DMover { @@ -760,22 +744,20 @@ public: protected: EElevator m_Type; int m_Direction; - fixed_t m_FloorDestDist; - fixed_t m_CeilingDestDist; - fixed_t m_Speed; + double m_FloorDestDist; + double m_CeilingDestDist; + double m_Speed; TObjPtr m_Interp_Ceiling; TObjPtr m_Interp_Floor; void StartFloorSound (); - friend bool EV_DoElevator (line_t *line, DElevator::EElevator type, fixed_t speed, - fixed_t height, int tag); + friend bool EV_DoElevator (line_t *line, DElevator::EElevator type, double speed, double height, int tag); private: DElevator (); }; -bool EV_DoElevator (line_t *line, DElevator::EElevator type, fixed_t speed, - fixed_t height, int tag); +bool EV_DoElevator (line_t *line, DElevator::EElevator type, double speed, double height, int tag); class DWaggleBase : public DMover { @@ -787,12 +769,12 @@ public: void Serialize (FArchive &arc); protected: - fixed_t m_OriginalDist; - fixed_t m_Accumulator; - fixed_t m_AccDelta; - fixed_t m_TargetScale; - fixed_t m_Scale; - fixed_t m_ScaleDelta; + double m_OriginalDist; + double m_Accumulator; + double m_AccDelta; + double m_TargetScale; + double m_Scale; + double m_ScaleDelta; int m_Ticker; int m_State; TObjPtr m_Interpolation; @@ -851,12 +833,10 @@ enum TELF_KEEPHEIGHT = 16, }; -void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool beforeTele = true, bool setTarget = false); //Spawns teleport fog. Pass the actor to pluck TeleFogFromType and TeleFogToType. 'from' determines if this is the fog to spawn at the old position (true) or new (false). -inline void P_SpawnTeleportFog(AActor *mobj, const fixedvec3 &pos, bool beforeTele = true, bool setTarget = false) -{ - P_SpawnTeleportFog(mobj, pos.x, pos.y, pos.z, beforeTele, setTarget); -} -bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int flags); // bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false +//Spawns teleport fog. Pass the actor to pluck TeleFogFromType and TeleFogToType. 'from' determines if this is the fog to spawn at the old position (true) or new (false). +void P_SpawnTeleportFog(AActor *mobj, const DVector3 &pos, bool beforeTele = true, bool setTarget = false); + +inline bool P_Teleport(AActor *thing, DVector3 pos, DAngle angle, int flags); bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags); bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse); bool EV_TeleportOther (int other_tid, int dest_tid, bool fog); diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 254abb0ad..fdea7747b 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -59,7 +59,7 @@ class DActiveButton : public DThinker DECLARE_CLASS (DActiveButton, DThinker) public: DActiveButton (); - DActiveButton (side_t *, int, FSwitchDef *, fixed_t x, fixed_t y, bool flippable); + DActiveButton (side_t *, int, FSwitchDef *, const DVector2 &pos, bool flippable); void Serialize (FArchive &arc); void Tick (); @@ -71,7 +71,7 @@ public: FSwitchDef *m_SwitchDef; SDWORD m_Frame; DWORD m_Timer; - fixed_t m_X, m_Y; // Location of timer sound + DVector2 m_Pos; protected: bool AdvanceFrame (); @@ -85,7 +85,7 @@ protected: // //========================================================================== -static bool P_StartButton (side_t *side, int Where, FSwitchDef *Switch, fixed_t x, fixed_t y, bool useagain) +static bool P_StartButton (side_t *side, int Where, FSwitchDef *Switch, const DVector2 &pos, bool useagain) { DActiveButton *button; TThinkerIterator iterator; @@ -100,7 +100,7 @@ static bool P_StartButton (side_t *side, int Where, FSwitchDef *Switch, fixed_t } } - new DActiveButton (side, Where, Switch, x, y, useagain); + new DActiveButton (side, Where, Switch, pos, useagain); return true; } @@ -112,15 +112,15 @@ static bool P_StartButton (side_t *side, int Where, FSwitchDef *Switch, fixed_t // //========================================================================== -bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpos) +bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, const DVector3 *optpos) { // Activated from an empty side -> always succeed side_t *side = line->sidedef[sideno]; if (side == NULL) return true; - fixed_t checktop; - fixed_t checkbot; + double checktop; + double checkbot; sector_t *front = side->sector; FLineOpening open; int flags = line->flags; @@ -136,15 +136,16 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo // calculate the point where the user would touch the wall. divline_t dll, dlu; - fixed_t inter, checkx, checky; + double inter; + DVector2 check; P_MakeDivline (line, &dll); - fixedvec3 pos = optpos? *optpos : user->PosRelative(line); - dlu.x = pos.x; - dlu.y = pos.y; - dlu.dx = finecosine[user->angle >> ANGLETOFINESHIFT]; - dlu.dy = finesine[user->angle >> ANGLETOFINESHIFT]; + DVector3 pos = optpos? *optpos : user->PosRelative(line); + dlu.x = pos.X; + dlu.y = pos.Y; + dlu.dx = user->Angles.Yaw.Cos(); + dlu.dy = user->Angles.Yaw.Sin(); inter = P_InterceptVector(&dll, &dlu); @@ -153,14 +154,14 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo { // Get a check point slightly inside the polyobject so that this still works // if the polyobject lies directly on a sector boundary - checkx = dll.x + FixedMul(dll.dx, inter + (FRACUNIT/100)); - checky = dll.y + FixedMul(dll.dy, inter + (FRACUNIT/100)); - front = P_PointInSector(checkx, checky); + check.X = dll.x + dll.dx * (inter + 0.01); + check.Y = dll.y + dll.dy * (inter + 0.01); + front = P_PointInSector(check); } else { - checkx = dll.x + FixedMul(dll.dx, inter); - checky = dll.y + FixedMul(dll.dy, inter); + check.X = dll.x + dll.dx * inter; + check.Y = dll.y + dll.dy * inter; } @@ -168,13 +169,13 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo if (line->sidedef[1] == NULL || (line->sidedef[0]->Flags & WALLF_POLYOBJ)) { onesided: - fixed_t sectorc = front->ceilingplane.ZatPoint(checkx, checky); - fixed_t sectorf = front->floorplane.ZatPoint(checkx, checky); + double sectorc = front->ceilingplane.ZatPoint(check); + double sectorf = front->floorplane.ZatPoint(check); return (user->Top() >= sectorf && user->Z() <= sectorc); } // Now get the information from the line. - P_LineOpening(open, NULL, line, checkx, checky, pos.x, pos.y); + P_LineOpening(open, NULL, line, check, &pos); if (open.range <= 0) goto onesided; @@ -184,14 +185,13 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo // Check 3D floors on back side { sector_t * back = line->sidedef[1 - sideno]->sector; - for (unsigned i = 0; i < back->e->XFloor.ffloors.Size(); i++) + for (auto rover : back->e->XFloor.ffloors) { - F3DFloor *rover = back->e->XFloor.ffloors[i]; if (!(rover->flags & FF_EXISTS)) continue; if (!(rover->flags & FF_UPPERTEXTURE)) continue; - if (user->Z() > rover->top.plane->ZatPoint(checkx, checky) || - user->Top() < rover->bottom.plane->ZatPoint(checkx, checky)) + if (user->isAbove(rover->top.plane->ZatPoint(check)) || + user->Top() < rover->bottom.plane->ZatPoint(check)) continue; // This 3D floor depicts a switch texture in front of the player's eyes @@ -212,8 +212,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo if (!(rover->flags & FF_EXISTS)) continue; if (!(rover->flags & FF_LOWERTEXTURE)) continue; - if (user->Z() > rover->top.plane->ZatPoint(checkx, checky) || - user->Top() < rover->bottom.plane->ZatPoint(checkx, checky)) + if (user->isAbove(rover->top.plane->ZatPoint(check)) || + user->Top() < rover->bottom.plane->ZatPoint(check)) continue; // This 3D floor depicts a switch texture in front of the player's eyes @@ -229,12 +229,12 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo // to keep compatibility with Eternity's implementation. if (!P_GetMidTexturePosition(line, sideno, &checktop, &checkbot)) return false; - return user->Z() < checktop && user->Top() > checkbot; + return user->isBelow(checktop) && user->Top() > checkbot; } else { // no switch found. Check whether the player can touch either top or bottom texture - return (user->Top() > open.top) || (user->Z() < open.bottom); + return (user->Top() > open.top) || (user->isBelow(open.bottom)); } } @@ -291,16 +291,13 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques // which wasn't necessarily anywhere near the switch if it was // facing a big sector (and which wasn't necessarily for the // button just activated, either). - fixed_t pt[2]; - line_t *line = side->linedef; + DVector2 pt(side->linedef->v1->fPos() + side->linedef->Delta() / 2); bool playsound; - pt[0] = line->v1->x + (line->dx >> 1); - pt[1] = line->v1->y + (line->dy >> 1); side->SetTexture(texture, Switch->frames[0].Texture); if (useAgain || Switch->NumFrames > 1) { - playsound = P_StartButton (side, texture, Switch, pt[0], pt[1], !!useAgain); + playsound = P_StartButton (side, texture, Switch, pt, !!useAgain); } else { @@ -308,7 +305,7 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques } if (playsound) { - S_Sound (pt[0], pt[1], 0, CHAN_VOICE|CHAN_LISTENERZ, sound, 1, ATTN_STATIC); + S_Sound (DVector3(pt, 0), CHAN_VOICE|CHAN_LISTENERZ, sound, 1, ATTN_STATIC); } if (quest != NULL) { @@ -331,20 +328,18 @@ DActiveButton::DActiveButton () m_Part = -1; m_SwitchDef = 0; m_Timer = 0; - m_X = 0; - m_Y = 0; + m_Pos = { 0,0 }; bFlippable = false; bReturning = false; m_Frame = 0; } DActiveButton::DActiveButton (side_t *side, int Where, FSwitchDef *Switch, - fixed_t x, fixed_t y, bool useagain) + const DVector2 &pos, bool useagain) { m_Side = side; m_Part = SBYTE(Where); - m_X = x; - m_Y = y; + m_Pos = pos; bFlippable = useagain; bReturning = false; @@ -362,7 +357,7 @@ DActiveButton::DActiveButton (side_t *side, int Where, FSwitchDef *Switch, void DActiveButton::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << m_Side << m_Part << m_SwitchDef << m_Frame << m_Timer << bFlippable << m_X << m_Y << bReturning; + arc << m_Side << m_Part << m_SwitchDef << m_Frame << m_Timer << bFlippable << m_Pos << bReturning; } //========================================================================== @@ -390,7 +385,7 @@ void DActiveButton::Tick () if (def != NULL) { m_Frame = -1; - S_Sound (m_X, m_Y, 0, CHAN_VOICE|CHAN_LISTENERZ, + S_Sound (DVector3(m_Pos, 0), CHAN_VOICE|CHAN_LISTENERZ, def->Sound != 0 ? FSoundID(def->Sound) : FSoundID("switches/normbutn"), 1, ATTN_STATIC); bFlippable = false; diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index b6bdceda5..40ae4efed 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -78,7 +78,7 @@ void ATeleportFog::PostBeginPlay () // //========================================================================== -void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool beforeTele, bool setTarget) +void P_SpawnTeleportFog(AActor *mobj, const DVector3 &pos, bool beforeTele, bool setTarget) { AActor *mo; if ((beforeTele ? mobj->TeleFogSourceType : mobj->TeleFogDestType) == NULL) @@ -88,7 +88,7 @@ void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool befo } else { - mo = Spawn((beforeTele ? mobj->TeleFogSourceType : mobj->TeleFogDestType), x, y, z, ALLOW_REPLACE); + mo = Spawn((beforeTele ? mobj->TeleFogSourceType : mobj->TeleFogDestType), pos, ALLOW_REPLACE); } if (mo != NULL && setTarget) @@ -99,50 +99,50 @@ void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool befo // TELEPORTATION // -bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int flags) +bool P_Teleport (AActor *thing, DVector3 pos, DAngle angle, int flags) { bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING)); - fixedvec3 old; - fixed_t aboveFloor; + DVector3 old; + double aboveFloor; player_t *player; sector_t *destsect; bool resetpitch = false; - fixed_t floorheight, ceilingheight; - fixed_t missilespeed = 0; + double floorheight, ceilingheight; + double missilespeed = 0; old = thing->Pos(); aboveFloor = thing->Z() - thing->floorz; - destsect = P_PointInSector (x, y); + destsect = P_PointInSector (pos); // killough 5/12/98: exclude voodoo dolls: player = thing->player; if (player && player->mo != thing) player = NULL; - floorheight = destsect->floorplane.ZatPoint (x, y); - ceilingheight = destsect->ceilingplane.ZatPoint (x, y); + floorheight = destsect->floorplane.ZatPoint (pos); + ceilingheight = destsect->ceilingplane.ZatPoint (pos); if (thing->flags & MF_MISSILE) { // We don't measure z velocity, because it doesn't change. - missilespeed = xs_CRoundToInt(DVector2(thing->vel.x, thing->vel.y).Length()); + missilespeed = thing->VelXYToSpeed(); } if (flags & TELF_KEEPHEIGHT) { - z = floorheight + aboveFloor; + pos.Z = floorheight + aboveFloor; } - else if (z == ONFLOORZ) + else if (pos.Z == ONFLOORZ) { if (player) { if (thing->flags & MF_NOGRAVITY && aboveFloor) { - z = floorheight + aboveFloor; - if (z + thing->height > ceilingheight) + pos.Z = floorheight + aboveFloor; + if (pos.Z + thing->Height > ceilingheight) { - z = ceilingheight - thing->height; + pos.Z = ceilingheight - thing->Height; } } else { - z = floorheight; + pos.Z = floorheight; if (!(flags & TELF_KEEPORIENTATION)) { resetpitch = false; @@ -151,18 +151,18 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, } else if (thing->flags & MF_MISSILE) { - z = floorheight + aboveFloor; - if (z + thing->height > ceilingheight) + pos.Z = floorheight + aboveFloor; + if (pos.Z + thing->Height > ceilingheight) { - z = ceilingheight - thing->height; + pos.Z = ceilingheight - thing->Height; } } else { - z = floorheight; + pos.Z = floorheight; } } - if (!P_TeleportMove (thing, x, y, z, false)) + if (!P_TeleportMove (thing, pos, false)) { return false; } @@ -171,16 +171,16 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, player->viewz = thing->Z() + player->viewheight; if (resetpitch) { - player->mo->pitch = 0; + player->mo->Angles.Pitch = 0.; } } if (!(flags & TELF_KEEPORIENTATION)) { - thing->angle = angle; + thing->Angles.Yaw = angle; } else { - angle = thing->angle; + angle = thing->Angles.Yaw; } // Spawn teleport fog at source and destination if ((flags & TELF_SOURCEFOG) && !predicting) @@ -191,10 +191,10 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, { if (!predicting) { - fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT; - fixedvec2 vector = Vec2Angle(20 * FRACUNIT, angle); - fixedvec2 fogpos = P_GetOffsetPosition(x, y, vector.x, vector.y); - P_SpawnTeleportFog(thing, fogpos.x, fogpos.y, thing->Z() + fogDelta, false, true); + double fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT; + DVector2 vector = angle.ToVector(20); + DVector2 fogpos = P_GetOffsetPosition(pos.X, pos.Y, vector.X, vector.Y); + P_SpawnTeleportFog(thing, DVector3(fogpos, thing->Z() + fogDelta), false, true); } if (thing->player) @@ -214,17 +214,14 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, } if (thing->flags & MF_MISSILE) { - angle >>= ANGLETOFINESHIFT; - thing->vel.x = FixedMul (missilespeed, finecosine[angle]); - thing->vel.y = FixedMul (missilespeed, finesine[angle]); + thing->VelFromAngle(missilespeed); } // [BC] && bHaltVelocity. else if (!(flags & TELF_KEEPORIENTATION) && !(flags & TELF_KEEPVELOCITY)) { // no fog doesn't alter the player's momentum - thing->vel.x = thing->vel.y = thing->vel.z = 0; + thing->Vel.Zero(); // killough 10/98: kill all bobbing velocity too - if (player) - player->vel.x = player->vel.y = 0; + if (player) player->Vel.Zero(); } return true; } @@ -327,11 +324,11 @@ static AActor *SelectTeleDest (int tid, int tag, bool norandom) bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags) { AActor *searcher; - fixed_t z; - angle_t angle = 0; - fixed_t s = 0, c = 0; - fixed_t vx = 0, vy = 0; - angle_t badangle = 0; + double z; + DAngle angle = 0.; + double s = 0, c = 0; + double vx = 0, vy = 0; + DAngle badangle = 0.; if (thing == NULL) { // Teleport function called with an invalid actor @@ -358,15 +355,15 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int f // Rotate 90 degrees, so that walking perpendicularly across // teleporter linedef causes thing to exit in the direction // indicated by the exit thing. - angle = R_PointToAngle2 (0, 0, line->dx, line->dy) - searcher->angle + ANG90; + angle = line->Delta().Angle() - searcher->Angles.Yaw + 90.; // Sine, cosine of angle adjustment - s = finesine[angle>>ANGLETOFINESHIFT]; - c = finecosine[angle>>ANGLETOFINESHIFT]; + s = angle.Sin(); + c = angle.Cos(); // Velocity of thing crossing teleporter linedef - vx = thing->vel.x; - vy = thing->vel.y; + vx = thing->Vel.X; + vy = thing->Vel.Y; z = searcher->Z(); } @@ -380,21 +377,21 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int f } if ((i_compatflags2 & COMPATF2_BADANGLES) && (thing->player != NULL)) { - badangle = 1 << ANGLETOFINESHIFT; + badangle = 0.01; } - if (P_Teleport (thing, searcher->X(), searcher->Y(), z, searcher->angle + badangle, flags)) + if (P_Teleport (thing, DVector3(searcher->Pos(), z), searcher->Angles.Yaw + badangle, flags)) { // [RH] Lee Killough's changes for silent teleporters from BOOM if (!(flags & TELF_DESTFOG) && line && (flags & TELF_KEEPORIENTATION)) { // Rotate thing according to difference in angles - thing->angle += angle; + thing->Angles.Yaw += angle; // Rotate thing's velocity to come out of exit just like it entered - thing->vel.x = FixedMul(vx, c) - FixedMul(vy, s); - thing->vel.y = FixedMul(vy, c) + FixedMul(vx, s); + thing->Vel.X = vx*c - vy*s; + thing->Vel.Y = vy*c + vx*s; } - if ((vx | vy) == 0 && thing->player != NULL && thing->player->mo == thing && !predicting) + if (vx == 0 && vy == 0 && thing->player != NULL && thing->player->mo == thing && !predicting) { thing->player->mo->PlayIdle (); } @@ -429,65 +426,57 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO if ((l=lines+i) != line && l->backsector) { // Get the thing's position along the source linedef - SDWORD pos; // 30.2 fixed - fixed_t nposx, nposy; // offsets from line - { - SQWORD den; + double pos; + DVector2 npos; // offsets from line + double den; - den = (SQWORD)line->dx*line->dx + (SQWORD)line->dy*line->dy; - if (den == 0) + den = line->Delta().LengthSquared(); + if (den == 0) + { + pos = 0; + npos.Zero(); + } + else + { + double num = (thing->Pos().XY() - line->v1->fPos()) | line->Delta(); + if (num <= 0) { pos = 0; - nposx = 0; - nposy = 0; + } + else if (num >= den) + { + pos = 1; } else { - SQWORD num = (SQWORD)(thing->X()-line->v1->x)*line->dx + - (SQWORD)(thing->Y()-line->v1->y)*line->dy; - if (num <= 0) - { - pos = 0; - } - else if (num >= den) - { - pos = 1<<30; - } - else - { - pos = (SDWORD)(num / (den>>30)); - } - nposx = thing->X() - line->v1->x - MulScale30 (line->dx, pos); - nposy = thing->Y() - line->v1->y - MulScale30 (line->dy, pos); + pos = num / den; } + npos = thing->Pos().XY() - line->v1->fPos() - line->Delta() * pos; } // Get the angle between the two linedefs, for rotating // orientation and velocity. Rotate 180 degrees, and flip // the position across the exit linedef, if reversed. - angle_t angle = - R_PointToAngle2(0, 0, l->dx, l->dy) - - R_PointToAngle2(0, 0, line->dx, line->dy); + DAngle angle = l->Delta().Angle() - line->Delta().Angle(); if (!reverse) { - angle += ANGLE_180; - pos = (1<<30) - pos; + angle += 180.; + pos = 1 - pos; } // Sine, cosine of angle adjustment - fixed_t s = finesine[angle>>ANGLETOFINESHIFT]; - fixed_t c = finecosine[angle>>ANGLETOFINESHIFT]; + double s = angle.Sin(); + double c = angle.Cos(); - fixed_t x, y; + DVector2 p; // Rotate position along normal to match exit linedef - x = DMulScale16 (nposx, c, -nposy, s); - y = DMulScale16 (nposy, c, nposx, s); + p.X = npos.X*c - npos.Y*s; + p.Y = npos.Y*c + npos.X*s; // Interpolate position across the exit linedef - x += l->v1->x + MulScale30 (pos, l->dx); - y += l->v1->y + MulScale30 (pos, l->dy); + p += l->v1->fPos() + pos*l->Delta(); // Whether this is a player, and if so, a pointer to its player_t. // Voodoo dolls are excluded by making sure thing->player->mo==thing. @@ -495,10 +484,10 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO thing->player : NULL; // Whether walking towards first side of exit linedef steps down - bool stepdown = l->frontsector->floorplane.ZatPoint(x, y) < l->backsector->floorplane.ZatPoint(x, y); + bool stepdown = l->frontsector->floorplane.ZatPoint(p) < l->backsector->floorplane.ZatPoint(p); // Height of thing above ground - fixed_t z = thing->Z() - thing->floorz; + double z = thing->Z() - thing->floorz; // Side to exit the linedef on positionally. // @@ -522,25 +511,30 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO // Exiting on side 1 slightly improves player viewing // when going down a step on a non-reversed teleporter. + // Is this really still necessary with real math instead of imprecise trig tables? +#if 1 int side = reverse || (player && stepdown); int fudge = FUDGEFACTOR; + double dx = line->Delta().X; + double dy = line->Delta().Y; // Make sure we are on correct side of exit linedef. - while (P_PointOnLineSidePrecise(x, y, l) != side && --fudge >= 0) + while (P_PointOnLineSidePrecise(p, l) != side && --fudge >= 0) { - if (abs(l->dx) > abs(l->dy)) - y -= (l->dx < 0) != side ? -1 : 1; + if (fabs(dx) > fabs(dy)) + p.Y -= (dx < 0) != side ? -1 : 1; else - x += (l->dy < 0) != side ? -1 : 1; + p.X += (dy < 0) != side ? -1 : 1; } +#endif // Adjust z position to be same height above ground as before. // Ground level at the exit is measured as the higher of the // two floor heights at the exit linedef. - z = z + l->sidedef[stepdown]->sector->floorplane.ZatPoint(x, y); + z = z + l->sidedef[stepdown]->sector->floorplane.ZatPoint(p); // Attempt to teleport, aborting if blocked - if (!P_TeleportMove (thing, x, y, z, false)) + if (!P_TeleportMove (thing, DVector3(p, z), false)) { return false; } @@ -551,27 +545,23 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO } // Rotate thing's orientation according to difference in linedef angles - thing->angle += angle; - - // Velocity of thing crossing teleporter linedef - x = thing->vel.x; - y = thing->vel.y; + thing->Angles.Yaw += angle; // Rotate thing's velocity to come out of exit just like it entered - thing->vel.x = DMulScale16 (x, c, -y, s); - thing->vel.y = DMulScale16 (y, c, x, s); + p = thing->Vel.XY(); + thing->Vel.X = p.X*c - p.Y*s; + thing->Vel.Y = p.Y*c + p.X*s; // Adjust a player's view, in case there has been a height change if (player && player->mo == thing) { // Adjust player's local copy of velocity - x = player->vel.x; - y = player->vel.y; - player->vel.x = DMulScale16 (x, c, -y, s); - player->vel.y = DMulScale16 (y, c, x, s); + p = player->Vel; + player->Vel.X = p.X*c - p.Y*s; + player->Vel.Y = p.Y*c + p.X*s; // Save the current deltaviewheight, used in stepping - fixed_t deltaviewheight = player->deltaviewheight; + double deltaviewheight = player->deltaviewheight; // Clear deltaviewheight, since we don't want any changes now player->deltaviewheight = 0; @@ -611,37 +601,21 @@ bool EV_TeleportOther (int other_tid, int dest_tid, bool fog) static bool DoGroupForOne (AActor *victim, AActor *source, AActor *dest, bool floorz, bool fog) { - int an = (dest->angle - source->angle) >> ANGLETOFINESHIFT; - fixed_t offX = victim->X() - source->X(); - fixed_t offY = victim->Y() - source->Y(); - angle_t offAngle = victim->angle - source->angle; - fixed_t newX = DMulScale16 (offX, finecosine[an], -offY, finesine[an]); - fixed_t newY = DMulScale16 (offX, finesine[an], offY, finecosine[an]); + DAngle an = dest->Angles.Yaw - source->Angles.Yaw; + DVector2 off = victim->Pos() - source->Pos(); + DAngle offAngle = victim->Angles.Yaw - source->Angles.Yaw; + DVector2 newp = { off.X * an.Cos() - off.Y * an.Sin(), off.X * an.Sin() + off.Y * an.Cos() }; + double z = floorz ? ONFLOORZ : dest->Z() + victim->Z() - source->Z(); bool res = - P_Teleport (victim, dest->X() + newX, - dest->Y() + newY, - floorz ? ONFLOORZ : dest->Z() + victim->Z() - source->Z(), - 0, fog ? (TELF_DESTFOG | TELF_SOURCEFOG) : TELF_KEEPORIENTATION); + P_Teleport (victim, DVector3(dest->Pos().XY() + newp, z), + 0., fog ? (TELF_DESTFOG | TELF_SOURCEFOG) : TELF_KEEPORIENTATION); // P_Teleport only changes angle if fog is true - victim->angle = dest->angle + offAngle; + victim->Angles.Yaw = (dest->Angles.Yaw + victim->Angles.Yaw - source->Angles.Yaw).Normalized360(); return res; } -#if 0 -static void MoveTheDecal (DBaseDecal *decal, fixed_t z, AActor *source, AActor *dest) -{ - int an = (dest->angle - source->angle) >> ANGLETOFINESHIFT; - fixed_t offX = decal->x - source->x; - fixed_t offY = decal->y - source->y; - fixed_t newX = DMulScale16 (offX, finecosine[an], -offY, finesine[an]); - fixed_t newY = DMulScale16 (offX, finesine[an], offY, finecosine[an]); - - decal->Relocate (dest->x + newX, dest->y + newY, dest->z + z - source->z); -} -#endif - // [RH] Teleport a group of actors centered around source_tid so // that they become centered around dest_tid instead. bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_tid, bool moveSource, bool fog) @@ -689,9 +663,8 @@ bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_t if (moveSource && didSomething) { didSomething |= - P_Teleport (sourceOrigin, destOrigin->X(), destOrigin->Y(), - floorz ? ONFLOORZ : destOrigin->Z(), 0, TELF_KEEPORIENTATION); - sourceOrigin->angle = destOrigin->angle; + P_Teleport (sourceOrigin, destOrigin->PosAtZ(floorz ? ONFLOORZ : destOrigin->Z()), 0., TELF_KEEPORIENTATION); + sourceOrigin->Angles.Yaw = destOrigin->Angles.Yaw; } return didSomething; @@ -743,32 +716,6 @@ bool EV_TeleportSector (int tag, int source_tid, int dest_tid, bool fog, int gro } node = next; } - -#if 0 - if (group_tid == 0 && !fog) - { - int lineindex; - for (lineindex = sec->linecount-1; lineindex >= 0; --lineindex) - { - line_t *line = sec->lines[lineindex]; - int wallnum; - - wallnum = line->sidenum[(line->backsector == sec)]; - if (wallnum != -1) - { - side_t *wall = &sides[wallnum]; - ADecal *decal = wall->BoundActors; - - while (decal != NULL) - { - ADecal *next = (ADecal *)decal->snext; - MoveTheDecal (decal, decal->GetRealZ (wall), sourceOrigin, destOrigin); - decal = next; - } - } - } - } -#endif } return didSomething; } diff --git a/src/p_terrain.cpp b/src/p_terrain.cpp index 3c6519393..1b3226780 100644 --- a/src/p_terrain.cpp +++ b/src/p_terrain.cpp @@ -89,12 +89,12 @@ enum ETerrainKeywords enum EGenericType { GEN_End, - GEN_Fixed, GEN_Sound, GEN_Byte, GEN_Class, GEN_Splash, GEN_Float, + GEN_Double, GEN_Time, GEN_Bool, GEN_Int, @@ -193,7 +193,7 @@ static FGenericParse SplashParser[] = { { GEN_End, {0} }, { GEN_Sound, {myoffsetof(FSplashDef, SmallSplashSound)} }, - { GEN_Fixed, {myoffsetof(FSplashDef, SmallSplashClip)} }, + { GEN_Double, {myoffsetof(FSplashDef, SmallSplashClip)} }, { GEN_Sound, {myoffsetof(FSplashDef, NormalSplashSound)} }, { GEN_Class, {myoffsetof(FSplashDef, SmallSplash)} }, { GEN_Class, {myoffsetof(FSplashDef, SplashBase)} }, @@ -201,7 +201,7 @@ static FGenericParse SplashParser[] = { GEN_Byte, {myoffsetof(FSplashDef, ChunkXVelShift)} }, { GEN_Byte, {myoffsetof(FSplashDef, ChunkYVelShift)} }, { GEN_Byte, {myoffsetof(FSplashDef, ChunkZVelShift)} }, - { GEN_Fixed, {myoffsetof(FSplashDef, ChunkBaseZVel)} }, + { GEN_Double, {myoffsetof(FSplashDef, ChunkBaseZVel)} }, { GEN_Bool, {myoffsetof(FSplashDef, NoAlert)} } }; @@ -212,7 +212,7 @@ static FGenericParse TerrainParser[] = { GEN_Int, {myoffsetof(FTerrainDef, DamageAmount)} }, { GEN_Custom, {(size_t)ParseDamage} }, { GEN_Int, {myoffsetof(FTerrainDef, DamageTimeMask)} }, - { GEN_Fixed, {myoffsetof(FTerrainDef, FootClip)} }, + { GEN_Double, {myoffsetof(FTerrainDef, FootClip)} }, { GEN_Float, {myoffsetof(FTerrainDef, StepVolume)} }, { GEN_Time, {myoffsetof(FTerrainDef, WalkStepTics)} }, { GEN_Time, {myoffsetof(FTerrainDef, RunStepTics)} }, @@ -360,8 +360,8 @@ static void SetSplashDefaults (FSplashDef *splashdef) splashdef->ChunkXVelShift = splashdef->ChunkYVelShift = splashdef->ChunkZVelShift = 8; - splashdef->ChunkBaseZVel = FRACUNIT; - splashdef->SmallSplashClip = 12*FRACUNIT; + splashdef->ChunkBaseZVel = 1; + splashdef->SmallSplashClip = 12.; splashdef->NoAlert = false; } @@ -487,15 +487,15 @@ static void ParseDamage (FScanner &sc, int keyword, void *fields) static void ParseFriction (FScanner &sc, int keyword, void *fields) { FTerrainDef *def = (FTerrainDef *)fields; - fixed_t friction, movefactor; + double friction, movefactor; sc.MustGetFloat (); // These calculations should match those in P_SetSectorFriction(). // A friction of 1.0 is equivalent to ORIG_FRICTION. - friction = (fixed_t)(0x1EB8*(sc.Float*100))/0x80 + 0xD001; - friction = clamp (friction, 0, FRACUNIT); + friction = (0x1EB8*(sc.Float*100))/0x80 + 0xD001; + friction = clamp (friction, 0, 65536.); if (friction > ORIG_FRICTION) // ice movefactor = ((0x10092 - friction) * 1024) / 4352 + 568; @@ -505,8 +505,8 @@ static void ParseFriction (FScanner &sc, int keyword, void *fields) if (movefactor < 32) movefactor = 32; - def->Friction = friction; - def->MoveFactor = movefactor; + def->Friction = friction / 65536.; + def->MoveFactor = movefactor / 65536.; } //========================================================================== @@ -533,11 +533,6 @@ static void GenericParse (FScanner &sc, FGenericParse *parser, const char **keyw notdone = false; break; - case GEN_Fixed: - sc.MustGetFloat (); - SET_FIELD (fixed_t, (fixed_t)(FRACUNIT * sc.Float)); - break; - case GEN_Sound: sc.MustGetString (); SET_FIELD (FSoundID, FSoundID(sc.String)); @@ -595,6 +590,11 @@ static void GenericParse (FScanner &sc, FGenericParse *parser, const char **keyw SET_FIELD (float, float(sc.Float)); break; + case GEN_Double: + sc.MustGetFloat(); + SET_FIELD(double, sc.Float); + break; + case GEN_Time: sc.MustGetFloat (); SET_FIELD (int, (int)(sc.Float * TICRATE)); diff --git a/src/p_terrain.h b/src/p_terrain.h index 43d445c7e..2a15eb976 100644 --- a/src/p_terrain.h +++ b/src/p_terrain.h @@ -95,9 +95,9 @@ struct FSplashDef BYTE ChunkXVelShift; BYTE ChunkYVelShift; BYTE ChunkZVelShift; - fixed_t ChunkBaseZVel; - fixed_t SmallSplashClip; bool NoAlert; + double ChunkBaseZVel; + double SmallSplashClip; }; struct FTerrainDef @@ -107,7 +107,7 @@ struct FTerrainDef int DamageAmount; FName DamageMOD; int DamageTimeMask; - fixed_t FootClip; + double FootClip; float StepVolume; int WalkStepTics; int RunStepTics; @@ -115,8 +115,8 @@ struct FTerrainDef FSoundID RightStepSound; bool IsLiquid; bool AllowProtection; - fixed_t Friction; - fixed_t MoveFactor; + double Friction; + double MoveFactor; }; extern TArray Splashes; diff --git a/src/p_things.cpp b/src/p_things.cpp index 5b0810d51..1560736a0 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -50,13 +50,14 @@ #include "d_player.h" #include "r_utility.h" #include "p_spec.h" +#include "math/cmath.h" // Set of spawnable things for the Thing_Spawn and Thing_Projectile specials. FClassMap SpawnableThings; static FRandom pr_leadtarget ("LeadTarget"); -bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid) +bool P_Thing_Spawn (int tid, AActor *source, int type, DAngle angle, bool fog, int newtid) { int rtn = 0; PClassActor *kind; @@ -94,10 +95,10 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, if (P_TestMobjLocation (mobj)) { rtn++; - mobj->angle = (angle != ANGLE_MAX ? angle : spot->angle); + mobj->Angles.Yaw = (angle != 1000000. ? angle : spot->Angles.Yaw); if (fog) { - P_SpawnTeleportFog(mobj, spot->X(), spot->Y(), spot->Z() + TELEFOGHEIGHT, false, true); + P_SpawnTeleportFog(mobj, spot->PosPlusZ(TELEFOGHEIGHT), false, true); } if (mobj->flags & MF_SPECIAL) mobj->flags |= MF_DROPPED; // Don't respawn @@ -122,21 +123,17 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, // [BC] Added // [RH] Fixed -bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog) +bool P_MoveThing(AActor *source, const DVector3 &pos, bool fog) { - fixed_t oldx, oldy, oldz; + DVector3 old = source->Pos(); - oldx = source->X(); - oldy = source->Y(); - oldz = source->Z(); - - source->SetOrigin (x, y, z, true); + source->SetOrigin (pos, true); if (P_TestMobjLocation (source)) { if (fog) { - P_SpawnTeleportFog(source, x, y, z, false, true); - P_SpawnTeleportFog(source, oldx, oldy, oldz, true, true); + P_SpawnTeleportFog(source, pos, false, true); + P_SpawnTeleportFog(source, old, true, true); } source->ClearInterpolation(); if (source == players[consoleplayer].camera) @@ -147,7 +144,7 @@ bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog) } else { - source->SetOrigin (oldx, oldy, oldz, true); + source->SetOrigin (old, true); return false; } } @@ -166,20 +163,19 @@ bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog) if (source != NULL && target != NULL) { - return P_MoveThing(source, target->X(), target->Y(), target->Z(), fog); + return P_MoveThing(source, target->Pos(), fog); } return false; } -bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_name, angle_t angle, - fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid, +bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_name, DAngle angle, + double speed, double vspeed, int dest, AActor *forcedest, int gravity, int newtid, bool leadTarget) { int rtn = 0; PClassActor *kind; AActor *spot, *mobj, *targ = forcedest; FActorIterator iterator (tid); - double fspeed = speed; int defflags3; if (type_name == NULL) @@ -219,7 +215,7 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam { do { - fixed_t z = spot->Z(); + double z = spot->Z(); if (defflags3 & MF3_FLOORHUGGER) { z = ONFLOORZ; @@ -230,9 +226,9 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam } else if (z != ONFLOORZ) { - z -= spot->floorclip; + z -= spot->Floorclip; } - mobj = Spawn (kind, spot->X(), spot->Y(), z, ALLOW_REPLACE); + mobj = Spawn (kind, spot->PosAtZ(z), ALLOW_REPLACE); if (mobj) { @@ -244,7 +240,7 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam mobj->flags &= ~MF_NOGRAVITY; if (!(mobj->flags3 & MF3_ISMONSTER) && gravity == 1) { - mobj->gravity = FRACUNIT/8; + mobj->Gravity = 1./8; } } else @@ -255,11 +251,10 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam if (targ != NULL) { - fixedvec3 vect = mobj->Vec3To(targ); - vect.z += targ->height / 2; - DVector3 aim(vect.x, vect.y, vect.z); + DVector3 aim = mobj->Vec3To(targ); + aim.Z += targ->Height / 2; - if (leadTarget && speed > 0 && (targ->vel.x | targ->vel.y | targ->vel.z)) + if (leadTarget && speed > 0 && !targ->Vel.isZero()) { // Aiming at the target's position some time in the future // is basically just an application of the law of sines: @@ -268,14 +263,14 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam // with the math. I don't think I would have thought of using // trig alone had I been left to solve it by myself. - DVector3 tvel(targ->vel.x, targ->vel.y, targ->vel.z); + DVector3 tvel = targ->Vel; if (!(targ->flags & MF_NOGRAVITY) && targ->waterlevel < 3) { // If the target is subject to gravity and not underwater, // assume that it isn't moving vertically. Thanks to gravity, // even if we did consider the vertical component of the target's // velocity, we would still miss more often than not. tvel.Z = 0.0; - if ((targ->vel.x | targ->vel.y) == 0) + if (targ->Vel.X == 0 && targ->Vel.Y == 0) { goto nolead; } @@ -283,9 +278,9 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam double dist = aim.Length(); double targspeed = tvel.Length(); double ydotx = -aim | tvel; - double a = acos (clamp (ydotx / targspeed / dist, -1.0, 1.0)); + double a = g_acos (clamp (ydotx / targspeed / dist, -1.0, 1.0)); double multiplier = double(pr_leadtarget.Random2())*0.1/255+1.1; - double sinb = -clamp (targspeed*multiplier * sin(a) / fspeed, -1.0, 1.0); + double sinb = -clamp (targspeed*multiplier * g_sin(a) / speed, -1.0, 1.0); // Use the cross product of two of the triangle's sides to get a // rotation vector. @@ -293,25 +288,19 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam // The vector must be normalized. rv.MakeUnit(); // Now combine the rotation vector with angle b to get a rotation matrix. - DMatrix3x3 rm(rv, cos(asin(sinb)), sinb); + DMatrix3x3 rm(rv, g_cos(g_asin(sinb)), sinb); // And multiply the original aim vector with the matrix to get a // new aim vector that leads the target. DVector3 aimvec = rm * aim; // And make the projectile follow that vector at the desired speed. - double aimscale = fspeed / dist; - mobj->vel.x = fixed_t (aimvec[0] * aimscale); - mobj->vel.y = fixed_t (aimvec[1] * aimscale); - mobj->vel.z = fixed_t (aimvec[2] * aimscale); - mobj->angle = R_PointToAngle2 (0, 0, mobj->vel.x, mobj->vel.y); + mobj->Vel = aimvec * (speed / dist); + mobj->AngleFromVel(); } else { nolead: - mobj->angle = mobj->AngleTo(targ); - aim.Resize (fspeed); - mobj->vel.x = fixed_t(aim[0]); - mobj->vel.y = fixed_t(aim[1]); - mobj->vel.z = fixed_t(aim[2]); + mobj->Angles.Yaw = mobj->AngleTo(targ); + mobj->Vel = aim.Resized (speed); } if (mobj->flags2 & MF2_SEEKERMISSILE) { @@ -320,20 +309,19 @@ nolead: } else { - mobj->angle = angle; - mobj->vel.x = FixedMul (speed, finecosine[angle>>ANGLETOFINESHIFT]); - mobj->vel.y = FixedMul (speed, finesine[angle>>ANGLETOFINESHIFT]); - mobj->vel.z = vspeed; + mobj->Angles.Yaw = angle; + mobj->VelFromAngle(speed); + mobj->Vel.Z = vspeed; } // Set the missile's speed to reflect the speed it was spawned at. if (mobj->flags & MF_MISSILE) { - mobj->Speed = fixed_t (sqrt (double(mobj->vel.x)*mobj->vel.x + double(mobj->vel.y)*mobj->vel.y + double(mobj->vel.z)*mobj->vel.z)); + mobj->Speed = mobj->VelToSpeed(); } // Hugger missiles don't have any vertical velocity if (mobj->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)) { - mobj->vel.z = 0; + mobj->Vel.Z = 0; } if (mobj->flags & MF_SPECIAL) { @@ -427,21 +415,21 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser) AActor *info = thing->GetDefault (); - thing->vel.x = thing->vel.y = 0; + thing->Vel.X = thing->Vel.Y = 0; // [RH] Check against real height and radius - fixed_t oldheight = thing->height; - fixed_t oldradius = thing->radius; + double oldheight = thing->Height; + double oldradius = thing->radius; ActorFlags oldflags = thing->flags; thing->flags |= MF_SOLID; - thing->height = info->height; // [RH] Use real height + thing->Height = info->Height; // [RH] Use real height thing->radius = info->radius; // [RH] Use real radius if (!P_CheckPosition (thing, thing->Pos())) { thing->flags = oldflags; thing->radius = oldradius; - thing->height = oldheight; + thing->Height = oldheight; return false; } @@ -472,11 +460,11 @@ bool P_Thing_CanRaise(AActor *thing) // Check against real height and radius ActorFlags oldflags = thing->flags; - fixed_t oldheight = thing->height; - fixed_t oldradius = thing->radius; + double oldheight = thing->Height; + double oldradius = thing->radius; thing->flags |= MF_SOLID; - thing->height = info->height; + thing->Height = info->Height; thing->radius = info->radius; bool check = P_CheckPosition (thing, thing->Pos()); @@ -484,7 +472,7 @@ bool P_Thing_CanRaise(AActor *thing) // Restore checked properties thing->flags = oldflags; thing->radius = oldradius; - thing->height = oldheight; + thing->Height = oldheight; if (!check) { @@ -494,22 +482,19 @@ bool P_Thing_CanRaise(AActor *thing) return true; } -void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob) +void P_Thing_SetVelocity(AActor *actor, const DVector3 &vec, bool add, bool setbob) { if (actor != NULL) { if (!add) { - actor->vel.x = actor->vel.y = actor->vel.z = 0; - if (actor->player != NULL) actor->player->vel.x = actor->player->vel.y = 0; + actor->Vel.Zero(); + if (actor->player != NULL) actor->player->Vel.Zero(); } - actor->vel.x += vx; - actor->vel.y += vy; - actor->vel.z += vz; + actor->Vel += vec; if (setbob && actor->player != NULL) { - actor->player->vel.x += vx; - actor->player->vel.y += vy; + actor->player->Vel += vec.XY(); } } } @@ -683,7 +668,7 @@ void InitSpawnablesFromMapinfo() } -int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset, fixed_t radiusoffset, angle_t pitch) +int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch) { if (flags & WARPF_MOVEPTR) { @@ -692,32 +677,33 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, caller = temp; } - fixedvec3 old = caller->Pos(); + DVector3 old = caller->Pos(); int oldpgroup = caller->Sector->PortalGroup; - zofs += FixedMul(reference->height, heightoffset); + zofs += reference->Height * heightoffset; if (!(flags & WARPF_ABSOLUTEANGLE)) { - angle += (flags & WARPF_USECALLERANGLE) ? caller->angle : reference->angle; + angle += (flags & WARPF_USECALLERANGLE) ? caller->Angles.Yaw: reference->Angles.Yaw; } - const fixed_t rad = FixedMul(radiusoffset, reference->radius); - const angle_t fineangle = angle >> ANGLETOFINESHIFT; + const double rad = radiusoffset * reference->radius; + const double s = angle.Sin(); + const double c = angle.Cos(); if (!(flags & WARPF_ABSOLUTEPOSITION)) { if (!(flags & WARPF_ABSOLUTEOFFSET)) { - fixed_t xofs1 = xofs; + double xofs1 = xofs; // (borrowed from A_SpawnItemEx, assumed workable) // in relative mode negative y values mean 'left' and positive ones mean 'right' // This is the inverse orientation of the absolute mode! - xofs = FixedMul(xofs1, finecosine[fineangle]) + FixedMul(yofs, finesine[fineangle]); - yofs = FixedMul(xofs1, finesine[fineangle]) - FixedMul(yofs, finecosine[fineangle]); + xofs = xofs1 * c + yofs * s; + yofs = xofs1 * s - yofs * c; } if (flags & WARPF_TOFLOOR) @@ -726,31 +712,22 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, // now the caller's floorz should be appropriate for the assigned xy-position // assigning position again with. // extra unlink, link and environment calculation - caller->SetOrigin(reference->Vec3Offset( - xofs + FixedMul(rad, finecosine[fineangle]), - yofs + FixedMul(rad, finesine[fineangle]), - 0), true); + caller->SetOrigin(reference->Vec3Offset(xofs + rad * c, yofs + rad * s, 0.), true); + // The two-step process is important. caller->SetZ(caller->floorz + zofs); } else { - caller->SetOrigin(reference->Vec3Offset( - xofs + FixedMul(rad, finecosine[fineangle]), - yofs + FixedMul(rad, finesine[fineangle]), - zofs), true); + caller->SetOrigin(reference->Vec3Offset(xofs + rad * c, yofs + rad * s, zofs), true); } } else // [MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's. { + caller->SetOrigin(xofs + rad * c, yofs + rad * s, zofs, true); if (flags & WARPF_TOFLOOR) { - caller->SetOrigin(xofs + FixedMul(rad, finecosine[fineangle]), yofs + FixedMul(rad, finesine[fineangle]), zofs, true); caller->SetZ(caller->floorz + zofs); } - else - { - caller->SetOrigin(xofs + FixedMul(rad, finecosine[fineangle]), yofs + FixedMul(rad, finesine[fineangle]), zofs, true); - } } if ((flags & WARPF_NOCHECKPOSITION) || P_TestMobjLocation(caller)) @@ -761,51 +738,44 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, } else { - caller->angle = angle; + caller->Angles.Yaw = angle; if (flags & WARPF_COPYPITCH) - caller->SetPitch(reference->pitch, false); + caller->SetPitch(reference->Angles.Pitch, false); - if (pitch) - caller->SetPitch(caller->pitch + pitch, false); + if (pitch != 0) + caller->SetPitch(caller->Angles.Pitch + pitch, false); if (flags & WARPF_COPYVELOCITY) { - caller->vel.x = reference->vel.x; - caller->vel.y = reference->vel.y; - caller->vel.z = reference->vel.z; + caller->Vel = reference->Vel; } if (flags & WARPF_STOP) { - caller->vel.x = 0; - caller->vel.y = 0; - caller->vel.z = 0; + caller->Vel.Zero(); } // this is no fun with line portals if (flags & WARPF_WARPINTERPOLATION) { // This just translates the movement but doesn't change the vector - fixedvec3 displacedold = old + Displacements.getOffset(oldpgroup, caller->Sector->PortalGroup); - caller->PrevX += caller->X() - displacedold.x; - caller->PrevY += caller->Y() - displacedold.y; - caller->PrevZ += caller->Z() - displacedold.z; + DVector3 displacedold = old + Displacements.getOffset(oldpgroup, caller->Sector->PortalGroup); + caller->Prev += caller->Pos() - displacedold; caller->PrevPortalGroup = caller->Sector->PortalGroup; } else if (flags & WARPF_COPYINTERPOLATION) { // Map both positions of the reference actor to the current portal group - fixedvec3 displacedold = old + Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup); - fixedvec3 displacedref = old + Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup); - caller->PrevX = caller->X() + displacedold.x - displacedref.x; - caller->PrevY = caller->Y() + displacedold.y - displacedref.y; - caller->PrevZ = caller->Z() + displacedold.z - displacedref.z; + DVector3 displacedold = old + Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup); + DVector3 displacedref = old + Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup); + caller->Prev = caller->Pos() + displacedold - displacedref; caller->PrevPortalGroup = caller->Sector->PortalGroup; } else if (!(flags & WARPF_INTERPOLATE)) { caller->ClearInterpolation(); } + if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB)) { caller->AddZ(reference->GetBobOffset()); diff --git a/src/p_tick.cpp b/src/p_tick.cpp index 0c9550428..032aa8bf5 100644 --- a/src/p_tick.cpp +++ b/src/p_tick.cpp @@ -21,7 +21,7 @@ // //----------------------------------------------------------------------------- - +#include #include "p_local.h" #include "p_effect.h" #include "c_console.h" @@ -57,7 +57,7 @@ bool P_CheckTickerPaused () ConsoleState == c_down || ConsoleState == c_falling) && !demoplayback && !demorecording - && players[consoleplayer].viewz != 1 + && players[consoleplayer].viewz != NO_VALUE && wipegamestate == gamestate) { S_PauseSound (!(level.flags2 & LEVEL2_PAUSE_MUSIC_IN_MENUS), false); diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 1de5e7059..dabc92110 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -49,23 +49,23 @@ struct FTraceInfo { - fixed_t StartX, StartY, StartZ; - fixed_t Vx, Vy, Vz; + DVector3 Start; + DVector3 Vec; ActorFlags ActorMask; DWORD WallMask; AActor *IgnoreThis; FTraceResults *Results; FTraceResults *TempResults; sector_t *CurSector; - fixed_t MaxDist; - fixed_t EnterDist; + double MaxDist; + double EnterDist; ETraceStatus (*TraceCallback)(FTraceResults &res, void *data); void *TraceCallbackData; DWORD TraceFlags; int inshootthrough; - fixed_t startfrac; + double startfrac; int aimdir; - fixed_t limitz; + double limitz; // These are required for 3D-floor checking // to create a fake sector with a floor @@ -78,8 +78,8 @@ struct FTraceInfo bool ThingCheck(intercept_t *in); bool TraceTraverse (int ptflags); bool CheckPlane(const secplane_t &plane); - int EnterLinePortal(line_t *li, fixed_t frac); - void EnterSectorPortal(int position, fixed_t frac, sector_t *entersec); + int EnterLinePortal(line_t *li, double frac); + void EnterSectorPortal(int position, double frac, sector_t *entersec); bool CheckSectorPlane(const sector_t *sector, bool checkFloor) @@ -94,9 +94,9 @@ struct FTraceInfo void SetSourcePosition() { - Results->SrcFromTarget = { StartX, StartY, StartZ }; - Results->HitVector = { Vx, Vy, Vz }; - Results->SrcAngleToTarget = R_PointToAngle2(0, 0, Results->HitPos.x - StartX, Results->HitPos.y - StartY); + Results->SrcFromTarget = Start; + Results->HitVector = Vec; + Results->SrcAngleFromTarget = Results->HitVector.Angle(); } @@ -111,27 +111,21 @@ static bool EditTraceResult (DWORD flags, FTraceResults &res); // //========================================================================== -bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, - fixed_t vx, fixed_t vy, fixed_t vz, fixed_t maxDist, - ActorFlags actorMask, DWORD wallMask, AActor *ignore, - FTraceResults &res, - DWORD flags, ETraceStatus (*callback)(FTraceResults &res, void *), void *callbackdata) +bool Trace(const DVector3 &start, sector_t *sector, const DVector3 &direction, double maxDist, + ActorFlags actorMask, DWORD wallMask, AActor *ignore, FTraceResults &res, DWORD flags, + ETraceStatus(*callback)(FTraceResults &res, void *), void *callbackdata) { int ptflags; FTraceInfo inf; FTraceResults tempResult; memset(&tempResult, 0, sizeof(tempResult)); - tempResult.Fraction = tempResult.Distance = FIXED_MAX; + tempResult.Fraction = tempResult.Distance = NO_VALUE; ptflags = actorMask ? PT_ADDLINES|PT_ADDTHINGS|PT_COMPATIBLE : PT_ADDLINES; - inf.StartX = x; - inf.StartY = y; - inf.StartZ = z; - inf.Vx = vx; - inf.Vy = vy; - inf.Vz = vz; + inf.Start = start; + inf.Vec = direction; inf.ActorMask = actorMask; inf.WallMask = wallMask; inf.IgnoreThis = ignore; @@ -149,30 +143,6 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, inf.startfrac = 0; memset(&res, 0, sizeof(res)); - // check for overflows and clip if necessary - SQWORD xd = (SQWORD)x + ((SQWORD(vx) * SQWORD(maxDist)) >> 16); - - if (xd>SQWORD(32767)*FRACUNIT) - { - inf.MaxDist = FixedDiv(FIXED_MAX - x, vx); - } - else if (xd<-SQWORD(32767)*FRACUNIT) - { - inf.MaxDist = FixedDiv(FIXED_MIN - x, vx); - } - - - SQWORD yd = (SQWORD)y + ((SQWORD(vy) * SQWORD(maxDist)) >> 16); - - if (yd>SQWORD(32767)*FRACUNIT) - { - inf.MaxDist = FixedDiv(FIXED_MAX - y, vy); - } - else if (yd<-SQWORD(32767)*FRACUNIT) - { - inf.MaxDist = FixedDiv(FIXED_MIN - y, vy); - } - if (inf.TraceTraverse (ptflags)) { return flags ? EditTraceResult(flags, res) : true; @@ -190,37 +160,32 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, // //============================================================================ -void FTraceInfo::EnterSectorPortal(int position, fixed_t frac, sector_t *entersec) +void FTraceInfo::EnterSectorPortal(int position, double frac, sector_t *entersec) { if (aimdir != -1 && aimdir != position) return; AActor *portal = entersec->SkyBoxes[position]; - if (aimdir == sector_t::ceiling && portal->threshold < limitz) return; - else if (aimdir == sector_t::floor && portal->threshold > limitz) return; + if (aimdir == sector_t::ceiling && portal->specialf1 < limitz) return; + else if (aimdir == sector_t::floor && portal->specialf1 > limitz) return; FTraceInfo newtrace; FTraceResults results; memset(&results, 0, sizeof(results)); - newtrace.StartX = StartX + portal->scaleX; - newtrace.StartY = StartY + portal->scaleY; - newtrace.StartZ = StartZ; + newtrace.Start += portal->Scale; - frac += FixedDiv(FRACUNIT, MaxDist); - fixed_t enterdist = FixedMul(MaxDist, frac); - fixed_t enterX = newtrace.StartX + FixedMul(enterdist, Vx); - fixed_t enterY = newtrace.StartY + FixedMul(enterdist, Vy); + frac += 1 / MaxDist; + double enterdist = MaxDist * frac; + DVector2 enter = newtrace.Start.XY() + enterdist * Vec.XY(); - newtrace.Vx = Vx; - newtrace.Vy = Vy; - newtrace.Vz = Vz; + newtrace.Vec = Vec; newtrace.ActorMask = ActorMask; newtrace.WallMask = WallMask; newtrace.IgnoreThis = IgnoreThis; newtrace.Results = &results; newtrace.TempResults = TempResults; - newtrace.CurSector = P_PointInSector(enterX ,enterY); + newtrace.CurSector = P_PointInSector(enter); newtrace.MaxDist = MaxDist; newtrace.EnterDist = EnterDist; newtrace.TraceCallback = TraceCallback; @@ -229,7 +194,7 @@ void FTraceInfo::EnterSectorPortal(int position, fixed_t frac, sector_t *enterse newtrace.inshootthrough = true; newtrace.startfrac = frac; newtrace.aimdir = position; - newtrace.limitz = portal->threshold; + newtrace.limitz = portal->specialf1; newtrace.sectorsel = 0; if (newtrace.TraceTraverse(ActorMask ? PT_ADDLINES | PT_ADDTHINGS | PT_COMPATIBLE : PT_ADDLINES)) @@ -241,11 +206,10 @@ void FTraceInfo::EnterSectorPortal(int position, fixed_t frac, sector_t *enterse //============================================================================ // // traverses a line portal -// simply calling PortalRelocate does not work here because more needs to be set up // //============================================================================ -int FTraceInfo::EnterLinePortal(line_t *li, fixed_t frac) +int FTraceInfo::EnterLinePortal(line_t *li, double frac) { FLinePortal *port = li->getPortal(); @@ -254,28 +218,23 @@ int FTraceInfo::EnterLinePortal(line_t *li, fixed_t frac) FTraceInfo newtrace; - newtrace.StartX = StartX; - newtrace.StartY = StartY; - newtrace.StartZ = StartZ; - newtrace.Vx = Vx; - newtrace.Vy = Vy; - newtrace.Vz = Vz; + newtrace.Start = Start; + newtrace.Vec = Vec; - P_TranslatePortalXY(li, newtrace.StartX, newtrace.StartY); - P_TranslatePortalZ(li, newtrace.StartZ); - P_TranslatePortalVXVY(li, newtrace.Vx, newtrace.Vy); + P_TranslatePortalXY(li, newtrace.Start.X, newtrace.Start.Y); + P_TranslatePortalZ(li, newtrace.Start.Z); + P_TranslatePortalVXVY(li, newtrace.Vec.X, newtrace.Vec.Y); - frac += FixedDiv(FRACUNIT, MaxDist); - fixed_t enterdist = FixedMul(MaxDist, frac); - fixed_t enterX = newtrace.StartX + FixedMul(enterdist, Vx); - fixed_t enterY = newtrace.StartY + FixedMul(enterdist, Vy); + frac += 1 / MaxDist; + double enterdist = MaxDist / frac; + DVector2 enter = newtrace.Start.XY() + enterdist * Vec.XY(); newtrace.ActorMask = ActorMask; newtrace.WallMask = WallMask; newtrace.IgnoreThis = IgnoreThis; newtrace.Results = Results; newtrace.TempResults = TempResults; - newtrace.CurSector = P_PointInSector(enterX, enterY); + newtrace.CurSector = P_PointInSector(enter); newtrace.MaxDist = MaxDist; newtrace.EnterDist = EnterDist; newtrace.TraceCallback = TraceCallback; @@ -307,14 +266,12 @@ void FTraceInfo::Setup3DFloors() CurSector = &DummySector[0]; sectorsel = 1; - fixed_t sdist = FixedMul(MaxDist, startfrac); - fixed_t x = StartX + FixedMul(Vx, sdist); - fixed_t y = StartY + FixedMul(Vy, sdist); - fixed_t z = StartZ + FixedMul(Vz, sdist); + double sdist = MaxDist * startfrac; + DVector3 pos = Start + Vec * sdist; - fixed_t bf = CurSector->floorplane.ZatPoint(x, y); - fixed_t bc = CurSector->ceilingplane.ZatPoint(x, y); + double bf = CurSector->floorplane.ZatPoint(pos); + double bc = CurSector->ceilingplane.ZatPoint(pos); for (auto rover : ff) { @@ -332,10 +289,10 @@ void FTraceInfo::Setup3DFloors() if (!(rover->flags&FF_SHOOTTHROUGH)) { - fixed_t ff_bottom = rover->bottom.plane->ZatPoint(x, y); - fixed_t ff_top = rover->top.plane->ZatPoint(x, y); + double ff_bottom = rover->bottom.plane->ZatPoint(pos); + double ff_top = rover->top.plane->ZatPoint(pos); // clip to the part of the sector we are in - if (z > ff_top) + if (pos.Z > ff_top) { // above if (bf < ff_top) @@ -346,7 +303,7 @@ void FTraceInfo::Setup3DFloors() bf = ff_top; } } - else if (z < ff_bottom) + else if (pos.Z < ff_bottom) { //below if (bc > ff_bottom) @@ -402,12 +359,10 @@ bool FTraceInfo::LineCheck(intercept_t *in) int lineside; sector_t *entersector; - fixed_t dist = FixedMul(MaxDist, in->frac); - fixed_t hitx = StartX + FixedMul(Vx, dist); - fixed_t hity = StartY + FixedMul(Vy, dist); - fixed_t hitz = StartZ + FixedMul(Vz, dist); + double dist = MaxDist * in->frac; + DVector3 hit = Start + Vec * dist; - fixed_t ff, fc, bf = 0, bc = 0; + double ff, fc, bf = 0, bc = 0; if (in->d.line->frontsector->sectornum == CurSector->sectornum) { @@ -426,7 +381,7 @@ bool FTraceInfo::LineCheck(intercept_t *in) } else { - lineside = P_PointOnLineSide(StartX, StartY, in->d.line); + lineside = P_PointOnLineSide(Start, in->d.line); CurSector = lineside ? in->d.line->backsector : in->d.line->frontsector; } } @@ -456,20 +411,20 @@ bool FTraceInfo::LineCheck(intercept_t *in) } } - ff = CurSector->floorplane.ZatPoint(hitx, hity); - fc = CurSector->ceilingplane.ZatPoint(hitx, hity); + ff = CurSector->floorplane.ZatPoint(hit); + fc = CurSector->ceilingplane.ZatPoint(hit); if (entersector != NULL) { - bf = entersector->floorplane.ZatPoint(hitx, hity); - bc = entersector->ceilingplane.ZatPoint(hitx, hity); + bf = entersector->floorplane.ZatPoint(hit); + bc = entersector->ceilingplane.ZatPoint(hit); } sector_t *hsec = CurSector->GetHeightSec(); if (Results->CrossedWater == NULL && hsec != NULL && //CurSector->heightsec->waterzone && - hitz <= hsec->floorplane.ZatPoint(hitx, hity)) + hit.Z <= hsec->floorplane.ZatPoint(hit)) { // hit crossed a water plane if (CheckSectorPlane(hsec, true)) @@ -479,7 +434,7 @@ bool FTraceInfo::LineCheck(intercept_t *in) } } - if (hitz <= ff) + if (hit.Z <= ff) { if (CurSector->PortalBlocksMovement(sector_t::floor)) { @@ -494,7 +449,7 @@ bool FTraceInfo::LineCheck(intercept_t *in) return false; } } - else if (hitz >= fc) + else if (hit.Z >= fc) { if (CurSector->PortalBlocksMovement(sector_t::ceiling)) { @@ -511,7 +466,7 @@ bool FTraceInfo::LineCheck(intercept_t *in) } else if (in->d.line->isLinePortal()) { - if (entersector == NULL || (hitz >= bf && hitz <= bc)) + if (entersector == NULL || (hit.Z >= bf && hit.Z <= bc)) { int res = EnterLinePortal(in->d.line, in->frac); if (res != -1) @@ -523,7 +478,7 @@ bool FTraceInfo::LineCheck(intercept_t *in) goto normalline; // hit upper or lower tier. } else if (entersector == NULL || - hitz < bf || hitz > bc || + hit.Z < bf || hit.Z > bc || in->d.line->flags & WallMask) { normalline: @@ -531,8 +486,8 @@ normalline: Results->HitType = TRACE_HitWall; Results->Tier = entersector == NULL ? TIER_Middle : - hitz <= bf ? TIER_Lower : - hitz >= bc ? TIER_Upper : TIER_Middle; + hit.Z <= bf ? TIER_Lower : + hit.Z >= bc ? TIER_Upper : TIER_Middle; if (TraceFlags & TRACE_Impact) { P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_Impact); @@ -553,11 +508,11 @@ normalline: if (entershootthrough != inshootthrough && rover->flags&FF_EXISTS) { - fixed_t ff_bottom = rover->bottom.plane->ZatPoint(hitx, hity); - fixed_t ff_top = rover->top.plane->ZatPoint(hitx, hity); + double ff_bottom = rover->bottom.plane->ZatPoint(hit); + double ff_top = rover->top.plane->ZatPoint(hit); // clip to the part of the sector we are in - if (hitz > ff_top) + if (hit.Z > ff_top) { // above if (bf < ff_top) @@ -568,7 +523,7 @@ normalline: bf = ff_top; } } - else if (hitz < ff_bottom) + else if (hit.Z < ff_bottom) { //below if (bc > ff_bottom) @@ -632,12 +587,12 @@ cont: } else { - if (hitz <= bf || hitz >= bc) + if (hit.Z <= bf || hit.Z >= bc) { Results->HitType = TRACE_HitWall; Results->Tier = - hitz <= bf ? TIER_Lower : - hitz >= bc ? TIER_Upper : TIER_Middle; + hit.Z <= bf ? TIER_Lower : + hit.Z >= bc ? TIER_Upper : TIER_Middle; } else { @@ -652,7 +607,7 @@ cont: if (Results->HitType == TRACE_HitWall) { - Results->HitPos = { hitx, hity, hitz }; + Results->HitPos = hit; SetSourcePosition(); Results->Distance = dist; Results->Fraction = in->frac; @@ -693,60 +648,54 @@ cont: bool FTraceInfo::ThingCheck(intercept_t *in) { - fixed_t dist = FixedMul(MaxDist, in->frac); - fixed_t hitx = StartX + FixedMul(Vx, dist); - fixed_t hity = StartY + FixedMul(Vy, dist); - fixed_t hitz = StartZ + FixedMul(Vz, dist); + double dist = MaxDist * in->frac; + DVector3 hit = Start + Vec * dist; - if (hitz > in->d.thing->Top()) + if (hit.Z > in->d.thing->Top()) { // trace enters above actor - if (Vz >= 0) return true; // Going up: can't hit + if (Vec.Z >= 0) return true; // Going up: can't hit // Does it hit the top of the actor? - dist = FixedDiv(in->d.thing->Top() - StartZ, Vz); + dist = (in->d.thing->Top() - Start.Z) / Vec.Z; if (dist > MaxDist) return true; - in->frac = FixedDiv(dist, MaxDist); + in->frac = dist / MaxDist; - hitx = StartX + FixedMul(Vx, dist); - hity = StartY + FixedMul(Vy, dist); - hitz = StartZ + FixedMul(Vz, dist); + hit = Start + Vec * dist; // calculated coordinate is outside the actor's bounding box - if (abs(hitx - in->d.thing->X()) > in->d.thing->radius || - abs(hity - in->d.thing->Y()) > in->d.thing->radius) return true; + if (fabs(hit.X - in->d.thing->X()) > in->d.thing->radius || + fabs(hit.Y - in->d.thing->Y()) > in->d.thing->radius) return true; } - else if (hitz < in->d.thing->Z()) + else if (hit.Z < in->d.thing->Z()) { // trace enters below actor - if (Vz <= 0) return true; // Going down: can't hit + if (Vec.Z <= 0) return true; // Going down: can't hit // Does it hit the bottom of the actor? - dist = FixedDiv(in->d.thing->Z() - StartZ, Vz); + dist = (in->d.thing->Z() - Start.Z) / Vec.Z; if (dist > MaxDist) return true; - in->frac = FixedDiv(dist, MaxDist); + in->frac = dist / MaxDist; - hitx = StartX + FixedMul(Vx, dist); - hity = StartY + FixedMul(Vy, dist); - hitz = StartZ + FixedMul(Vz, dist); + hit = Start + Vec * dist; // calculated coordinate is outside the actor's bounding box - if (abs(hitx - in->d.thing->X()) > in->d.thing->radius || - abs(hity - in->d.thing->Y()) > in->d.thing->radius) return true; + if (fabs(hit.X - in->d.thing->X()) > in->d.thing->radius || + fabs(hit.Y - in->d.thing->Y()) > in->d.thing->radius) return true; } if (CurSector->e->XFloor.ffloors.Size()) { // check for 3D floor hits first. - fixed_t ff_floor = CurSector->floorplane.ZatPoint(hitx, hity); - fixed_t ff_ceiling = CurSector->ceilingplane.ZatPoint(hitx, hity); + double ff_floor = CurSector->floorplane.ZatPoint(hit); + double ff_ceiling = CurSector->ceilingplane.ZatPoint(hit); - if (hitz > ff_ceiling && CurSector->PortalBlocksMovement(sector_t::ceiling)) // actor is hit above the current ceiling + if (hit.Z > ff_ceiling && CurSector->PortalBlocksMovement(sector_t::ceiling)) // actor is hit above the current ceiling { Results->HitType = TRACE_HitCeiling; Results->HitTexture = CurSector->GetTexture(sector_t::ceiling); } - else if (hitz < ff_floor && CurSector->PortalBlocksMovement(sector_t::floor)) // actor is hit below the current floor + else if (hit.Z < ff_floor && CurSector->PortalBlocksMovement(sector_t::floor)) // actor is hit below the current floor { Results->HitType = TRACE_HitFloor; Results->HitTexture = CurSector->GetTexture(sector_t::floor); @@ -779,7 +728,7 @@ cont1: Results->HitType = TRACE_HitActor; - Results->HitPos = { hitx, hity, hitz }; + Results->HitPos = hit; SetSourcePosition(); Results->Distance = dist; Results->Fraction = in->frac; @@ -812,7 +761,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) // Do a 3D floor check in the starting sector Setup3DFloors(); - FPathTraverse it(StartX, StartY, FixedMul (Vx, MaxDist), FixedMul (Vy, MaxDist), ptflags | PT_DELTA, startfrac); + FPathTraverse it(Start.X, Start.Y, Vec.X * MaxDist, Vec.Y * MaxDist, ptflags | PT_DELTA, startfrac); intercept_t *in; int lastsplashsector = -1; @@ -859,7 +808,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) // We still need to do a water check here or this may get missed on occasion if (Results->CrossedWater == NULL && CurSector->heightsec != NULL && - CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.z) + CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.Z) { // Save the result so that the water check doesn't destroy it. FTraceResults *res = Results; @@ -896,7 +845,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) if (Results->CrossedWater == NULL && CurSector->heightsec != NULL && - CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.z) + CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.Z) { // Save the result so that the water check doesn't destroy it. FTraceResults *res = Results; @@ -912,13 +861,10 @@ bool FTraceInfo::TraceTraverse (int ptflags) } if (Results->HitType == TRACE_HitNone && Results->Distance == 0) { - Results->HitPos = { - StartX + FixedMul(Vx, MaxDist), - StartY + FixedMul(Vy, MaxDist), - StartZ + FixedMul(Vz, MaxDist) }; + Results->HitPos = Start + Vec * MaxDist; SetSourcePosition(); Results->Distance = MaxDist; - Results->Fraction = FRACUNIT; + Results->Fraction = 1.; } return Results->HitType != TRACE_HitNone; } @@ -931,25 +877,20 @@ bool FTraceInfo::TraceTraverse (int ptflags) bool FTraceInfo::CheckPlane (const secplane_t &plane) { - fixed_t den = TMulScale16 (plane.a, Vx, plane.b, Vy, plane.c, Vz); + double den = plane.Normal() | Vec; if (den != 0) { - fixed_t num = TMulScale16 (plane.a, StartX, - plane.b, StartY, - plane.c, StartZ) + plane.d; + double num = (plane.Normal() | Start) + plane.fD(); - fixed_t hitdist = FixedDiv (-num, den); + double hitdist = -num / den; if (hitdist > EnterDist && hitdist < MaxDist) { - Results->HitPos = { - StartX + FixedMul(Vx, hitdist), - StartY + FixedMul(Vy, hitdist), - StartZ + FixedMul(Vz, hitdist) }; + Results->HitPos = Start + Vec * hitdist; SetSourcePosition(); Results->Distance = hitdist; - Results->Fraction = FixedDiv (hitdist, MaxDist); + Results->Fraction = hitdist / MaxDist; return true; } } diff --git a/src/p_trace.h b/src/p_trace.h index 43203f035..2c817816e 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -65,13 +65,13 @@ struct FTraceResults { sector_t *Sector; FTextureID HitTexture; - fixedvec3 HitPos; - fixedvec3 HitVector; - fixedvec3 SrcFromTarget; - angle_t SrcAngleToTarget; + DVector3 HitPos; + DVector3 HitVector; + DVector3 SrcFromTarget; + DAngle SrcAngleFromTarget; - fixed_t Distance; - fixed_t Fraction; + double Distance; + double Fraction; AActor *Actor; // valid if hit an actor @@ -83,9 +83,9 @@ struct FTraceResults F3DFloor *ffloor; sector_t *CrossedWater; // For Boom-style, Transfer_Heights-based deep water - fixedvec3 CrossedWaterPos; // remember the position so that we can use it for spawning the splash + DVector3 CrossedWaterPos; // remember the position so that we can use it for spawning the splash F3DFloor *Crossed3DWater; // For 3D floor-based deep water - fixedvec3 Crossed3DWaterPos; + DVector3 Crossed3DWaterPos; void CopyIfCloser(FTraceResults *other) { @@ -124,11 +124,8 @@ enum ETraceStatus TRACE_Abort, // stop the trace, returning no hits }; -bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, - fixed_t vx, fixed_t vy, fixed_t vz, fixed_t maxDist, - ActorFlags ActorMask, DWORD WallMask, AActor *ignore, - FTraceResults &res, - DWORD traceFlags=0, - ETraceStatus (*callback)(FTraceResults &res, void *)=NULL, void *callbackdata=NULL); +bool Trace(const DVector3 &start, sector_t *sector, const DVector3 &direction, double maxDist, + ActorFlags ActorMask, DWORD WallMask, AActor *ignore, FTraceResults &res, DWORD traceFlags = 0, + ETraceStatus(*callback)(FTraceResults &res, void *) = NULL, void *callbackdata = NULL); #endif //__P_TRACE_H__ diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 778e99adf..35ad22f63 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -252,14 +252,9 @@ double UDMFParserBase::CheckFloat(const char *key) return sc.Float; } -fixed_t UDMFParserBase::CheckFixed(const char *key) +DAngle UDMFParserBase::CheckAngle(const char *key) { - return FLOAT2FIXED(CheckFloat(key)); -} - -angle_t UDMFParserBase::CheckAngle(const char *key) -{ - return FLOAT2ANGLE(CheckFloat(key)); + return DAngle(CheckFloat(key)).Normalized360(); } bool UDMFParserBase::CheckBool(const char *key) @@ -358,7 +353,7 @@ int GetUDMFInt(int type, int index, const char *key) return 0; } -fixed_t GetUDMFFixed(int type, int index, const char *key) +double GetUDMFFloat(int type, int index, const char *key) { assert(type >=0 && type <=3); @@ -369,7 +364,7 @@ fixed_t GetUDMFFixed(int type, int index, const char *key) FUDMFKey *pKey = pKeys->Find(key); if (pKey != NULL) { - return FLOAT2FIXED(pKey->FloatVal); + return pKey->FloatVal; } } return 0; @@ -471,9 +466,9 @@ public: FString arg0str, arg1str; memset(th, 0, sizeof(*th)); - th->gravity = FRACUNIT; + th->Gravity = 1; th->RenderStyle = STYLE_Count; - th->alpha = -1; + th->Alpha = -1; th->health = 1; th->FloatbobPhase = -1; sc.MustGetToken('{'); @@ -487,15 +482,15 @@ public: break; case NAME_X: - th->x = CheckFixed(key); + th->pos.X = CheckFloat(key); break; case NAME_Y: - th->y = CheckFixed(key); + th->pos.Y = CheckFloat(key); break; case NAME_Height: - th->z = CheckFixed(key); + th->pos.Z = CheckFloat(key); break; case NAME_Angle: @@ -519,7 +514,7 @@ public: case NAME_Gravity: CHECK_N(Zd | Zdt) - th->gravity = CheckFixed(key); + th->Gravity = CheckFloat(key); break; case NAME_Arg0: @@ -694,7 +689,7 @@ public: break; case NAME_Alpha: - th->alpha = CheckFixed(key); + th->Alpha = CheckFloat(key); break; case NAME_FillColor: @@ -718,15 +713,15 @@ public: break; case NAME_ScaleX: - th->scaleX = CheckFixed(key); + th->Scale.X = CheckFloat(key); break; case NAME_ScaleY: - th->scaleY = CheckFixed(key); + th->Scale.Y = CheckFloat(key); break; case NAME_Scale: - th->scaleX = th->scaleY = CheckFixed(key); + th->Scale.X = th->Scale.Y = CheckFloat(key); break; default: @@ -790,7 +785,7 @@ public: FString tagstring; memset(ld, 0, sizeof(*ld)); - ld->Alpha = FRACUNIT; + ld->Alpha = OPAQUE; ld->portalindex = UINT_MAX; ld->sidedef[0] = ld->sidedef[1] = NULL; if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; @@ -970,7 +965,7 @@ public: if (namespace_bits & (Zd|Zdt|Va)) switch(key) { case NAME_Alpha: - ld->Alpha = CheckFixed(key); + ld->setAlpha(CheckFloat(key)); continue; case NAME_Renderstyle: @@ -1092,13 +1087,13 @@ public: { ld->activation = (ld->activation & ~SPAC_Use) | SPAC_UseThrough; } - if (strifetrans && ld->Alpha == FRACUNIT) + if (strifetrans && ld->Alpha == OPAQUE) { - ld->Alpha = FRACUNIT * 3/4; + ld->Alpha = TRANSLUC75; } - if (strifetrans2 && ld->Alpha == FRACUNIT) + if (strifetrans2 && ld->Alpha == OPAQUE) { - ld->Alpha = FRACUNIT * 1/4; + ld->Alpha = TRANSLUC25; } if (ld->sidedef[0] == NULL) { @@ -1127,14 +1122,14 @@ public: void ParseSidedef(side_t *sd, intmapsidedef_t *sdt, int index) { - fixed_t texofs[2]={0,0}; + double texOfs[2]={0,0}; memset(sd, 0, sizeof(*sd)); sdt->bottomtexture = "-"; sdt->toptexture = "-"; sdt->midtexture = "-"; - sd->SetTextureXScale(FRACUNIT); - sd->SetTextureYScale(FRACUNIT); + sd->SetTextureXScale(1.); + sd->SetTextureYScale(1.); sd->Index = index; sc.MustGetToken('{'); @@ -1144,11 +1139,11 @@ public: switch(key) { case NAME_Offsetx: - texofs[0] = CheckInt(key) << FRACBITS; + texOfs[0] = CheckInt(key); continue; case NAME_Offsety: - texofs[1] = CheckInt(key) << FRACBITS; + texOfs[1] = CheckInt(key); continue; case NAME_Texturetop: @@ -1174,51 +1169,51 @@ public: if (namespace_bits & (Zd|Zdt|Va)) switch(key) { case NAME_offsetx_top: - sd->SetTextureXOffset(side_t::top, CheckFixed(key)); + sd->SetTextureXOffset(side_t::top, CheckFloat(key)); continue; case NAME_offsety_top: - sd->SetTextureYOffset(side_t::top, CheckFixed(key)); + sd->SetTextureYOffset(side_t::top, CheckFloat(key)); continue; case NAME_offsetx_mid: - sd->SetTextureXOffset(side_t::mid, CheckFixed(key)); + sd->SetTextureXOffset(side_t::mid, CheckFloat(key)); continue; case NAME_offsety_mid: - sd->SetTextureYOffset(side_t::mid, CheckFixed(key)); + sd->SetTextureYOffset(side_t::mid, CheckFloat(key)); continue; case NAME_offsetx_bottom: - sd->SetTextureXOffset(side_t::bottom, CheckFixed(key)); + sd->SetTextureXOffset(side_t::bottom, CheckFloat(key)); continue; case NAME_offsety_bottom: - sd->SetTextureYOffset(side_t::bottom, CheckFixed(key)); + sd->SetTextureYOffset(side_t::bottom, CheckFloat(key)); continue; case NAME_scalex_top: - sd->SetTextureXScale(side_t::top, CheckFixed(key)); + sd->SetTextureXScale(side_t::top, CheckFloat(key)); continue; case NAME_scaley_top: - sd->SetTextureYScale(side_t::top, CheckFixed(key)); + sd->SetTextureYScale(side_t::top, CheckFloat(key)); continue; case NAME_scalex_mid: - sd->SetTextureXScale(side_t::mid, CheckFixed(key)); + sd->SetTextureXScale(side_t::mid, CheckFloat(key)); continue; case NAME_scaley_mid: - sd->SetTextureYScale(side_t::mid, CheckFixed(key)); + sd->SetTextureYScale(side_t::mid, CheckFloat(key)); continue; case NAME_scalex_bottom: - sd->SetTextureXScale(side_t::bottom, CheckFixed(key)); + sd->SetTextureXScale(side_t::bottom, CheckFloat(key)); continue; case NAME_scaley_bottom: - sd->SetTextureYScale(side_t::bottom, CheckFixed(key)); + sd->SetTextureYScale(side_t::bottom, CheckFloat(key)); continue; case NAME_light: @@ -1263,12 +1258,12 @@ public: } } // initialization of these is delayed to allow separate offsets and add them with the global ones. - sd->AddTextureXOffset(side_t::top, texofs[0]); - sd->AddTextureXOffset(side_t::mid, texofs[0]); - sd->AddTextureXOffset(side_t::bottom, texofs[0]); - sd->AddTextureYOffset(side_t::top, texofs[1]); - sd->AddTextureYOffset(side_t::mid, texofs[1]); - sd->AddTextureYOffset(side_t::bottom, texofs[1]); + sd->AddTextureXOffset(side_t::top, texOfs[0]); + sd->AddTextureXOffset(side_t::mid, texOfs[0]); + sd->AddTextureXOffset(side_t::bottom, texOfs[0]); + sd->AddTextureYOffset(side_t::top, texOfs[1]); + sd->AddTextureYOffset(side_t::mid, texOfs[1]); + sd->AddTextureYOffset(side_t::bottom, texOfs[1]); } //=========================================================================== @@ -1288,12 +1283,12 @@ public: memset(sec, 0, sizeof(*sec)); sec->lightlevel = 160; - sec->SetXScale(sector_t::floor, FRACUNIT); // [RH] floor and ceiling scaling - sec->SetYScale(sector_t::floor, FRACUNIT); - sec->SetXScale(sector_t::ceiling, FRACUNIT); - sec->SetYScale(sector_t::ceiling, FRACUNIT); - sec->SetAlpha(sector_t::floor, FRACUNIT); - sec->SetAlpha(sector_t::ceiling, FRACUNIT); + sec->SetXScale(sector_t::floor, 1.); // [RH] floor and ceiling scaling + sec->SetYScale(sector_t::floor, 1.); + sec->SetXScale(sector_t::ceiling, 1.); + sec->SetYScale(sector_t::ceiling, 1.); + sec->SetAlpha(sector_t::floor, 1.); + sec->SetAlpha(sector_t::ceiling, 1.); sec->thinglist = NULL; sec->touching_thinglist = NULL; // phares 3/14/98 sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1; @@ -1306,7 +1301,7 @@ public: if (floordrop) sec->Flags = SECF_FLOORDROP; // killough 3/7/98: end changes - sec->gravity = 1.f; // [RH] Default sector gravity of 1.0 + sec->gravity = 1.; // [RH] Default sector gravity of 1.0 sec->ZoneNumber = 0xFFFF; // killough 8/28/98: initialize all sectors to normal friction @@ -1320,11 +1315,11 @@ public: switch(key) { case NAME_Heightfloor: - sec->SetPlaneTexZ(sector_t::floor, CheckInt(key) << FRACBITS); + sec->SetPlaneTexZ(sector_t::floor, CheckFloat(key)); continue; case NAME_Heightceiling: - sec->SetPlaneTexZ(sector_t::ceiling, CheckInt(key) << FRACBITS); + sec->SetPlaneTexZ(sector_t::ceiling, CheckFloat(key)); continue; case NAME_Texturefloor: @@ -1360,35 +1355,35 @@ public: if (namespace_bits & (Zd|Zdt|Va)) switch(key) { case NAME_Xpanningfloor: - sec->SetXOffset(sector_t::floor, CheckFixed(key)); + sec->SetXOffset(sector_t::floor, CheckFloat(key)); continue; case NAME_Ypanningfloor: - sec->SetYOffset(sector_t::floor, CheckFixed(key)); + sec->SetYOffset(sector_t::floor, CheckFloat(key)); continue; case NAME_Xpanningceiling: - sec->SetXOffset(sector_t::ceiling, CheckFixed(key)); + sec->SetXOffset(sector_t::ceiling, CheckFloat(key)); continue; case NAME_Ypanningceiling: - sec->SetYOffset(sector_t::ceiling, CheckFixed(key)); + sec->SetYOffset(sector_t::ceiling, CheckFloat(key)); continue; case NAME_Xscalefloor: - sec->SetXScale(sector_t::floor, CheckFixed(key)); + sec->SetXScale(sector_t::floor, CheckFloat(key)); continue; case NAME_Yscalefloor: - sec->SetYScale(sector_t::floor, CheckFixed(key)); + sec->SetYScale(sector_t::floor, CheckFloat(key)); continue; case NAME_Xscaleceiling: - sec->SetXScale(sector_t::ceiling, CheckFixed(key)); + sec->SetXScale(sector_t::ceiling, CheckFloat(key)); continue; case NAME_Yscaleceiling: - sec->SetYScale(sector_t::ceiling, CheckFixed(key)); + sec->SetYScale(sector_t::ceiling, CheckFloat(key)); continue; case NAME_Rotationfloor: @@ -1408,11 +1403,11 @@ public: continue; case NAME_Alphafloor: - sec->SetAlpha(sector_t::floor, CheckFixed(key)); + sec->SetAlpha(sector_t::floor, CheckFloat(key)); continue; case NAME_Alphaceiling: - sec->SetAlpha(sector_t::ceiling, CheckFixed(key)); + sec->SetAlpha(sector_t::ceiling, CheckFloat(key)); continue; case NAME_Renderstylefloor: @@ -1444,7 +1439,7 @@ public: continue; case NAME_Gravity: - sec->gravity = float(CheckFloat(key)); + sec->gravity = CheckFloat(key); continue; case NAME_Lightcolor: @@ -1600,39 +1595,22 @@ public: // Reset the planes to their defaults if not all of the plane equation's parameters were found. if (fplaneflags != 15) { - sec->floorplane.a = sec->floorplane.b = 0; - sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor); - sec->floorplane.c = FRACUNIT; - sec->floorplane.ic = FRACUNIT; + sec->floorplane.SetAtHeight(sec->GetPlaneTexZF(sector_t::floor), sector_t::floor); } else { - double ulen = DVector3(fp[0], fp[1], fp[2]).Length(); - // normalize the vector, it must have a length of 1 - sec->floorplane.a = FLOAT2FIXED(fp[0] / ulen); - sec->floorplane.b = FLOAT2FIXED(fp[1] / ulen); - sec->floorplane.c = FLOAT2FIXED(fp[2] / ulen); - sec->floorplane.d = FLOAT2FIXED(fp[3] / ulen); - sec->floorplane.ic = FLOAT2FIXED(ulen / fp[2]); + DVector3 n = DVector3(fp[0], fp[1], fp[2]).Unit(); + sec->floorplane.set(n.X, n.Y, n.Z, fp[3]); } if (cplaneflags != 15) { - sec->ceilingplane.a = sec->ceilingplane.b = 0; - sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling); - sec->ceilingplane.c = -FRACUNIT; - sec->ceilingplane.ic = -FRACUNIT; + sec->ceilingplane.SetAtHeight(sec->GetPlaneTexZF(sector_t::ceiling), sector_t::ceiling); } else { - double ulen = DVector3(cp[0], cp[1], cp[2]).Length(); - - // normalize the vector, it must have a length of 1 - sec->ceilingplane.a = FLOAT2FIXED(cp[0] / ulen); - sec->ceilingplane.b = FLOAT2FIXED(cp[1] / ulen); - sec->ceilingplane.c = FLOAT2FIXED(cp[2] / ulen); - sec->ceilingplane.d = FLOAT2FIXED(cp[3] / ulen); - sec->ceilingplane.ic = FLOAT2FIXED(ulen / cp[2]); + DVector3 n = DVector3(cp[0], cp[1], cp[2]).Unit(); + sec->ceilingplane.set(n.X, n.Y, n.Z, cp[3]); } if (lightcolor == -1 && fadecolor == -1 && desaturation == -1) @@ -1676,34 +1654,31 @@ public: void ParseVertex(vertex_t *vt, vertexdata_t *vd) { - vt->x = vt->y = 0; + vt->set(0, 0); vd->zCeiling = vd->zFloor = vd->flags = 0; - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) + + sc.MustGetToken('{'); + double x, y; + while (!sc.CheckToken('}')) { - sc.MustGetString(); - FName key = sc.String; - sc.MustGetStringName("="); - sc.MustGetString(); - FString value = sc.String; - sc.MustGetStringName(";"); - switch(key) + FName key = ParseKey(); + switch (key) { case NAME_X: - vt->x = FLOAT2FIXED(strtod(value, NULL)); + x = CheckFloat(key); break; case NAME_Y: - vt->y = FLOAT2FIXED(strtod(value, NULL)); + y = CheckFloat(key); break; case NAME_ZCeiling: - vd->zCeiling = FLOAT2FIXED(strtod(value, NULL)); + vd->zCeiling = CheckFloat(key); vd->flags |= VERTEXFLAG_ZCeilingEnabled; break; case NAME_ZFloor: - vd->zFloor = FLOAT2FIXED(strtod(value, NULL)); + vd->zFloor = CheckFloat(key); vd->flags |= VERTEXFLAG_ZFloorEnabled; break; @@ -1711,6 +1686,7 @@ public: break; } } + vt->set(x, y); } //=========================================================================== @@ -1733,7 +1709,7 @@ public: I_Error ("Line %d has invalid vertices: %zd and/or %zd.\nThe map only contains %d vertices.", i+skipped, v1i, v2i, numvertexes); } else if (v1i == v2i || - (vertexes[v1i].x == vertexes[v2i].x && vertexes[v1i].y == vertexes[v2i].y)) + (vertexes[v1i].fX() == vertexes[v2i].fX() && vertexes[v1i].fY() == vertexes[v2i].fY())) { Printf ("Removing 0-length line %d\n", i+skipped); ParsedLines.Delete(i); diff --git a/src/p_udmf.h b/src/p_udmf.h index 7fa7cf614..9e7bce5e2 100644 --- a/src/p_udmf.h +++ b/src/p_udmf.h @@ -17,8 +17,7 @@ protected: FName ParseKey(bool checkblock = false, bool *isblock = NULL); int CheckInt(const char *key); double CheckFloat(const char *key); - fixed_t CheckFixed(const char *key); - angle_t CheckAngle(const char *key); + DAngle CheckAngle(const char *key); bool CheckBool(const char *key); const char *CheckString(const char *key); diff --git a/src/p_user.cpp b/src/p_user.cpp index 5a26d46f3..63f05ef32 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -83,11 +83,8 @@ CUSTOM_CVAR(Float, cl_predict_lerpthreshold, 2.00f, CVAR_ARCHIVE | CVAR_GLOBALCO struct PredictPos { int gametic; - fixed_t x; - fixed_t y; - fixed_t z; - fixed_t pitch; - fixed_t yaw; + DVector3 pos; + DRotator angles; } static PredictionLerpFrom, PredictionLerpResult, PredictionLast; static int PredictionLerptics; @@ -238,7 +235,7 @@ CCMD (playerclasses) // // 16 pixels of bob -#define MAXBOB 0x100000 +#define MAXBOB 16. FArchive &operator<< (FArchive &arc, player_t *&p) { @@ -257,7 +254,7 @@ player_t::player_t() viewheight(0), deltaviewheight(0), bob(0), - vel({ 0,0 }), + Vel(0, 0), centering(0), turnticks(0), attackdown(0), @@ -313,7 +310,7 @@ player_t::player_t() crouchviewdelta(0), ConversationNPC(0), ConversationPC(0), - ConversationNPCAngle(0), + ConversationNPCAngle(0.), ConversationFaceTalker(0) { memset (&cmd, 0, sizeof(cmd)); @@ -336,8 +333,7 @@ player_t &player_t::operator=(const player_t &p) viewheight = p.viewheight; deltaviewheight = p.deltaviewheight; bob = p.bob; - vel.x = p.vel.x; - vel.y = p.vel.y; + Vel = p.Vel; centering = p.centering; turnticks = p.turnticks; attackdown = p.attackdown; @@ -647,28 +643,10 @@ void APlayerPawn::Serialize (FArchive &arc) << DamageFade << PlayerFlags << FlechetteType; - if (SaveVersion < 3829) - { - GruntSpeed = 12*FRACUNIT; - FallingScreamMinSpeed = 35*FRACUNIT; - FallingScreamMaxSpeed = 40*FRACUNIT; - } - else - { - arc << GruntSpeed << FallingScreamMinSpeed << FallingScreamMaxSpeed; - } - if (SaveVersion >= 4502) - { - arc << UseRange; - } - if (SaveVersion >= 4503) - { - arc << AirCapacity; - } - if (SaveVersion >= 4526) - { - arc << ViewHeight; - } + arc << GruntSpeed << FallingScreamMinSpeed << FallingScreamMaxSpeed; + arc << UseRange; + arc << AirCapacity; + arc << ViewHeight; } //=========================================================================== @@ -745,11 +723,11 @@ void APlayerPawn::Tick() { if (player != NULL && player->mo == this && player->CanCrouch() && player->playerstate != PST_DEAD) { - height = FixedMul(GetDefault()->height, player->crouchfactor); + Height = GetDefault()->Height * player->crouchfactor; } else { - if (health > 0) height = GetDefault()->height; + if (health > 0) Height = GetDefault()->Height; } Super::Tick(); } @@ -1054,7 +1032,7 @@ void APlayerPawn::GiveDeathmatchInventory() AKey *key = (AKey *)GetDefaultByType (PClassActor::AllActorClasses[i]); if (key->KeyNumber != 0) { - key = static_cast(Spawn(static_cast(PClassActor::AllActorClasses[i]), 0,0,0, NO_REPLACE)); + key = static_cast(Spawn(static_cast(PClassActor::AllActorClasses[i]))); if (!key->CallTryPickup (this)) { key->Destroy (); @@ -1226,10 +1204,10 @@ int APlayerPawn::GetMaxHealth() const // //=========================================================================== -bool APlayerPawn::UpdateWaterLevel (fixed_t oldz, bool splash) +bool APlayerPawn::UpdateWaterLevel (bool splash) { int oldlevel = waterlevel; - bool retval = Super::UpdateWaterLevel (oldz, splash); + bool retval = Super::UpdateWaterLevel (splash); if (player != NULL) { if (oldlevel < 3 && waterlevel == 3) @@ -1266,7 +1244,7 @@ bool APlayerPawn::ResetAirSupply (bool playgasp) { S_Sound (this, CHAN_VOICE, "*gasp", 1, ATTN_NORM); } - if (level.airsupply> 0 && player->mo->AirCapacity > 0) player->air_finished = level.time + FixedMul(level.airsupply, player->mo->AirCapacity); + if (level.airsupply> 0 && player->mo->AirCapacity > 0) player->air_finished = level.time + int(level.airsupply * player->mo->AirCapacity); else player->air_finished = INT_MAX; return wasdrowning; } @@ -1328,7 +1306,7 @@ void APlayerPawn::GiveDefaultInventory () // BasicArmor must come right after that. It should not affect any // other protection item as well but needs to process the damage // before the HexenArmor does. - ABasicArmor *barmor = Spawn (0,0,0, NO_REPLACE); + ABasicArmor *barmor = Spawn (); barmor->BecomeItem (); barmor->SavePercent = 0; barmor->Amount = 0; @@ -1351,7 +1329,7 @@ void APlayerPawn::GiveDefaultInventory () } else { - item = static_cast(Spawn (ti, 0,0,0, NO_REPLACE)); + item = static_cast(Spawn (ti)); item->ItemFlags |= IF_IGNORESKILL; // no skill multiplicators here item->Amount = di->Amount; if (item->IsKindOf (RUNTIME_CLASS (AWeapon))) @@ -1512,38 +1490,40 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags) // //=========================================================================== -void APlayerPawn::TweakSpeeds (int &forward, int &side) +void APlayerPawn::TweakSpeeds (double &forward, double &side) { - // Strife's player can't run when its healh is below 10 + // Strife's player can't run when its health is below 10 if (health <= RunHealth) { - forward = clamp(forward, -0x1900, 0x1900); - side = clamp(side, -0x1800, 0x1800); + forward = clamp(forward, -0x1900, 0x1900); + side = clamp(side, -0x1800, 0x1800); } // [GRB] - if ((unsigned int)(forward + 0x31ff) < 0x63ff) + if (fabs(forward) < 0x3200) { - forward = FixedMul (forward, ForwardMove1); + forward *= ForwardMove1; } else { - forward = FixedMul (forward, ForwardMove2); + forward *= ForwardMove2; } + + if (fabs(side) < 0x2800) if ((unsigned int)(side + 0x27ff) < 0x4fff) { - side = FixedMul (side, SideMove1); + side *= SideMove1; } else { - side = FixedMul (side, SideMove2); + side *= SideMove2; } if (!player->morphTics && Inventory != NULL) { - fixed_t factor = Inventory->GetSpeedFactor (); - forward = FixedMul(forward, factor); - side = FixedMul(side, factor); + double factor = Inventory->GetSpeedFactor (); + forward *= factor; + side *= factor; } } @@ -1579,7 +1559,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerScream) // Handle the different player death screams if ((((level.flags >> 15) | (dmflags)) & (DF_FORCE_FALLINGZD | DF_FORCE_FALLINGHX)) && - self->vel.z <= -39*FRACUNIT) + self->Vel.Z <= -39) { sound = S_FindSkinnedSound (self, "*splat"); chan = CHAN_BODY; @@ -1649,18 +1629,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullPop) } self->flags &= ~MF_SOLID; - mo = (APlayerPawn *)Spawn (spawntype, self->PosPlusZ(48*FRACUNIT), NO_REPLACE); + mo = (APlayerPawn *)Spawn (spawntype, self->PosPlusZ(48.), NO_REPLACE); //mo->target = self; - mo->vel.x = pr_skullpop.Random2() << 9; - mo->vel.y = pr_skullpop.Random2() << 9; - mo->vel.z = 2*FRACUNIT + (pr_skullpop() << 6); + mo->Vel.X = pr_skullpop.Random2() / 128.; + mo->Vel.Y = pr_skullpop.Random2() / 128.; + mo->Vel.Z = 2. + (pr_skullpop() / 1024.); // Attach player mobj to bloody skull player = self->player; self->player = NULL; mo->ObtainInventory (self); mo->player = player; mo->health = self->health; - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; if (player != NULL) { player->mo = mo; @@ -1702,7 +1682,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckPlayerDone) // //=========================================================================== -void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t &scaley) +void P_CheckPlayerSprite(AActor *actor, int &spritenum, DVector2 &scale) { player_t *player = actor->player; int crouchspriteno; @@ -1710,14 +1690,13 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t if (player->userinfo.GetSkin() != 0 && !(actor->flags4 & MF4_NOSKIN)) { // Convert from default scale to skin scale. - fixed_t defscaleY = actor->GetDefault()->scaleY; - fixed_t defscaleX = actor->GetDefault()->scaleX; - scaley = Scale(scaley, skins[player->userinfo.GetSkin()].ScaleY, defscaleY); - scalex = Scale(scalex, skins[player->userinfo.GetSkin()].ScaleX, defscaleX); + DVector2 defscale = actor->GetDefault()->Scale; + scale.X *= skins[player->userinfo.GetSkin()].Scale.X / defscale.X; + scale.Y *= skins[player->userinfo.GetSkin()].Scale.Y / defscale.Y; } // Set the crouch sprite? - if (player->crouchfactor < FRACUNIT*3/4) + if (player->crouchfactor < 0.75) { if (spritenum == actor->SpawnState->sprite || spritenum == player->mo->crouchsprite) { @@ -1738,9 +1717,9 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t { spritenum = crouchspriteno; } - else if (player->playerstate != PST_DEAD && player->crouchfactor < FRACUNIT*3/4) + else if (player->playerstate != PST_DEAD && player->crouchfactor < 0.75) { - scaley /= 2; + scale.Y *= 0.5; } } } @@ -1755,30 +1734,23 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t ================== */ -void P_SideThrust (player_t *player, angle_t angle, fixed_t move) +void P_SideThrust (player_t *player, DAngle angle, double move) { - angle = (angle - ANGLE_90) >> ANGLETOFINESHIFT; - - player->mo->vel.x += FixedMul (move, finecosine[angle]); - player->mo->vel.y += FixedMul (move, finesine[angle]); + player->mo->Thrust(angle-90, move); } -void P_ForwardThrust (player_t *player, angle_t angle, fixed_t move) +void P_ForwardThrust (player_t *player, DAngle angle, double move) { - angle >>= ANGLETOFINESHIFT; - if ((player->mo->waterlevel || (player->mo->flags & MF_NOGRAVITY)) - && player->mo->pitch != 0) + && player->mo->Angles.Pitch != 0) { - angle_t pitch = (angle_t)player->mo->pitch >> ANGLETOFINESHIFT; - fixed_t zpush = FixedMul (move, finesine[pitch]); + double zpush = move * player->mo->Angles.Pitch.Sin(); if (player->mo->waterlevel && player->mo->waterlevel < 2 && zpush < 0) zpush = 0; - player->mo->vel.z -= zpush; - move = FixedMul (move, finecosine[pitch]); + player->mo->Vel.Z -= zpush; + move *= player->mo->Angles.Pitch.Cos(); } - player->mo->vel.x += FixedMul (move, finecosine[angle]); - player->mo->vel.y += FixedMul (move, finesine[angle]); + player->mo->Thrust(angle, move); } // @@ -1792,20 +1764,15 @@ void P_ForwardThrust (player_t *player, angle_t angle, fixed_t move) // reduced at a regular rate, even on ice (where the player coasts). // -void P_Bob (player_t *player, angle_t angle, fixed_t move, bool forward) +void P_Bob (player_t *player, DAngle angle, double move, bool forward) { if (forward && (player->mo->waterlevel || (player->mo->flags & MF_NOGRAVITY)) - && player->mo->pitch != 0) + && player->mo->Angles.Pitch != 0) { - angle_t pitch = (angle_t)player->mo->pitch >> ANGLETOFINESHIFT; - move = FixedMul (move, finecosine[pitch]); + move *= player->mo->Angles.Pitch.Cos(); } - - angle >>= ANGLETOFINESHIFT; - - player->vel.x += FixedMul(move, finecosine[angle]); - player->vel.y += FixedMul(move, finesine[angle]); + player->Vel += angle.ToVector(move); } /* @@ -1821,8 +1788,8 @@ Calculate the walking / running height adjustment void P_CalcHeight (player_t *player) { - int angle; - fixed_t bob; + DAngle angle; + double bob; bool still = false; // Regular movement bobbing @@ -1840,32 +1807,32 @@ void P_CalcHeight (player_t *player) } else if ((player->mo->flags & MF_NOGRAVITY) && !player->onground) { - player->bob = FRACUNIT / 2; + player->bob = 0.5; } else { - player->bob = DMulScale16 (player->vel.x, player->vel.x, player->vel.y, player->vel.y); + player->bob = player->Vel.LengthSquared(); if (player->bob == 0) { still = true; } else { - player->bob = FixedMul (player->bob, player->userinfo.GetMoveBob()); + player->bob *= player->userinfo.GetMoveBob(); if (player->bob > MAXBOB) player->bob = MAXBOB; } } - fixed_t defaultviewheight = player->mo->ViewHeight + player->crouchviewdelta; + double defaultviewheight = player->mo->ViewHeight + player->crouchviewdelta; if (player->cheats & CF_NOVELOCITY) { player->viewz = player->mo->Z() + defaultviewheight; - if (player->viewz > player->mo->ceilingz-4*FRACUNIT) - player->viewz = player->mo->ceilingz-4*FRACUNIT; + if (player->viewz > player->mo->ceilingz-4) + player->viewz = player->mo->ceilingz-4; return; } @@ -1874,8 +1841,8 @@ void P_CalcHeight (player_t *player) { if (player->health > 0) { - angle = DivScale13 (level.time, 120*TICRATE/35) & FINEMASK; - bob = FixedMul (player->userinfo.GetStillBob(), finesine[angle]); + angle = level.time / (120 * TICRATE / 35.) * 360.; + bob = player->userinfo.GetStillBob() * angle.Sin(); } else { @@ -1884,9 +1851,8 @@ void P_CalcHeight (player_t *player) } else { - // DivScale 13 because FINEANGLES == (1<<13) - angle = DivScale13 (level.time, 20*TICRATE/35) & FINEMASK; - bob = FixedMul (player->bob>>(player->mo->waterlevel > 1 ? 2 : 1), finesine[angle]); + angle = level.time / (20 * TICRATE / 35.) * 360.; + bob = player->bob * angle.Sin() * (player->mo->waterlevel > 1 ? 0.25f : 0.5f); } // move viewheight @@ -1899,18 +1865,18 @@ void P_CalcHeight (player_t *player) player->viewheight = defaultviewheight; player->deltaviewheight = 0; } - else if (player->viewheight < (defaultviewheight>>1)) + else if (player->viewheight < (defaultviewheight/2)) { - player->viewheight = defaultviewheight>>1; + player->viewheight = defaultviewheight/2; if (player->deltaviewheight <= 0) - player->deltaviewheight = 1; + player->deltaviewheight = 1 / 65536.; } if (player->deltaviewheight) { - player->deltaviewheight += FRACUNIT/4; + player->deltaviewheight += 0.25; if (!player->deltaviewheight) - player->deltaviewheight = 1; + player->deltaviewheight = 1/65536.; } } @@ -1919,18 +1885,18 @@ void P_CalcHeight (player_t *player) bob = 0; } player->viewz = player->mo->Z() + player->viewheight + bob; - if (player->mo->floorclip && player->playerstate != PST_DEAD + if (player->mo->Floorclip && player->playerstate != PST_DEAD && player->mo->Z() <= player->mo->floorz) { - player->viewz -= player->mo->floorclip; + player->viewz -= player->mo->Floorclip; } - if (player->viewz > player->mo->ceilingz - 4*FRACUNIT) + if (player->viewz > player->mo->ceilingz - 4) { - player->viewz = player->mo->ceilingz - 4*FRACUNIT; + player->viewz = player->mo->ceilingz - 4; } - if (player->viewz < player->mo->floorz + 4*FRACUNIT) + if (player->viewz < player->mo->floorz + 4) { - player->viewz = player->mo->floorz + 4*FRACUNIT; + player->viewz = player->mo->floorz + 4; } } @@ -1943,7 +1909,7 @@ void P_CalcHeight (player_t *player) */ CUSTOM_CVAR (Float, sv_aircontrol, 0.00390625f, CVAR_SERVERINFO|CVAR_NOSAVE) { - level.aircontrol = (fixed_t)(self * 65536.f); + level.aircontrol = self; G_AirControlChanged (); } @@ -1956,11 +1922,11 @@ void P_MovePlayer (player_t *player) if (player->turnticks) { player->turnticks--; - mo->angle += (ANGLE_180 / TURN180_TICKS); + mo->Angles.Yaw += (180. / TURN180_TICKS); } else { - mo->angle += cmd->ucmd.yaw << 16; + mo->Angles.Yaw += cmd->ucmd.yaw * (360./65536.); } player->onground = (mo->Z() <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2); @@ -1974,51 +1940,51 @@ void P_MovePlayer (player_t *player) if (cmd->ucmd.forwardmove | cmd->ucmd.sidemove) { - fixed_t forwardmove, sidemove; - int bobfactor; - int friction, movefactor; - int fm, sm; + double forwardmove, sidemove; + double bobfactor; + double friction, movefactor; + double fm, sm; movefactor = P_GetMoveFactor (mo, &friction); bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR; if (!player->onground && !(player->mo->flags & MF_NOGRAVITY) && !player->mo->waterlevel) { // [RH] allow very limited movement if not on ground. - movefactor = FixedMul (movefactor, level.aircontrol); - bobfactor = FixedMul (bobfactor, level.aircontrol); + movefactor *= level.aircontrol; + bobfactor*= level.aircontrol; } fm = cmd->ucmd.forwardmove; sm = cmd->ucmd.sidemove; mo->TweakSpeeds (fm, sm); - fm = FixedMul (fm, player->mo->Speed); - sm = FixedMul (sm, player->mo->Speed); + fm *= player->mo->Speed / 256; + sm *= player->mo->Speed / 256; // When crouching, speed and bobbing have to be reduced - if (player->CanCrouch() && player->crouchfactor != FRACUNIT) + if (player->CanCrouch() && player->crouchfactor != 1) { - fm = FixedMul(fm, player->crouchfactor); - sm = FixedMul(sm, player->crouchfactor); - bobfactor = FixedMul(bobfactor, player->crouchfactor); + fm *= player->crouchfactor; + sm *= player->crouchfactor; + bobfactor *= player->crouchfactor; } - forwardmove = Scale (fm, movefactor * 35, TICRATE << 8); - sidemove = Scale (sm, movefactor * 35, TICRATE << 8); + forwardmove = fm * movefactor * (35 / TICRATE); + sidemove = sm * movefactor * (35 / TICRATE); if (forwardmove) { - P_Bob (player, mo->angle, (cmd->ucmd.forwardmove * bobfactor) >> 8, true); - P_ForwardThrust (player, mo->angle, forwardmove); + P_Bob(player, mo->Angles.Yaw, cmd->ucmd.forwardmove * bobfactor / 256., true); + P_ForwardThrust(player, mo->Angles.Yaw, forwardmove); } if (sidemove) { - P_Bob (player, mo->angle-ANG90, (cmd->ucmd.sidemove * bobfactor) >> 8, false); - P_SideThrust (player, mo->angle, sidemove); + P_Bob(player, mo->Angles.Yaw - 90, cmd->ucmd.sidemove * bobfactor / 256., false); + P_SideThrust(player, mo->Angles.Yaw, sidemove); } if (debugfile) { - fprintf (debugfile, "move player for pl %d%c: (%d,%d,%d) (%d,%d) %d %d w%d [", int(player-players), + fprintf (debugfile, "move player for pl %d%c: (%f,%f,%f) (%f,%f) %f %f w%d [", int(player-players), player->cheats&CF_PREDICTING?'p':' ', player->mo->X(), player->mo->Y(), player->mo->Z(),forwardmove, sidemove, movefactor, friction, player->mo->waterlevel); msecnode_t *n = player->mo->touching_sectorlist; @@ -2030,7 +1996,7 @@ void P_MovePlayer (player_t *player) fprintf (debugfile, "]\n"); } - if (!(player->cheats & CF_PREDICTING) && (forwardmove|sidemove)) + if (!(player->cheats & CF_PREDICTING) && (forwardmove != 0 || sidemove != 0)) { player->mo->PlayRunning (); } @@ -2053,7 +2019,7 @@ void P_FallingDamage (AActor *actor) { int damagestyle; int damage; - fixed_t vel; + double vel; damagestyle = ((level.flags >> 15) | (dmflags)) & (DF_FORCE_FALLINGZD | DF_FORCE_FALLINGHX); @@ -2064,7 +2030,7 @@ void P_FallingDamage (AActor *actor) if (actor->floorsector->Flags & SECF_NOFALLINGDAMAGE) return; - vel = abs(actor->vel.z); + vel = fabs(actor->Vel.Z); // Since Hexen falling damage is stronger than ZDoom's, it takes // precedence. ZDoom falling damage may not be as strong, but it @@ -2073,19 +2039,19 @@ void P_FallingDamage (AActor *actor) switch (damagestyle) { case DF_FORCE_FALLINGHX: // Hexen falling damage - if (vel <= 23*FRACUNIT) + if (vel <= 23) { // Not fast enough to hurt return; } - if (vel >= 63*FRACUNIT) + if (vel >= 63) { // automatic death damage = 1000000; } else { - vel = FixedMul (vel, 16*FRACUNIT/23); - damage = ((FixedMul (vel, vel) / 10) >> FRACBITS) - 24; - if (actor->vel.z > -39*FRACUNIT && damage > actor->health + vel *= (16. / 23); + damage = int((vel * vel) / 10 - 24); + if (actor->Vel.Z > -39 && damage > actor->health && actor->health != 1) { // No-death threshold damage = actor->health-1; @@ -2094,17 +2060,17 @@ void P_FallingDamage (AActor *actor) break; case DF_FORCE_FALLINGZD: // ZDoom falling damage - if (vel <= 19*FRACUNIT) + if (vel <= 19) { // Not fast enough to hurt return; } - if (vel >= 84*FRACUNIT) + if (vel >= 84) { // automatic death damage = 1000000; } else { - damage = ((MulScale23 (vel, vel*11) >> FRACBITS) - 30) / 2; + damage = int((vel*vel*(11 / 128.) - 30) / 2); if (damage < 1) { damage = 1; @@ -2113,13 +2079,13 @@ void P_FallingDamage (AActor *actor) break; case DF_FORCE_FALLINGST: // Strife falling damage - if (vel <= 20*FRACUNIT) + if (vel <= 20) { // Not fast enough to hurt return; } // The minimum amount of damage you take from falling in Strife // is 52. Ouch! - damage = vel / 25000; + damage = int(vel / (25000./65536.)); break; default: @@ -2147,47 +2113,46 @@ void P_FallingDamage (AActor *actor) void P_DeathThink (player_t *player) { int dir; - angle_t delta; - int lookDelta; + DAngle delta; P_MovePsprites (player); player->onground = (player->mo->Z() <= player->mo->floorz); if (player->mo->IsKindOf (RUNTIME_CLASS(APlayerChunk))) { // Flying bloody skull or flying ice chunk - player->viewheight = 6 * FRACUNIT; + player->viewheight = 6; player->deltaviewheight = 0; if (player->onground) { - if (player->mo->pitch > -(int)ANGLE_1*19) + if (player->mo->Angles.Pitch > -19.) { - lookDelta = (-(int)ANGLE_1*19 - player->mo->pitch) / 8; - player->mo->pitch += lookDelta; + DAngle lookDelta = (-19. - player->mo->Angles.Pitch) / 8; + player->mo->Angles.Pitch += lookDelta; } } } else if (!(player->mo->flags & MF_ICECORPSE)) { // Fall to ground (if not frozen) player->deltaviewheight = 0; - if (player->viewheight > 6*FRACUNIT) + if (player->viewheight > 6) { - player->viewheight -= FRACUNIT; + player->viewheight -= 1; } - if (player->viewheight < 6*FRACUNIT) + if (player->viewheight < 6) { - player->viewheight = 6*FRACUNIT; + player->viewheight = 6; } - if (player->mo->pitch < 0) + if (player->mo->Angles.Pitch < 0) { - player->mo->pitch += ANGLE_1*3; + player->mo->Angles.Pitch += 3; } - else if (player->mo->pitch > 0) + else if (player->mo->Angles.Pitch > 0) { - player->mo->pitch -= ANGLE_1*3; + player->mo->Angles.Pitch -= 3; } - if (abs(player->mo->pitch) < ANGLE_1*3) + if (fabs(player->mo->Angles.Pitch) < 3) { - player->mo->pitch = 0; + player->mo->Angles.Pitch = 0.; } } P_CalcHeight (player); @@ -2195,7 +2160,7 @@ void P_DeathThink (player_t *player) if (player->attacker && player->attacker != player->mo) { // Watch killer dir = P_FaceMobj (player->mo, player->attacker, &delta); - if (delta < ANGLE_1*10) + if (delta < 10) { // Looking at killer, so fade damage and poison counters if (player->damagecount) { @@ -2207,17 +2172,17 @@ void P_DeathThink (player_t *player) } } delta /= 8; - if (delta > ANGLE_1*5) + if (delta > 5.) { - delta = ANGLE_1*5; + delta = 5.; } if (dir) { // Turn clockwise - player->mo->angle += delta; + player->mo->Angles.Yaw += delta; } else { // Turn counter clockwise - player->mo->angle -= delta; + player->mo->Angles.Yaw -= delta; } } else @@ -2255,19 +2220,19 @@ void P_DeathThink (player_t *player) void P_CrouchMove(player_t * player, int direction) { - fixed_t defaultheight = player->mo->GetDefault()->height; - fixed_t savedheight = player->mo->height; - fixed_t crouchspeed = direction * CROUCHSPEED; - fixed_t oldheight = player->viewheight; + double defaultheight = player->mo->GetDefault()->Height; + double savedheight = player->mo->Height; + double crouchspeed = direction * CROUCHSPEED; + double oldheight = player->viewheight; player->crouchdir = (signed char) direction; player->crouchfactor += crouchspeed; // check whether the move is ok - player->mo->height = FixedMul(defaultheight, player->crouchfactor); - if (!P_TryMove(player->mo, player->mo->X(), player->mo->Y(), false, NULL)) + player->mo->Height = defaultheight * player->crouchfactor; + if (!P_TryMove(player->mo, player->mo->Pos(), false, NULL)) { - player->mo->height = savedheight; + player->mo->Height = savedheight; if (direction > 0) { // doesn't fit @@ -2275,10 +2240,10 @@ void P_CrouchMove(player_t * player, int direction) return; } } - player->mo->height = savedheight; + player->mo->Height = savedheight; - player->crouchfactor = clamp(player->crouchfactor, FRACUNIT/2, FRACUNIT); - player->viewheight = FixedMul(player->mo->ViewHeight, player->crouchfactor); + player->crouchfactor = clamp(player->crouchfactor, 0.5, 1.); + player->viewheight = player->mo->ViewHeight * player->crouchfactor; player->crouchviewdelta = player->viewheight - player->mo->ViewHeight; // Check for eyes going above/below fake floor due to crouching motion. @@ -2302,9 +2267,9 @@ void P_PlayerThink (player_t *player) if (debugfile && !(player->cheats & CF_PREDICTING)) { - fprintf (debugfile, "tic %d for pl %d: (%d, %d, %d, %u) b:%02x p:%d y:%d f:%d s:%d u:%d\n", + fprintf (debugfile, "tic %d for pl %d: (%f, %f, %f, %f) b:%02x p:%d y:%d f:%d s:%d u:%d\n", gametic, (int)(player-players), player->mo->X(), player->mo->Y(), player->mo->Z(), - player->mo->angle>>ANGLETOFINESHIFT, player->cmd.ucmd.buttons, + player->mo->Angles.Yaw.Degrees, player->cmd.ucmd.buttons, player->cmd.ucmd.pitch, player->cmd.ucmd.yaw, player->cmd.ucmd.forwardmove, player->cmd.ucmd.sidemove, player->cmd.ucmd.upmove); } @@ -2428,12 +2393,12 @@ void P_PlayerThink (player_t *player) { player->crouching = 0; } - if (crouchdir == 1 && player->crouchfactor < FRACUNIT && + if (crouchdir == 1 && player->crouchfactor < 1 && player->mo->Top() < player->mo->ceilingz) { P_CrouchMove(player, 1); } - else if (crouchdir == -1 && player->crouchfactor > FRACUNIT/2) + else if (crouchdir == -1 && player->crouchfactor > 0.5) { P_CrouchMove(player, -1); } @@ -2444,7 +2409,7 @@ void P_PlayerThink (player_t *player) player->Uncrouch(); } - player->crouchoffset = -FixedMul(player->mo->ViewHeight, (FRACUNIT - player->crouchfactor)); + player->crouchoffset = -(player->mo->ViewHeight) * (1 - player->crouchfactor); // MUSINFO stuff if (player->MUSINFOtics >= 0 && player->MUSINFOactor != NULL) @@ -2493,54 +2458,37 @@ void P_PlayerThink (player_t *player) // [RH] Look up/down stuff if (!level.IsFreelookAllowed()) { - player->mo->pitch = 0; + player->mo->Angles.Pitch = 0.; } else { - int look = cmd->ucmd.pitch << 16; - // The player's view pitch is clamped between -32 and +56 degrees, // which translates to about half a screen height up and (more than) // one full screen height down from straight ahead when view panning // is used. - if (look) + int clook = cmd->ucmd.pitch; + if (clook != 0) { - if (look == -32768 << 16) + if (clook == -32768) { // center view player->centering = true; } else if (!player->centering) { - fixed_t oldpitch = player->mo->pitch; - player->mo->pitch -= look; - if (look > 0) - { // look up - player->mo->pitch = MAX(player->mo->pitch, player->MinPitch); - if (player->mo->pitch > oldpitch) - { - player->mo->pitch = player->MinPitch; - } - } - else - { // look down - player->mo->pitch = MIN(player->mo->pitch, player->MaxPitch); - if (player->mo->pitch < oldpitch) - { - player->mo->pitch = player->MaxPitch; - } - } + // no more overflows with floating point. Yay! :) + player->mo->Angles.Pitch = clamp(player->mo->Angles.Pitch - clook * (360. / 65536.), player->MinPitch, player->MaxPitch); } } } if (player->centering) { - if (abs(player->mo->pitch) > 2*ANGLE_1) + if (fabs(player->mo->Angles.Pitch) > 2.) { - player->mo->pitch = FixedMul(player->mo->pitch, FRACUNIT*2/3); + player->mo->Angles.Pitch *= (2. / 3.); } else { - player->mo->pitch = 0; + player->mo->Angles.Pitch = 0.; player->centering = false; if (player - players == consoleplayer) { @@ -2574,20 +2522,20 @@ void P_PlayerThink (player_t *player) } else if (player->mo->waterlevel >= 2) { - player->mo->vel.z = FixedMul(4*FRACUNIT, player->mo->Speed); + player->mo->Vel.Z = 4 * player->mo->Speed; } else if (player->mo->flags & MF_NOGRAVITY) { - player->mo->vel.z = 3*FRACUNIT; + player->mo->Vel.Z = 3.; } else if (level.IsJumpingAllowed() && player->onground && player->jumpTics == 0) { - fixed_t jumpvelz = player->mo->JumpZ * 35 / TICRATE; + double jumpvelz = player->mo->JumpZ * 35 / TICRATE; // [BC] If the player has the high jump power, double his jump velocity. if ( player->cheats & CF_HIGHJUMP ) jumpvelz *= 2; - player->mo->vel.z += jumpvelz; + player->mo->Vel.Z += jumpvelz; player->mo->flags2 &= ~MF2_ONMOBJ; player->jumpTics = -1; if (!(player->cheats & CF_PREDICTING)) @@ -2613,12 +2561,12 @@ void P_PlayerThink (player_t *player) } if (player->mo->waterlevel >= 2 || (player->mo->flags2 & MF2_FLY) || (player->cheats & CF_NOCLIP2)) { - player->mo->vel.z = FixedMul(player->mo->Speed, cmd->ucmd.upmove << 9); + player->mo->Vel.Z = player->mo->Speed * cmd->ucmd.upmove / 128.; if (player->mo->waterlevel < 2 && !(player->mo->flags & MF_NOGRAVITY)) { player->mo->flags2 |= MF2_FLY; player->mo->flags |= MF_NOGRAVITY; - if ((player->mo->vel.z <= -39 * FRACUNIT) && !(player->cheats & CF_PREDICTING)) + if ((player->mo->Vel.Z <= -39) && !(player->cheats & CF_PREDICTING)) { // Stop falling scream S_StopSound (player->mo, CHAN_VOICE); } @@ -2642,14 +2590,14 @@ void P_PlayerThink (player_t *player) P_PlayerOnSpecial3DFloor (player); P_PlayerInSpecialSector (player); - if (player->mo->Z() <= player->mo->Sector->floorplane.ZatPoint(player->mo) || + if (!player->mo->isAbove(player->mo->Sector->floorplane.ZatPoint(player->mo)) || player->mo->waterlevel) { // Player must be touching the floor P_PlayerOnSpecialFlat(player, P_GetThingFloorType(player->mo)); } - if (player->mo->vel.z <= -player->mo->FallingScreamMinSpeed && - player->mo->vel.z >= -player->mo->FallingScreamMaxSpeed && !player->morphTics && + if (player->mo->Vel.Z <= -player->mo->FallingScreamMinSpeed && + player->mo->Vel.Z >= -player->mo->FallingScreamMaxSpeed && !player->morphTics && player->mo->waterlevel == 0) { int id = S_FindSkinnedSound (player->mo, "*falling"); @@ -2750,19 +2698,19 @@ void P_PredictionLerpReset() PredictionLerptics = PredictionLast.gametic = PredictionLerpFrom.gametic = PredictionLerpResult.gametic = 0; } -bool P_LerpCalculate(PredictPos from, PredictPos to, PredictPos &result, float scale) +bool P_LerpCalculate(AActor *pmo, PredictPos from, PredictPos to, PredictPos &result, float scale) { - DVector3 vecFrom(FIXED2DBL(from.x), FIXED2DBL(from.y), FIXED2DBL(from.z)); - DVector3 vecTo(FIXED2DBL(to.x), FIXED2DBL(to.y), FIXED2DBL(to.z)); + //DVector2 pfrom = Displacements.getOffset(from.portalgroup, to.portalgroup); + DVector3 vecFrom = from.pos; + DVector3 vecTo = to.pos; DVector3 vecResult; vecResult = vecTo - vecFrom; vecResult *= scale; vecResult = vecResult + vecFrom; DVector3 delta = vecResult - vecTo; - result.x = FLOAT2FIXED(vecResult.X); - result.y = FLOAT2FIXED(vecResult.Y); - result.z = FLOAT2FIXED(vecResult.Z); + result.pos = pmo->Vec3Offset(vecResult - to.pos); + //result.portalgroup = P_PointInSector(result.pos.x, result.pos.y)->PortalGroup; // As a fail safe, assume extrapolation is the threshold. return (delta.LengthSquared() > cl_predict_lerpthreshold && scale <= 1.00f); @@ -2868,16 +2816,15 @@ void P_PredictPlayer (player_t *player) { // Z is not compared as lifts will alter this with no apparent change // Make lerping less picky by only testing whole units - DoLerp = ((PredictionLast.x >> 16) != (player->mo->X() >> 16) || - (PredictionLast.y >> 16) != (player->mo->Y() >> 16)); + DoLerp = (int)PredictionLast.pos.X != (int)player->mo->X() || (int)PredictionLast.pos.Y != (int)player->mo->Y(); // Aditional Debug information if (developer && DoLerp) { - DPrintf("Lerp! Ltic (%d) && Ptic (%d) | Lx (%d) && Px (%d) | Ly (%d) && Py (%d)\n", + DPrintf("Lerp! Ltic (%d) && Ptic (%d) | Lx (%f) && Px (%f) | Ly (%f) && Py (%f)\n", PredictionLast.gametic, i, - (PredictionLast.x >> 16), (player->mo->X() >> 16), - (PredictionLast.y >> 16), (player->mo->Y() >> 16)); + (PredictionLast.pos.X), (player->mo->X()), + (PredictionLast.pos.Y), (player->mo->Y())); } } } @@ -2895,17 +2842,16 @@ void P_PredictPlayer (player_t *player) } PredictionLast.gametic = maxtic - 1; - PredictionLast.x = player->mo->X(); - PredictionLast.y = player->mo->Y(); - PredictionLast.z = player->mo->Z(); + PredictionLast.pos = player->mo->Pos(); + //PredictionLast.portalgroup = player->mo->Sector->PortalGroup; if (PredictionLerptics > 0) { if (PredictionLerpFrom.gametic > 0 && - P_LerpCalculate(PredictionLerpFrom, PredictionLast, PredictionLerpResult, (float)PredictionLerptics * cl_predict_lerpscale)) + P_LerpCalculate(player->mo, PredictionLerpFrom, PredictionLast, PredictionLerpResult, (float)PredictionLerptics * cl_predict_lerpscale)) { PredictionLerptics++; - player->mo->SetXYZ(PredictionLerpResult.x, PredictionLerpResult.y, PredictionLerpResult.z); + player->mo->SetXYZ(PredictionLerpResult.pos); } else { @@ -3071,16 +3017,10 @@ void player_t::Serialize (FArchive &arc) << viewheight << deltaviewheight << bob - << vel.x - << vel.y + << Vel << centering << health << inventorytics; - if (SaveVersion < 4513) - { - bool backpack; - arc << backpack; - } arc << fragcount << spreecount << multicount @@ -3111,54 +3051,18 @@ void player_t::Serialize (FArchive &arc) << air_finished << turnticks << oldbuttons; - if (SaveVersion >= 4929) - { - arc << hazardtype - << hazardinterval; - } - bool IsBot = false; - if (SaveVersion >= 4514) - { - arc << Bot; - } - else - { - arc << IsBot; - } + arc << hazardtype + << hazardinterval; + arc << Bot; arc << BlendR << BlendG << BlendB << BlendA; - if (SaveVersion < 3427) - { - WORD oldaccuracy, oldstamina; - arc << oldaccuracy << oldstamina; - if (mo != NULL) - { - mo->accuracy = oldaccuracy; - mo->stamina = oldstamina; - } - } - if (SaveVersion < 4041) - { - // Move weapon state flags from cheats and into WeaponState. - WeaponState = ((cheats >> 14) & 1) | ((cheats & (0x37 << 24)) >> (24 - 1)); - cheats &= ~((1 << 14) | (0x37 << 24)); - } - if (SaveVersion < 4527) - { - BYTE oldWeaponState; - arc << oldWeaponState; - WeaponState = oldWeaponState; - } - else - { - arc << WeaponState; - } + arc << WeaponState; arc << LogText << ConversationNPC << ConversationPC - << ConversationNPCAngle + << ConversationNPCAngle.Degrees << ConversationFaceTalker; for (i = 0; i < MAXPLAYERS; i++) @@ -3174,76 +3078,10 @@ void player_t::Serialize (FArchive &arc) << crouchviewdelta << original_cmd << original_oldbuttons; - - if (SaveVersion >= 3475) - { - arc << poisontype << poisonpaintype; - } - else if (poisoner != NULL) - { - poisontype = poisoner->DamageType; - poisonpaintype = poisoner->PainType != NAME_None ? poisoner->PainType : poisoner->DamageType; - } - - if (SaveVersion >= 3599) - { - arc << timefreezer; - } - else - { - cheats &= ~(1 << 15); // make sure old CF_TIMEFREEZE bit is cleared - } - if (SaveVersion < 3640) - { - cheats &= ~(1 << 17); // make sure old CF_REGENERATION bit is cleared - } - if (SaveVersion >= 3780) - { - arc << settings_controller; - } - else - { - settings_controller = (this - players == Net_Arbitrator); - } - if (SaveVersion >= 4505) - { - arc << onground; - } - else - { - onground = (mo->Z() <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (cheats & CF_NOCLIP2); - } - - if (SaveVersion < 4514 && IsBot) - { - Bot = new DBot; - - arc << Bot->angle - << Bot->dest - << Bot->prev - << Bot->enemy - << Bot->missile - << Bot->mate - << Bot->last_mate - << Bot->skill - << Bot->t_active - << Bot->t_respawn - << Bot->t_strafe - << Bot->t_react - << Bot->t_fight - << Bot->t_roam - << Bot->t_rocket - << Bot->first_shot - << Bot->sleft - << Bot->allround - << Bot->oldx - << Bot->oldy; - } - - if (SaveVersion < 4516 && Bot != NULL) - { - Bot->player = this; - } + arc << poisontype << poisonpaintype; + arc << timefreezer; + arc << settings_controller; + arc << onground; if (arc.IsLoading ()) { @@ -3256,10 +3094,7 @@ void player_t::Serialize (FArchive &arc) { userinfo.SkinChanged(skinname, CurrentPlayerClass); } - if (SaveVersion >= 4522) - { - arc << MUSINFOactor << MUSINFOtics; - } + arc << MUSINFOactor << MUSINFOtics; } bool P_IsPlayerTotallyFrozen(const player_t *player) diff --git a/src/p_writemap.cpp b/src/p_writemap.cpp index 309e12921..ba1320566 100644 --- a/src/p_writemap.cpp +++ b/src/p_writemap.cpp @@ -100,9 +100,9 @@ static int WriteTHINGS (FILE *file) mapthinghexen_t mt = { 0, 0, 0, 0, 0, 0, 0, 0, {0} }; AActor *mo = players[consoleplayer].mo; - mt.x = LittleShort(short(mo->X() >> FRACBITS)); - mt.y = LittleShort(short(mo->Y() >> FRACBITS)); - mt.angle = LittleShort(short(MulScale32 (mo->angle >> ANGLETOFINESHIFT, 360))); + mt.x = LittleShort(short(mo->X())); + mt.y = LittleShort(short(mo->Y())); + mt.angle = LittleShort(short(mo->Angles.Yaw.Degrees)); mt.type = LittleShort((short)1); mt.flags = LittleShort((short)(7|224|MTF_SINGLE)); fwrite (&mt, sizeof(mt), 1, file); @@ -150,8 +150,8 @@ static int WriteSIDEDEFS (FILE *file) for (int i = 0; i < numsides; ++i) { - msd.textureoffset = LittleShort(short(sides[i].GetTextureXOffset(side_t::mid) >> FRACBITS)); - msd.rowoffset = LittleShort(short(sides[i].GetTextureYOffset(side_t::mid) >> FRACBITS)); + msd.textureoffset = LittleShort(short(sides[i].GetTextureXOffsetF(side_t::mid))); + msd.rowoffset = LittleShort(short(sides[i].GetTextureYOffsetF(side_t::mid))); msd.sector = LittleShort(short(sides[i].sector - sectors)); uppercopy (msd.toptexture, GetTextureName (sides[i].GetTexture(side_t::top))); uppercopy (msd.bottomtexture, GetTextureName (sides[i].GetTexture(side_t::bottom))); @@ -167,8 +167,8 @@ static int WriteVERTEXES (FILE *file) for (int i = 0; i < numvertexes; ++i) { - mv.x = LittleShort(short(vertexes[i].x >> FRACBITS)); - mv.y = LittleShort(short(vertexes[i].y >> FRACBITS)); + mv.x = LittleShort(short(vertexes[i].fixX() >> FRACBITS)); + mv.y = LittleShort(short(vertexes[i].fixY() >> FRACBITS)); fwrite (&mv, sizeof(mv), 1, file); } return numvertexes * sizeof(mv); @@ -177,79 +177,17 @@ static int WriteVERTEXES (FILE *file) static int WriteSEGS (FILE *file) { -#if 0 - mapseg_t ms; - - ms.offset = 0; // unused by ZDoom, so just leave it 0 - for (int i = 0; i < numsegs; ++i) - { - if (segs[i].linedef!=NULL) - { - ms.v1 = LittleShort(short(segs[i].v1 - vertexes)); - ms.v2 = LittleShort(short(segs[i].v2 - vertexes)); - ms.linedef = LittleShort(short(segs[i].linedef - lines)); - ms.side = segs[i].sidedef == segs[i].linedef->sidedef[0] ? 0 : LittleShort((short)1); - ms.angle = LittleShort(short(R_PointToAngle2 (segs[i].v1->x, segs[i].v1->y, segs[i].v2->x, segs[i].v2->y)>>16)); - fwrite (&ms, sizeof(ms), 1, file); - } - } - return numsegs * sizeof(ms); -#else return 0; -#endif } static int WriteSSECTORS (FILE *file) { -#if 0 - mapsubsector_t mss; - - for (int i = 0; i < numsubsectors; ++i) - { - mss.firstseg = LittleShort((WORD)subsectors[i].firstline); - mss.numsegs = LittleShort((WORD)subsectors[i].numlines); - fwrite (&mss, sizeof(mss), 1, file); - } - return numsubsectors * sizeof(mss); -#else return 0; -#endif } static int WriteNODES (FILE *file) { -#if 0 - mapnode_t mn; - - for (int i = 0; i < numnodes; ++i) - { - mn.x = LittleShort(short(nodes[i].x >> FRACBITS)); - mn.y = LittleShort(short(nodes[i].y >> FRACBITS)); - mn.dx = LittleShort(short(nodes[i].dx >> FRACBITS)); - mn.dy = LittleShort(short(nodes[i].dy >> FRACBITS)); - for (int j = 0; j < 2; ++j) - { - for (int k = 0; k < 4; ++k) - { - mn.bbox[j][k] = LittleShort(short(nodes[i].bbox[j][k] >> FRACBITS)); - } - WORD child; - if ((size_t)nodes[i].children[j] & 1) - { - child = mapnode_t::NF_SUBSECTOR | WORD((subsector_t *)((BYTE *)nodes[i].children[j] - 1) - subsectors); - } - else - { - child = WORD((node_t *)nodes[i].children[j] - nodes); - } - mn.children[j] = LittleShort(child); - } - fwrite (&mn, sizeof(mn), 1, file); - } - return numnodes * sizeof(mn); -#else return 0; -#endif } static int WriteSECTORS (FILE *file) @@ -258,8 +196,8 @@ static int WriteSECTORS (FILE *file) for (int i = 0; i < numsectors; ++i) { - ms.floorheight = LittleShort(short(sectors[i].GetPlaneTexZ(sector_t::floor) >> FRACBITS)); - ms.ceilingheight = LittleShort(short(sectors[i].GetPlaneTexZ(sector_t::ceiling) >> FRACBITS)); + ms.floorheight = LittleShort(short(sectors[i].GetPlaneTexZF(sector_t::floor))); + ms.ceilingheight = LittleShort(short(sectors[i].GetPlaneTexZF(sector_t::ceiling))); uppercopy (ms.floorpic, GetTextureName (sectors[i].GetTexture(sector_t::floor))); uppercopy (ms.ceilingpic, GetTextureName (sectors[i].GetTexture(sector_t::ceiling))); ms.lightlevel = LittleShort((short)sectors[i].lightlevel); diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index ea6bd7d9e..2e30925bb 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -87,10 +87,10 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineindexforid) passthrough = true; break; case -2: - ld->Alpha = FRACUNIT*3/4; + ld->Alpha = TRANSLUC75; break; case -3: - ld->Alpha = FRACUNIT / 4; + ld->Alpha = TRANSLUC25; break; default: newflags |= LineFlagTranslations[i].newvalue; diff --git a/src/po_man.cpp b/src/po_man.cpp index ab6de8756..d21141c35 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -32,6 +32,7 @@ #include "p_blockmap.h" #include "p_maputl.h" #include "r_utility.h" +#include "p_blockmap.h" // MACROS ------------------------------------------------------------------ @@ -77,14 +78,14 @@ public: void Serialize (FArchive &arc); void Destroy(); void Stop(); - int GetSpeed() const { return m_Speed; } + double GetSpeed() const { return m_Speed; } void StopInterpolation (); protected: DPolyAction (); int m_PolyObj; - int m_Speed; - int m_Dist; + double m_Speed; + double m_Dist; TObjPtr m_Interpolation; void SetInterpolation (); @@ -112,11 +113,10 @@ public: void Tick (); protected: DMovePoly (); - int m_Angle; - fixed_t m_xSpeed; // for sliding walls - fixed_t m_ySpeed; + DAngle m_Angle; + DVector2 m_Speedv; - friend bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, fixed_t dist, bool overRide); + friend bool EV_MovePoly(line_t *line, int polyNum, double speed, DAngle angle, double dist, bool overRide); }; class DMovePolyTo : public DPolyAction @@ -128,12 +128,10 @@ public: void Tick(); protected: DMovePolyTo(); - fixed_t m_xSpeed; - fixed_t m_ySpeed; - fixed_t m_xTarget; - fixed_t m_yTarget; + DVector2 m_Speedv; + DVector2 m_Target; - friend bool EV_MovePolyTo(line_t *line, int polyNum, int speed, fixed_t x, fixed_t y, bool overRide); + friend bool EV_MovePolyTo(line_t *line, int polyNum, double speed, const DVector2 &pos, bool overRide); }; @@ -145,14 +143,14 @@ public: void Serialize (FArchive &arc); void Tick (); protected: - int m_Direction; - int m_TotalDist; + DAngle m_Direction; + double m_TotalDist; int m_Tics; int m_WaitTics; podoortype_t m_Type; bool m_Close; - friend bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, int delay, int distance, podoortype_t type); + friend bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int delay, double distance, podoortype_t type); private: DPolyDoor (); }; @@ -171,19 +169,18 @@ public: // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- void PO_Init (void); +void P_AdjustLine(line_t *ld); // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static void RotatePt (int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, - fixed_t startSpotY); static void UnLinkPolyobj (FPolyObj *po); static void LinkPolyobj (FPolyObj *po); static bool CheckMobjBlocking (side_t *seg, FPolyObj *po); static void InitBlockMap (void); static void IterFindPolySides (FPolyObj *po, side_t *side); static void SpawnPolyobj (int index, int tag, int type); -static void TranslateToStartSpot (int tag, int originX, int originY); -static void DoMovePolyobj (FPolyObj *po, int x, int y); +static void TranslateToStartSpot (int tag, const DVector2 &origin); +static void DoMovePolyobj (FPolyObj *po, const DVector2 & move); static void InitSegLists (); static void KillSegLists (); static FPolyNode *NewPolyNode(); @@ -305,15 +302,14 @@ DMovePoly::DMovePoly () void DMovePoly::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << m_Angle << m_xSpeed << m_ySpeed; + arc << m_Angle << m_Speed; } DMovePoly::DMovePoly (int polyNum) : Super (polyNum) { - m_Angle = 0; - m_xSpeed = 0; - m_ySpeed = 0; + m_Angle = 0.; + m_Speedv = { 0,0 }; } //========================================================================== @@ -332,16 +328,13 @@ DMovePolyTo::DMovePolyTo() void DMovePolyTo::Serialize(FArchive &arc) { Super::Serialize(arc); - arc << m_xSpeed << m_ySpeed << m_xTarget << m_yTarget; + arc << m_Speedv << m_Target; } DMovePolyTo::DMovePolyTo(int polyNum) : Super(polyNum) { - m_xSpeed = 0; - m_ySpeed = 0; - m_xTarget = 0; - m_yTarget = 0; + m_Speedv = m_Target = { 0,0 }; } //========================================================================== @@ -365,7 +358,7 @@ void DPolyDoor::Serialize (FArchive &arc) DPolyDoor::DPolyDoor (int polyNum, podoortype_t type) : Super (polyNum), m_Type (type) { - m_Direction = 0; + m_Direction = 0.; m_TotalDist = 0; m_Tics = 0; m_WaitTics = 0; @@ -386,7 +379,7 @@ void DRotatePoly::Tick () if (poly == NULL) return; // Don't let non-perpetual polyobjs overshoot their targets. - if (m_Dist != -1 && (unsigned int)m_Dist < (unsigned int)abs(m_Speed)) + if (m_Dist != -1 && m_Dist < fabs(m_Speed)) { m_Speed = m_Speed < 0 ? -m_Dist : m_Dist; } @@ -397,7 +390,7 @@ void DRotatePoly::Tick () { // perpetual polyobj return; } - m_Dist -= abs(m_Speed); + m_Dist -= fabs(m_Speed); if (m_Dist == 0) { SN_StopSequence (poly); @@ -438,18 +431,18 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, { if (byteAngle == 255) { - pe->m_Dist = ~0; + pe->m_Dist = -1.; } else { - pe->m_Dist = byteAngle*(ANGLE_90/64); // Angle + pe->m_Dist = byteAngle*(90./64); // Angle } } else { - pe->m_Dist = ANGLE_MAX-1; + pe->m_Dist = 360.; } - pe->m_Speed = speed*direction*(ANGLE_90/(64<<3)); + pe->m_Speed = speed*direction*(90./(64<<3)); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0); direction = -direction; // Reverse the direction } @@ -468,9 +461,9 @@ void DMovePoly::Tick () if (poly != NULL) { - if (poly->MovePolyobj (m_xSpeed, m_ySpeed)) + if (poly->MovePolyobj (m_Speedv)) { - int absSpeed = abs (m_Speed); + double absSpeed = fabs (m_Speed); m_Dist -= absSpeed; if (m_Dist <= 0) { @@ -480,8 +473,7 @@ void DMovePoly::Tick () else if (m_Dist < absSpeed) { m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1); - m_xSpeed = FixedMul (m_Speed, finecosine[m_Angle]); - m_ySpeed = FixedMul (m_Speed, finesine[m_Angle]); + m_Speedv = m_Angle.ToVector(m_Speed); } } } @@ -493,12 +485,12 @@ void DMovePoly::Tick () // //========================================================================== -bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, - fixed_t dist, bool overRide) +bool EV_MovePoly (line_t *line, int polyNum, double speed, DAngle angle, + double dist, bool overRide) { DMovePoly *pe = NULL; FPolyObj *poly; - angle_t an = angle; + DAngle an = angle; if ((poly = PO_GetPolyobj(polyNum)) == NULL) { @@ -517,9 +509,8 @@ bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, poly->specialdata = pe; pe->m_Dist = dist; // Distance pe->m_Speed = speed; - pe->m_Angle = an >> ANGLETOFINESHIFT; - pe->m_xSpeed = FixedMul (pe->m_Speed, finecosine[pe->m_Angle]); - pe->m_ySpeed = FixedMul (pe->m_Speed, finesine[pe->m_Angle]); + pe->m_Angle = angle; + pe->m_Speedv = angle.ToVector(speed); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0); // Do not interpolate very fast moving polyobjects. The minimum tic count is @@ -531,7 +522,7 @@ bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, pe->StopInterpolation (); } - an = an + ANGLE_180; // Reverse the angle. + angle += 180.; // Reverse the angle. } return pe != NULL; // Return true if something started moving. } @@ -548,9 +539,9 @@ void DMovePolyTo::Tick () if (poly != NULL) { - if (poly->MovePolyobj (m_xSpeed, m_ySpeed)) + if (poly->MovePolyobj (m_Speedv)) { - int absSpeed = abs (m_Speed); + double absSpeed = fabs (m_Speed); m_Dist -= absSpeed; if (m_Dist <= 0) { @@ -560,8 +551,7 @@ void DMovePolyTo::Tick () else if (m_Dist < absSpeed) { m_Speed = m_Dist * (m_Speed < 0 ? -1 : 1); - m_xSpeed = m_xTarget - poly->StartSpot.x; - m_ySpeed = m_yTarget - poly->StartSpot.y; + m_Speedv = m_Target - poly->StartSpot.pos; } } } @@ -573,7 +563,7 @@ void DMovePolyTo::Tick () // //========================================================================== -bool EV_MovePolyTo(line_t *line, int polyNum, int speed, fixed_t targx, fixed_t targy, bool overRide) +bool EV_MovePolyTo(line_t *line, int polyNum, double speed, const DVector2 &targ, bool overRide) { DMovePolyTo *pe = NULL; FPolyObj *poly; @@ -587,8 +577,7 @@ bool EV_MovePolyTo(line_t *line, int polyNum, int speed, fixed_t targx, fixed_t } FPolyMirrorIterator it(poly); - dist.X = targx - poly->StartSpot.x; - dist.Y = targy - poly->StartSpot.y; + dist = targ - poly->StartSpot.pos; distlen = dist.MakeUnit(); while ((poly = it.NextMirror()) != NULL) { @@ -598,12 +587,10 @@ bool EV_MovePolyTo(line_t *line, int polyNum, int speed, fixed_t targx, fixed_t } pe = new DMovePolyTo(poly->tag); poly->specialdata = pe; - pe->m_Dist = xs_RoundToInt(distlen); + pe->m_Dist = distlen; pe->m_Speed = speed; - pe->m_xSpeed = xs_RoundToInt(speed * dist.X); - pe->m_ySpeed = xs_RoundToInt(speed * dist.Y); - pe->m_xTarget = xs_RoundToInt(poly->StartSpot.x + distlen * dist.X); - pe->m_yTarget = xs_RoundToInt(poly->StartSpot.y + distlen * dist.Y); + pe->m_Speedv = dist * speed; + pe->m_Target = poly->StartSpot.pos + dist * distlen; if ((pe->m_Dist / pe->m_Speed) <= 2) { pe->StopInterpolation(); @@ -621,7 +608,6 @@ bool EV_MovePolyTo(line_t *line, int polyNum, int speed, fixed_t targx, fixed_t void DPolyDoor::Tick () { - int absSpeed; FPolyObj *poly = PO_GetPolyobj (m_PolyObj); if (poly == NULL) return; @@ -637,9 +623,9 @@ void DPolyDoor::Tick () switch (m_Type) { case PODOOR_SLIDE: - if (m_Dist <= 0 || poly->MovePolyobj (m_xSpeed, m_ySpeed)) + if (m_Dist <= 0 || poly->MovePolyobj (m_Speedv)) { - absSpeed = abs (m_Speed); + double absSpeed = fabs (m_Speed); m_Dist -= absSpeed; if (m_Dist <= 0) { @@ -649,9 +635,8 @@ void DPolyDoor::Tick () m_Dist = m_TotalDist; m_Close = true; m_Tics = m_WaitTics; - m_Direction = (ANGLE_MAX>>ANGLETOFINESHIFT) - m_Direction; - m_xSpeed = -m_xSpeed; - m_ySpeed = -m_ySpeed; + m_Direction = -m_Direction; + m_Speedv = -m_Speedv; } else { @@ -668,10 +653,8 @@ void DPolyDoor::Tick () else { // open back up m_Dist = m_TotalDist - m_Dist; - m_Direction = (ANGLE_MAX>>ANGLETOFINESHIFT)- - m_Direction; - m_xSpeed = -m_xSpeed; - m_ySpeed = -m_ySpeed; + m_Direction = -m_Direction; + m_Speedv = -m_Speedv; m_Close = false; SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0); } @@ -681,7 +664,7 @@ void DPolyDoor::Tick () case PODOOR_SWING: if (m_Dist <= 0 || poly->RotatePolyobj (m_Speed)) { - absSpeed = abs (m_Speed); + double absSpeed = fabs (m_Speed); m_Dist -= absSpeed; if (m_Dist <= 0) { @@ -726,8 +709,7 @@ void DPolyDoor::Tick () // //========================================================================== -bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, - int delay, int distance, podoortype_t type) +bool EV_OpenPolyDoor(line_t *line, int polyNum, double speed, DAngle angle, int delay, double distance, podoortype_t type) { DPolyDoor *pd = NULL; FPolyObj *poly; @@ -753,18 +735,17 @@ bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, pd->m_WaitTics = delay; pd->m_Speed = speed; pd->m_Dist = pd->m_TotalDist = distance; // Distance - pd->m_Direction = angle >> ANGLETOFINESHIFT; - pd->m_xSpeed = FixedMul (pd->m_Speed, finecosine[pd->m_Direction]); - pd->m_ySpeed = FixedMul (pd->m_Speed, finesine[pd->m_Direction]); + pd->m_Direction = angle; + pd->m_Speedv = angle.ToVector(speed); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0); - angle += ANGLE_180; // reverse the angle + angle += 180.; // reverse the angle } else if (type == PODOOR_SWING) { pd->m_WaitTics = delay; - pd->m_Direction = swingdir; - pd->m_Speed = (speed*pd->m_Direction*(ANGLE_90/64))>>3; - pd->m_Dist = pd->m_TotalDist = angle; + pd->m_Direction.Degrees = swingdir; + pd->m_Speed = (speed*swingdir*(90. / 64)) / 8; + pd->m_Dist = pd->m_TotalDist = angle.Degrees; SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0); swingdir = -swingdir; // reverse the direction } @@ -825,15 +806,15 @@ FPolyObj *PO_GetPolyobj (int polyNum) FPolyObj::FPolyObj() { - StartSpot.x = StartSpot.y = 0; - angle = 0; + StartSpot.pos = { 0,0 }; + Angle = 0.; tag = 0; memset(bbox, 0, sizeof(bbox)); validcount = 0; crush = 0; bHurtOnTouch = false; seqType = 0; - size = 0; + Size = 0; subsectorlinks = NULL; specialdata = NULL; interpolation = NULL; @@ -858,12 +839,10 @@ int FPolyObj::GetMirror() void FPolyObj::ThrustMobj (AActor *actor, side_t *side) { - int thrustAngle; - int thrustX; - int thrustY; + DAngle thrustAngle; DPolyAction *pe; - int force; + double force; if (!(actor->flags&MF_SHOOTABLE) && !actor->player) { @@ -871,41 +850,33 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side) } vertex_t *v1 = side->V1(); vertex_t *v2 = side->V2(); - thrustAngle = (R_PointToAngle2 (v1->x, v1->y, v2->x, v2->y) - ANGLE_90) >> ANGLETOFINESHIFT; + thrustAngle = (v2->fPos() - v1->fPos()).Angle() - 90.; pe = static_cast(specialdata); if (pe) { if (pe->IsKindOf (RUNTIME_CLASS (DRotatePoly))) { - force = pe->GetSpeed() >> 8; + force = pe->GetSpeed() * (90. / 2048); // For DRotatePoly m_Speed stores an angle which needs to be converted differently } else { - force = pe->GetSpeed() >> 3; - } - if (force < FRACUNIT) - { - force = FRACUNIT; - } - else if (force > 4*FRACUNIT) - { - force = 4*FRACUNIT; + force = pe->GetSpeed() / 8; } + force = clamp(force, 1., 4.); } else { - force = FRACUNIT; + force = 1; } - thrustX = FixedMul (force, finecosine[thrustAngle]); - thrustY = FixedMul (force, finesine[thrustAngle]); - actor->vel.x += thrustX; - actor->vel.y += thrustY; + DVector2 thrust = thrustAngle.ToVector(force); + actor->Vel += thrust; + if (crush) { - fixedvec2 pos = actor->Vec2Offset(thrustX, thrustY); - if (bHurtOnTouch || !P_CheckMove (actor, pos.x, pos.y)) + DVector2 pos = actor->Vec2Offset(thrust.X, thrust.Y); + if (bHurtOnTouch || !P_CheckMove (actor, pos)) { int newdam = P_DamageMobj (actor, NULL, NULL, crush, NAME_Crush); P_TraceBleed (newdam > 0 ? newdam : crush, actor); @@ -924,46 +895,19 @@ void FPolyObj::UpdateBBox () { for(unsigned i=0;iv1->x < line->v2->x) - { - line->bbox[BOXLEFT] = line->v1->x; - line->bbox[BOXRIGHT] = line->v2->x; - } - else - { - line->bbox[BOXLEFT] = line->v2->x; - line->bbox[BOXRIGHT] = line->v1->x; - } - if (line->v1->y < line->v2->y) - { - line->bbox[BOXBOTTOM] = line->v1->y; - line->bbox[BOXTOP] = line->v2->y; - } - else - { - line->bbox[BOXBOTTOM] = line->v2->y; - line->bbox[BOXTOP] = line->v1->y; - } - - // Update the line's slopetype - line->dx = line->v2->x - line->v1->x; - line->dy = line->v2->y - line->v1->y; + P_AdjustLine(Linedefs[i]); } CalcCenter(); } void FPolyObj::CalcCenter() { - SQWORD cx = 0, cy = 0; + DVector2 c = { 0, 0 }; for(unsigned i=0;ix; - cy += Vertices[i]->y; + c += Vertices[i]->fPos(); } - CenterSpot.x = (fixed_t)(cx / Vertices.Size()); - CenterSpot.y = (fixed_t)(cy / Vertices.Size()); + CenterSpot.pos = c / Vertices.Size(); } //========================================================================== @@ -972,11 +916,11 @@ void FPolyObj::CalcCenter() // //========================================================================== -bool FPolyObj::MovePolyobj (int x, int y, bool force) +bool FPolyObj::MovePolyobj (const DVector2 &pos, bool force) { FBoundingBox oldbounds = Bounds; UnLinkPolyobj (); - DoMovePolyobj (x, y); + DoMovePolyobj (pos); if (!force) { @@ -991,15 +935,13 @@ bool FPolyObj::MovePolyobj (int x, int y, bool force) } if (blocked) { - DoMovePolyobj (-x, -y); + DoMovePolyobj (-pos); LinkPolyobj(); return false; } } - StartSpot.x += x; - StartSpot.y += y; - CenterSpot.x += x; - CenterSpot.y += y; + StartSpot.pos += pos; + CenterSpot.pos += pos; LinkPolyobj (); ClearSubsectorLinks(); RecalcActorFloorCeil(Bounds | oldbounds); @@ -1012,21 +954,19 @@ bool FPolyObj::MovePolyobj (int x, int y, bool force) // //========================================================================== -void FPolyObj::DoMovePolyobj (int x, int y) +void FPolyObj::DoMovePolyobj (const DVector2 &pos) { for(unsigned i=0;i < Vertices.Size(); i++) { - Vertices[i]->x += x; - Vertices[i]->y += y; - PrevPts[i].x += x; - PrevPts[i].y += y; + Vertices[i]->set(Vertices[i]->fX() + pos.X, Vertices[i]->fY() + pos.Y); + PrevPts[i].pos += pos; } for (unsigned i = 0; i < Linedefs.Size(); i++) { - Linedefs[i]->bbox[BOXTOP] += y; - Linedefs[i]->bbox[BOXBOTTOM] += y; - Linedefs[i]->bbox[BOXLEFT] += x; - Linedefs[i]->bbox[BOXRIGHT] += x; + Linedefs[i]->bbox[BOXTOP] += pos.Y; + Linedefs[i]->bbox[BOXBOTTOM] += pos.Y; + Linedefs[i]->bbox[BOXLEFT] += pos.X; + Linedefs[i]->bbox[BOXRIGHT] += pos.X; } } @@ -1036,13 +976,15 @@ void FPolyObj::DoMovePolyobj (int x, int y) // //========================================================================== -static void RotatePt (int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, fixed_t startSpotY) +static void RotatePt (DAngle an, DVector2 &out, const DVector2 &start) { - fixed_t tr_x = *x; - fixed_t tr_y = *y; + DVector2 tr = out; - *x = (DMulScale16 (tr_x, finecosine[an], -tr_y, finesine[an]) & 0xFFFFFE00) + startSpotX; - *y = (DMulScale16 (tr_x, finesine[an], tr_y, finecosine[an]) & 0xFFFFFE00) + startSpotY; + double s = an.Sin(); + double c = an.Cos(); + + out.X = tr.X * c - tr.Y * s + start.X; + out.Y = tr.X * s + tr.Y * c + start.Y; } //========================================================================== @@ -1051,23 +993,22 @@ static void RotatePt (int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, fixed_ // //========================================================================== -bool FPolyObj::RotatePolyobj (angle_t angle, bool fromsave) +bool FPolyObj::RotatePolyobj (DAngle angle, bool fromsave) { - int an; + DAngle an; bool blocked; FBoundingBox oldbounds = Bounds; - an = (this->angle+angle)>>ANGLETOFINESHIFT; + an = Angle + angle; UnLinkPolyobj(); for(unsigned i=0;i < Vertices.Size(); i++) { - PrevPts[i].x = Vertices[i]->x; - PrevPts[i].y = Vertices[i]->y; - Vertices[i]->x = OriginalPts[i].x; - Vertices[i]->y = OriginalPts[i].y; - RotatePt(an, &Vertices[i]->x, &Vertices[i]->y, StartSpot.x, StartSpot.y); + PrevPts[i].pos = Vertices[i]->fPos(); + FPolyVertex torot = OriginalPts[i]; + RotatePt(an, torot.pos, StartSpot.pos); + Vertices[i]->set(torot.pos.X, torot.pos.Y); } blocked = false; validcount++; @@ -1087,15 +1028,14 @@ bool FPolyObj::RotatePolyobj (angle_t angle, bool fromsave) { for(unsigned i=0;i < Vertices.Size(); i++) { - Vertices[i]->x = PrevPts[i].x; - Vertices[i]->y = PrevPts[i].y; + Vertices[i]->set(PrevPts[i].pos.X, PrevPts[i].pos.Y); } UpdateBBox(); LinkPolyobj(); return false; } } - this->angle += angle; + Angle += angle; LinkPolyobj(); ClearSubsectorLinks(); RecalcActorFloorCeil(Bounds | oldbounds); @@ -1156,10 +1096,10 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) ld = sd->linedef; - top = GetSafeBlockY(ld->bbox[BOXTOP]-bmaporgy); - bottom = GetSafeBlockY(ld->bbox[BOXBOTTOM]-bmaporgy); - left = GetSafeBlockX(ld->bbox[BOXLEFT]-bmaporgx); - right = GetSafeBlockX(ld->bbox[BOXRIGHT]-bmaporgx); + top = GetBlockY(ld->bbox[BOXTOP]); + bottom = GetBlockY(ld->bbox[BOXBOTTOM]); + left = GetBlockX(ld->bbox[BOXLEFT]); + right = GetBlockX(ld->bbox[BOXRIGHT]); blocked = false; checker.Clear(); @@ -1193,8 +1133,8 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) if ((mobj->flags&MF_SOLID) && !(mobj->flags&MF_NOCLIP)) { FLineOpening open; - open.top = INT_MAX; - open.bottom = -INT_MAX; + open.top = LINEOPEN_MAX; + open.bottom = LINEOPEN_MIN; // [TN] Check wether this actor gets blocked by the line. if (ld->backsector != NULL && !(ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING)) @@ -1219,14 +1159,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) FBoundingBox box(mobj->X(), mobj->Y(), mobj->radius); - if (box.Right() <= ld->bbox[BOXLEFT] - || box.Left() >= ld->bbox[BOXRIGHT] - || box.Top() <= ld->bbox[BOXBOTTOM] - || box.Bottom() >= ld->bbox[BOXTOP]) - { - continue; - } - if (box.BoxOnLineSide(ld) != -1) + if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) { continue; } @@ -1235,7 +1168,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) // Best use the one facing the player and ignore the back side. if (ld->sidedef[1] != NULL) { - int side = P_PointOnLineSidePrecise(mobj->X(), mobj->Y(), ld); + int side = P_PointOnLineSidePrecise(mobj->Pos(), ld); if (ld->sidedef[side] != sd) { continue; @@ -1283,14 +1216,14 @@ void FPolyObj::LinkPolyobj () vertex_t *vt; vt = Sidedefs[i]->linedef->v1; - Bounds.AddToBox(vt->x, vt->y); + Bounds.AddToBox(vt->fPos()); vt = Sidedefs[i]->linedef->v2; - Bounds.AddToBox(vt->x, vt->y); + Bounds.AddToBox(vt->fPos()); } - bbox[BOXRIGHT] = GetSafeBlockX(Bounds.Right() - bmaporgx); - bbox[BOXLEFT] = GetSafeBlockX(Bounds.Left() - bmaporgx); - bbox[BOXTOP] = GetSafeBlockY(Bounds.Top() - bmaporgy); - bbox[BOXBOTTOM] = GetSafeBlockY(Bounds.Bottom() - bmaporgy); + bbox[BOXRIGHT] = GetBlockX(Bounds.Right()); + bbox[BOXLEFT] = GetBlockX(Bounds.Left()); + bbox[BOXTOP] = GetBlockY(Bounds.Top()); + bbox[BOXBOTTOM] = GetBlockY(Bounds.Bottom()); // add the polyobj to each blockmap section for(int j = bbox[BOXBOTTOM]*bmapwidth; j <= bbox[BOXTOP]*bmapwidth; j += bmapwidth) @@ -1363,10 +1296,10 @@ void FPolyObj::RecalcActorFloorCeil(FBoundingBox bounds) const // //=========================================================================== -void FPolyObj::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy, side_t **side) const +void FPolyObj::ClosestPoint(const DVector2 &fpos, DVector2 &out, side_t **side) const { unsigned int i; - double x = fx, y = fy; + double x = fpos.X, y = fpos.Y; double bestdist = HUGE_VAL; double bestx = 0, besty = 0; side_t *bestline = NULL; @@ -1375,34 +1308,34 @@ void FPolyObj::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy, si { vertex_t *v1 = Sidedefs[i]->V1(); vertex_t *v2 = Sidedefs[i]->V2(); - double a = v2->x - v1->x; - double b = v2->y - v1->y; + double a = v2->fX() - v1->fX(); + double b = v2->fY() - v1->fY(); double den = a*a + b*b; double ix, iy, dist; if (den == 0) { // Line is actually a point! - ix = v1->x; - iy = v1->y; + ix = v1->fX(); + iy = v1->fY(); } else { - double num = (x - v1->x) * a + (y - v1->y) * b; + double num = (x - v1->fX()) * a + (y - v1->fY()) * b; double u = num / den; if (u <= 0) { - ix = v1->x; - iy = v1->y; + ix = v1->fX(); + iy = v1->fY(); } else if (u >= 1) { - ix = v2->x; - iy = v2->y; + ix = v2->fX(); + iy = v2->fY(); } else { - ix = v1->x + u * a; - iy = v1->y + u * b; + ix = v1->fX() + u * a; + iy = v1->fY() + u * b; } } a = (ix - x); @@ -1416,8 +1349,7 @@ void FPolyObj::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy, si bestline = Sidedefs[i]; } } - ox = fixed_t(bestx); - oy = fixed_t(besty); + out = { bestx, besty }; if (side != NULL) { *side = bestline; @@ -1653,11 +1585,10 @@ static void SpawnPolyobj (int index, int tag, int type) // //========================================================================== -static void TranslateToStartSpot (int tag, int originX, int originY) +static void TranslateToStartSpot (int tag, const DVector2 &origin) { FPolyObj *po; - int deltaX; - int deltaY; + DVector2 delta; po = NULL; for (int i = 0; i < po_NumPolyobjs; i++) @@ -1678,8 +1609,7 @@ static void TranslateToStartSpot (int tag, int originX, int originY) } po->OriginalPts.Resize(po->Sidedefs.Size()); po->PrevPts.Resize(po->Sidedefs.Size()); - deltaX = originX - po->StartSpot.x; - deltaY = originY - po->StartSpot.y; + delta = origin - po->StartSpot.pos; for (unsigned i = 0; i < po->Sidedefs.Size(); i++) { @@ -1687,21 +1617,19 @@ static void TranslateToStartSpot (int tag, int originX, int originY) } for (unsigned i = 0; i < po->Linedefs.Size(); i++) { - po->Linedefs[i]->bbox[BOXTOP] -= deltaY; - po->Linedefs[i]->bbox[BOXBOTTOM] -= deltaY; - po->Linedefs[i]->bbox[BOXLEFT] -= deltaX; - po->Linedefs[i]->bbox[BOXRIGHT] -= deltaX; + po->Linedefs[i]->bbox[BOXTOP] -= delta.Y; + po->Linedefs[i]->bbox[BOXBOTTOM] -= delta.Y; + po->Linedefs[i]->bbox[BOXLEFT] -= delta.X; + po->Linedefs[i]->bbox[BOXRIGHT] -= delta.X; } for (unsigned i = 0; i < po->Vertices.Size(); i++) { - po->Vertices[i]->x -= deltaX; - po->Vertices[i]->y -= deltaY; - po->OriginalPts[i].x = po->Vertices[i]->x - po->StartSpot.x; - po->OriginalPts[i].y = po->Vertices[i]->y - po->StartSpot.y; + po->Vertices[i]->set(po->Vertices[i]->fX() - delta.X, po->Vertices[i]->fY() - delta.Y); + po->OriginalPts[i].pos = po->Vertices[i]->fPos() - po->StartSpot.pos; } po->CalcCenter(); // For compatibility purposes - po->CenterSubsector = R_PointInSubsector(po->CenterSpot.x, po->CenterSpot.y); + po->CenterSubsector = R_PointInSubsector(po->CenterSpot.pos); } //========================================================================== @@ -1732,8 +1660,7 @@ void PO_Init (void) if (polyspawn->type >= SMT_PolySpawn && polyspawn->type <= SMT_PolySpawnHurt) { // Polyobj StartSpot Pt. - polyobjs[polyIndex].StartSpot.x = polyspawn->x; - polyobjs[polyIndex].StartSpot.y = polyspawn->y; + polyobjs[polyIndex].StartSpot.pos = polyspawn->pos; SpawnPolyobj(polyIndex, polyspawn->angle, polyspawn->type); polyIndex++; *prev = polyspawn->next; @@ -1752,7 +1679,7 @@ void PO_Init (void) if (polyspawn->type == SMT_PolyAnchor) { // Polyobj Anchor Pt. - TranslateToStartSpot (polyspawn->angle, polyspawn->x, polyspawn->y); + TranslateToStartSpot (polyspawn->angle, polyspawn->pos); } delete polyspawn; polyspawn = next; @@ -1770,15 +1697,15 @@ void PO_Init (void) } InitBlockMap(); - // [RH] Don't need the seg lists anymore + // [RH] Don't need the side lists anymore KillSideLists (); for(int i=0;idx; - double fdy = (double)no->dy; - no->len = (float)sqrt(fdx * fdx + fdy * fdy); + double fdx = FIXED2DBL(no->dx); + double fdy = FIXED2DBL(no->dy); + no->len = (float)g_sqrt(fdx * fdx + fdy * fdy); } // mark all subsectors which have a seg belonging to a polyobj @@ -1880,14 +1807,14 @@ static bool GetIntersection(FPolySeg *seg, node_t *bsp, FPolyVertex *v) double num; double den; - double v2x = (double)seg->v1.x; - double v2y = (double)seg->v1.y; - double v2dx = (double)(seg->v2.x - seg->v1.x); - double v2dy = (double)(seg->v2.y - seg->v1.y); - double v1x = (double)bsp->x; - double v1y = (double)bsp->y; - double v1dx = (double)bsp->dx; - double v1dy = (double)bsp->dy; + double v2x = seg->v1.pos.X; + double v2y = seg->v1.pos.Y; + double v2dx = seg->v2.pos.X - v2x; + double v2dy = seg->v2.pos.Y - v2y; + double v1x = FIXED2DBL(bsp->x); + double v1y = FIXED2DBL(bsp->y); + double v1dx = FIXED2DBL(bsp->dx); + double v1dy = FIXED2DBL(bsp->dy); den = v1dy*v2dx - v1dx*v2dy; @@ -1899,8 +1826,8 @@ static bool GetIntersection(FPolySeg *seg, node_t *bsp, FPolyVertex *v) if (frac < 0. || frac > 1.) return false; - v->x = xs_RoundToInt(v2x + frac * v2dx); - v->y = xs_RoundToInt(v2y + frac * v2dy); + v->pos.X = v2x + frac * v2dx; + v->pos.Y = v2y + frac * v2dy; return true; } @@ -1914,7 +1841,7 @@ static bool GetIntersection(FPolySeg *seg, node_t *bsp, FPolyVertex *v) static double PartitionDistance(FPolyVertex *vt, node_t *node) { - return fabs(double(-node->dy) * (vt->x - node->x) + double(node->dx) * (vt->y - node->y)) / node->len; + return fabs(FIXED2DBL(-node->dy) * (vt->pos.X - FIXED2DBL(node->x)) + FIXED2DBL(node->dx) * (vt->pos.Y - FIXED2DBL(node->y))) / node->len; } //========================================================================== @@ -1951,21 +1878,23 @@ static void AddToBBox(fixed_t child[4], fixed_t parent[4]) static void AddToBBox(FPolyVertex *v, fixed_t bbox[4]) { - if (v->x < bbox[BOXLEFT]) + fixed_t x = FLOAT2FIXED(v->pos.X); + fixed_t y = FLOAT2FIXED(v->pos.Y); + if (x < bbox[BOXLEFT]) { - bbox[BOXLEFT] = v->x; + bbox[BOXLEFT] = x; } - if (v->x > bbox[BOXRIGHT]) + if (x > bbox[BOXRIGHT]) { - bbox[BOXRIGHT] = v->x; + bbox[BOXRIGHT] = x; } - if (v->y < bbox[BOXBOTTOM]) + if (y < bbox[BOXBOTTOM]) { - bbox[BOXBOTTOM] = v->y; + bbox[BOXBOTTOM] = y; } - if (v->y > bbox[BOXTOP]) + if (y > bbox[BOXTOP]) { - bbox[BOXTOP] = v->y; + bbox[BOXTOP] = y; } } @@ -1984,7 +1913,7 @@ static void SplitPoly(FPolyNode *pnode, void *node, fixed_t bbox[4]) { node_t *bsp = (node_t *)node; - int centerside = R_PointOnSide(pnode->poly->CenterSpot.x, pnode->poly->CenterSpot.y, bsp); + int centerside = R_PointOnSide(pnode->poly->CenterSpot.pos, bsp); lists[0].Clear(); lists[1].Clear(); @@ -2020,19 +1949,19 @@ static void SplitPoly(FPolyNode *pnode, void *node, fixed_t bbox[4]) } else { - int side = R_PointOnSide(seg->v2.x, seg->v2.y, bsp); + int side = R_PointOnSide(seg->v2.pos, bsp); lists[side].Push(*seg); } } else if (dist_v2 <= POLY_EPSILON) { - int side = R_PointOnSide(seg->v1.x, seg->v1.y, bsp); + int side = R_PointOnSide(seg->v1.pos, bsp); lists[side].Push(*seg); } else { - int side1 = R_PointOnSide(seg->v1.x, seg->v1.y, bsp); - int side2 = R_PointOnSide(seg->v2.x, seg->v2.y, bsp); + int side1 = R_PointOnSide(seg->v1.pos, bsp); + int side2 = R_PointOnSide(seg->v2.pos, bsp); if(side1 != side2) { diff --git a/src/po_man.h b/src/po_man.h index 6ab7d20a7..2fbc433cf 100644 --- a/src/po_man.h +++ b/src/po_man.h @@ -9,12 +9,11 @@ class DPolyAction; struct FPolyVertex { - fixed_t x, y; + DVector2 pos; FPolyVertex &operator=(vertex_t *v) { - x = v->x; - y = v->y; + pos = v->fPos(); return *this; } }; @@ -57,14 +56,14 @@ struct FPolyObj subsector_t *CenterSubsector; int MirrorNum; - angle_t angle; + DAngle Angle; int tag; // reference tag assigned in HereticEd int bbox[4]; // bounds in blockmap coordinates int validcount; int crush; // should the polyobj attempt to crush mobjs? bool bHurtOnTouch; // should the polyobj hurt anything it touches? int seqType; - fixed_t size; // polyobj size (area of POLY_AREAUNIT == size of FRACUNIT) + double Size; // polyobj size (area of POLY_AREAUNIT == size of FRACUNIT) FPolyNode *subsectorlinks; DPolyAction *specialdata; // pointer to a thinker, if the poly is moving TObjPtr interpolation; @@ -74,9 +73,9 @@ struct FPolyObj void StopInterpolation(); int GetMirror(); - bool MovePolyobj (int x, int y, bool force = false); - bool RotatePolyobj (angle_t angle, bool fromsave = false); - void ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy, side_t **side) const; + bool MovePolyobj (const DVector2 &pos, bool force = false); + bool RotatePolyobj (DAngle angle, bool fromsave = false); + void ClosestPoint(const DVector2 &fpos, DVector2 &out, side_t **side) const; void LinkPolyobj (); void RecalcActorFloorCeil(FBoundingBox bounds) const; void CreateSubsectorLinks(); @@ -88,7 +87,7 @@ private: void ThrustMobj (AActor *actor, side_t *side); void UpdateBBox (); - void DoMovePolyobj (int x, int y); + void DoMovePolyobj (const DVector2 &pos); void UnLinkPolyobj (); bool CheckMobjBlocking (side_t *sd); @@ -118,9 +117,9 @@ typedef enum } podoortype_t; bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide); -bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, fixed_t dist, bool overRide); -bool EV_MovePolyTo (line_t *line, int polyNum, int speed, fixed_t x, fixed_t y, bool overRide); -bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, int delay, int distance, podoortype_t type); +bool EV_MovePoly (line_t *line, int polyNum, double speed, DAngle angle, double dist, bool overRide); +bool EV_MovePolyTo (line_t *line, int polyNum, double speed, const DVector2 &pos, bool overRide); +bool EV_OpenPolyDoor (line_t *line, int polyNum, double speed, DAngle angle, int delay, double distance, podoortype_t type); bool EV_StopPoly (int polyNum); @@ -129,8 +128,7 @@ bool EV_StopPoly (int polyNum); struct polyspawns_t { polyspawns_t *next; - fixed_t x; - fixed_t y; + DVector2 pos; short angle; short type; }; diff --git a/src/portal.cpp b/src/portal.cpp index ad8e166b1..f0c5b8962 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -53,6 +53,7 @@ #include "p_maputl.h" #include "p_spec.h" #include "p_checkposition.h" +#include "math/cmath.h" // simulation recurions maximum CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO) @@ -162,19 +163,19 @@ void FLinePortalTraverse::AddLineIntercepts(int bx, int by) for (unsigned i = 0; ivalidcount == validcount) continue; // already processed - if (P_PointOnDivlineSidePrecise (ld->v1->x, ld->v1->y, &trace) == - P_PointOnDivlineSidePrecise (ld->v2->x, ld->v2->y, &trace)) + if (P_PointOnDivlineSide (ld->v1->fPos(), &trace) == + P_PointOnDivlineSide (ld->v2->fPos(), &trace)) { continue; // line isn't crossed } P_MakeDivline (ld, &dl); - if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &dl) != 0 || - P_PointOnDivlineSidePrecise (trace.x+trace.dx, trace.y+trace.dy, &dl) != 1) + if (P_PointOnDivlineSide(trace.x, trace.y, &dl) != 0 || + P_PointOnDivlineSide(trace.x + trace.dx, trace.y + trace.dy, &dl) != 1) { continue; // line isn't crossed from the front side } @@ -182,7 +183,7 @@ void FLinePortalTraverse::AddLineIntercepts(int bx, int by) // hit the line P_MakeDivline(ld, &dl); frac = P_InterceptVector(&trace, &dl); - if (frac < 0 || frac > FRACUNIT) continue; // behind source + if (frac < 0 || frac > 1.) continue; // behind source intercept_t newintercept; @@ -204,8 +205,7 @@ FArchive &operator<< (FArchive &arc, FLinePortal &port) { arc << port.mOrigin << port.mDestination - << port.mXDisplacement - << port.mYDisplacement + << port.mDisplacement << port.mType << port.mFlags << port.mDefFlags @@ -249,12 +249,12 @@ static void SetRotation(FLinePortal *port) { if (port != NULL && port->mDestination != NULL) { - line_t *dst = port->mDestination; - line_t *line = port->mOrigin; - double angle = atan2(dst->dy, dst->dx) - atan2(line->dy, line->dx) + M_PI; - port->mSinRot = FLOAT2FIXED(sin(angle)); - port->mCosRot = FLOAT2FIXED(cos(angle)); - port->mAngleDiff = RAD2ANGLE(angle); + line_t *dst = port->mDestination; + line_t *line = port->mOrigin; + DAngle angle = dst->Delta().Angle() - line->Delta().Angle() + 180.; + port->mSinRot = sindeg(angle.Degrees); // Here precision matters so use the slower but more precise versions. + port->mCosRot = cosdeg(angle.Degrees); + port->mAngleDiff = angle; } } @@ -384,8 +384,8 @@ void P_UpdatePortal(FLinePortal *port) } else { - port->mXDisplacement = port->mDestination->v2->x - port->mOrigin->v1->x; - port->mYDisplacement = port->mDestination->v2->y - port->mOrigin->v1->y; + port->mDisplacement.X = port->mDestination->v2->fX() - port->mOrigin->v1->fX(); + port->mDisplacement.Y = port->mDestination->v2->fY() - port->mOrigin->v1->fY(); } } } @@ -500,26 +500,22 @@ void P_ClearPortals() } -inline int P_PointOnLineSideExplicit (fixed_t x, fixed_t y, fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2) -{ - return DMulScale32 (y-y1, x2-x1, x1-x, y2-y1) > 0; -} - //============================================================================ // // check if this line is between portal and the viewer. clip away if it is. // //============================================================================ -inline int P_GetLineSide(fixed_t x, fixed_t y, const line_t *line) +inline int P_GetLineSide(const DVector2 &pos, const line_t *line) { - return DMulScale32(y - line->v1->y, line->dx, line->v1->x - x, line->dy); + 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->x, line->v1->y, portal); - int behind2 = P_GetLineSide(line->v2->x, line->v2->y, portal); + int behind1 = P_GetLineSide(line->v1->fPos(), portal); + int behind2 = P_GetLineSide(line->v2->fPos(), portal); if (behind1 == 0 && behind2 == 0) { @@ -543,14 +539,12 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie else { // The line intersects with the portal straight, so we need to do another check to see how both ends of the portal lie in relation to the viewer. - int viewside = P_PointOnLineSidePrecise(viewx, viewy, line); - int p1side = P_GetLineSide(portal->v1->x, portal->v1->y, line); - int p2side = P_GetLineSide(portal->v2->x, portal->v2->y, line); - // Do the same handling of points on the portal straight than above. + int viewside = P_GetLineSide(view, line); + int p1side = P_GetLineSide(portal->v1->fPos(), line); + int p2side = P_GetLineSide(portal->v2->fPos(), line); + // Do the same handling of points on the portal straight as above. if (p1side == 0) p1side = p2side; else if (p2side == 0) p2side = p1side; - p1side = p1side > 0; - p2side = p2side > 0; // If the portal is on the other side of the line than the viewpoint, there is no possibility to see this line inside the portal. return (p1side == p2side && viewside != p1side); } @@ -562,22 +556,22 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie // //============================================================================ -void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y) +void P_TranslatePortalXY(line_t* src, double& x, double& y) { if (!src) return; FLinePortal *port = src->getPortal(); if (!port) return; // offsets from line - fixed_t nposx = x - src->v1->x; - fixed_t nposy = y - src->v1->y; + double nposx = x - src->v1->fX(); + double nposy = y - src->v1->fY(); // Rotate position along normal to match exit linedef - fixed_t tx = FixedMul(nposx, port->mCosRot) - FixedMul(nposy, port->mSinRot); - fixed_t ty = FixedMul(nposy, port->mCosRot) + FixedMul(nposx, port->mSinRot); + double tx = nposx * port->mCosRot - nposy * port->mSinRot; + double ty = nposy * port->mCosRot + nposx * port->mSinRot; - tx += port->mDestination->v2->x; - ty += port->mDestination->v2->y; + tx += port->mDestination->v2->fX(); + ty += port->mDestination->v2->fY(); x = tx; y = ty; @@ -589,16 +583,16 @@ void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y) // //============================================================================ -void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy) +void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely) { if (!src) return; FLinePortal *port = src->getPortal(); if (!port) return; - fixed_t orig_velx = vx; - fixed_t orig_vely = vy; - vx = FixedMul(orig_velx, port->mCosRot) - FixedMul(orig_vely, port->mSinRot); - vy = FixedMul(orig_vely, port->mCosRot) + FixedMul(orig_velx, port->mSinRot); + double orig_velx = velx; + double orig_vely = vely; + velx = orig_velx * port->mCosRot - orig_vely * port->mSinRot; + vely = orig_vely * port->mCosRot - orig_velx * port->mSinRot; } //============================================================================ @@ -607,12 +601,12 @@ void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy) // //============================================================================ -void P_TranslatePortalAngle(line_t* src, angle_t& angle) +void P_TranslatePortalAngle(line_t* src, DAngle& angle) { if (!src) return; FLinePortal *port = src->getPortal(); if (!port) return; - angle += port->mAngleDiff; + angle = (angle + port->mAngleDiff).Normalized360(); } //============================================================================ @@ -621,7 +615,7 @@ void P_TranslatePortalAngle(line_t* src, angle_t& angle) // //============================================================================ -void P_TranslatePortalZ(line_t* src, fixed_t& z) +void P_TranslatePortalZ(line_t* src, double& z) { // args[2] = 0 - no adjustment // args[2] = 1 - adjust by floor difference @@ -632,11 +626,11 @@ void P_TranslatePortalZ(line_t* src, fixed_t& z) switch (src->getPortalAlignment()) { case PORG_FLOOR: - z = z - src->frontsector->floorplane.ZatPoint(src->v1->x, src->v1->y) + dst->frontsector->floorplane.ZatPoint(dst->v2->x, dst->v2->y); + z = z - src->frontsector->floorplane.ZatPoint(src->v1) + dst->frontsector->floorplane.ZatPoint(dst->v2); return; case PORG_CEILING: - z = z - src->frontsector->ceilingplane.ZatPoint(src->v1->x, src->v1->y) + dst->frontsector->ceilingplane.ZatPoint(dst->v2->x, dst->v2->y); + z = z - src->frontsector->ceilingplane.ZatPoint(src->v1) + dst->frontsector->ceilingplane.ZatPoint(dst->v2); return; default: @@ -644,37 +638,6 @@ void P_TranslatePortalZ(line_t* src, fixed_t& z) } } -//============================================================================ -// -// calculate shortest distance from a point (x,y) to a linedef -// -//============================================================================ - -fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y) -{ - angle_t angle = R_PointToAngle2(0, 0, line->dx, line->dy); - angle += ANGLE_180; - - fixed_t dx = line->v1->x - x; - fixed_t dy = line->v1->y - 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 = sqrt(_vx*_vx+_vy*_vy); - vx = FLOAT2FIXED(_vx/len); - vy = FLOAT2FIXED(_vy/len); -} - //============================================================================ // // P_GetOffsetPosition @@ -684,17 +647,17 @@ void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy) // //============================================================================ -fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy) +DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy) { - fixedvec2 dest = { x + dx, y + dy }; + DVector2 dest(x + dx, y + dy); if (PortalBlockmap.containsLines) { - fixed_t actx = x, acty = y; + double actx = x, acty = y; // Try some easily discoverable early-out first. If we know that the trace cannot possibly find a portal, this saves us from calling the traverser completely for vast parts of the map. - if (dx < 128 * FRACUNIT && dy < 128 * FRACUNIT) + if (dx < 128 && dy < 128) { - fixed_t blockx = GetSafeBlockX(actx - bmaporgx); - fixed_t blocky = GetSafeBlockY(acty - bmaporgy); + int blockx = GetBlockX(actx); + int blocky = GetBlockY(acty); if (blockx < 0 || blocky < 0 || blockx >= bmapwidth || blocky >= bmapheight || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest; } @@ -715,26 +678,24 @@ fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy) // Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence. if (port->mFlags & PORTF_INTERACTIVE) { - fixedvec2 hit = it.InterceptPoint(in); + DVector2 hit = it.InterceptPoint(in); if (port->mType == PORTT_LINKED) { // optimized handling for linked portals where we only need to add an offset. - hit.x += port->mXDisplacement; - hit.y += port->mYDisplacement; - dest.x += port->mXDisplacement; - dest.y += port->mYDisplacement; + hit += port->mDisplacement; + dest += port->mDisplacement; } else { // interactive ones are more complex because the vector may be rotated. // Note: There is no z-translation here, there's just too much code in the engine that wouldn't be able to handle interactive portals with a height difference. - P_TranslatePortalXY(line, hit.x, hit.y); - P_TranslatePortalXY(line, dest.x, dest.y); + P_TranslatePortalXY(line, hit.X, hit.Y); + P_TranslatePortalXY(line, dest.X, dest.Y); } // update the fields, end this trace and restart from the new position - dx = dest.x - hit.x; - dy = dest.y - hit.y; + dx = dest.X - hit.X; + dy = dest.Y - hit.Y; repeat = true; } @@ -814,13 +775,12 @@ static void AddDisplacementForPortal(AStackPoint *portal) FDisplacement & disp = Displacements(thisgroup, othergroup); if (!disp.isSet) { - disp.pos.x = portal->scaleX; - disp.pos.y = portal->scaleY; + disp.pos = portal->Scale; disp.isSet = true; } else { - if (disp.pos.x != portal->scaleX || disp.pos.y != portal->scaleY) + if (disp.pos != portal->Scale) { Printf("Portal between sectors %d and %d has displacement mismatch and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum); portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL; @@ -850,13 +810,12 @@ static void AddDisplacementForPortal(FLinePortal *portal) FDisplacement & disp = Displacements(thisgroup, othergroup); if (!disp.isSet) { - disp.pos.x = portal->mXDisplacement; - disp.pos.y = portal->mYDisplacement; + disp.pos = portal->mDisplacement; disp.isSet = true; } else { - if (disp.pos.x != portal->mXDisplacement || disp.pos.y != portal->mYDisplacement) + if (disp.pos != portal->mDisplacement) { Printf("Portal between lines %d and %d has displacement mismatch\n", int(portal->mOrigin - lines), int(portal->mDestination - lines)); portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; @@ -897,7 +856,7 @@ static bool ConnectGroups() FDisplacement &dispxz = Displacements(x, z); if (dispxz.isSet) { - if (dispxy.pos.x + dispyz.pos.x != dispxz.pos.x || dispxy.pos.y + dispyz.pos.y != dispxz.pos.y) + if (dispxy.pos.X + dispyz.pos.X != dispxz.pos.X || dispxy.pos.Y + dispyz.pos.Y != dispxz.pos.Y) { bogus = true; } @@ -960,30 +919,30 @@ void P_CreateLinkedPortals() id = 1; if (orgs.Size() != 0) { - for (int i = 0; i < numsectors; i++) + for (int i = 0; i < numsectors; i++) + { + for (int j = 0; j < 2; j++) { - for (int j = 0; j < 2; j++) + AActor *box = sectors[i].SkyBoxes[j]; + if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL) { - AActor *box = sectors[i].SkyBoxes[j]; - if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL) + secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane; + if (plane.isSlope()) { - secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane; - if (plane.a || plane.b) - { - // The engine cannot deal with portals on a sloped plane. - sectors[i].SkyBoxes[j] = NULL; + // The engine cannot deal with portals on a sloped plane. + sectors[i].SkyBoxes[j] = NULL; Printf("Portal on %s of sector %d is sloped and will be disabled\n", j == 0 ? "floor" : "ceiling", i); - } } } } + } - // Group all sectors, starting at each portal origin. - for (unsigned i = 0; i < orgs.Size(); i++) - { - if (CollectSectors(id, orgs[i]->Sector)) id++; - if (CollectSectors(id, orgs[i]->Mate->Sector)) id++; - } + // Group all sectors, starting at each portal origin. + for (unsigned i = 0; i < orgs.Size(); i++) + { + if (CollectSectors(id, orgs[i]->Sector)) id++; + if (CollectSectors(id, orgs[i]->Mate->Sector)) id++; + } } for (unsigned i = 0; i < linePortals.Size(); i++) { @@ -1033,7 +992,7 @@ void P_CreateLinkedPortals() FDisplacement &dispxy = Displacements(x, y); FDisplacement &dispyx = Displacements(y, x); if (dispxy.isSet && dispyx.isSet && - (dispxy.pos.x != -dispyx.pos.x || dispxy.pos.y != -dispyx.pos.y)) + (dispxy.pos.X != -dispyx.pos.X || dispxy.pos.Y != -dispyx.pos.Y)) { int sec1 = -1, sec2 = -1; for (int i = 0; i < numsectors && (sec1 == -1 || sec2 == -1); i++) @@ -1090,14 +1049,14 @@ void P_CreateLinkedPortals() } if (sectors[i].PortalIsLinked(sector_t::ceiling) && sectors[i].PortalIsLinked(sector_t::floor)) { - fixed_t cz = sectors[i].SkyBoxes[sector_t::ceiling]->threshold; - fixed_t fz = sectors[i].SkyBoxes[sector_t::floor]->threshold; + double cz = sectors[i].SkyBoxes[sector_t::ceiling]->specialf1; + double fz = sectors[i].SkyBoxes[sector_t::floor]->specialf1; if (cz < fz) { // This is a fatal condition. We have to remove one of the two portals. Choose the one that doesn't match the current plane - Printf("Error in sector %d: Ceiling portal at z=%d is below floor portal at z=%d\n", i, cz, fz); - fixed_t cp = sectors[i].ceilingplane.Zat0(); - fixed_t fp = sectors[i].ceilingplane.Zat0(); + Printf("Error in sector %d: Ceiling portal at z=%f is below floor portal at z=%f\n", i, cz, fz); + double cp = -sectors[i].ceilingplane.fD(); + double fp = -sectors[i].ceilingplane.fD(); if (cp < fp || fz == fp) { sectors[i].SkyBoxes[sector_t::ceiling] = NULL; @@ -1138,7 +1097,7 @@ void P_CreateLinkedPortals() // //============================================================================ -bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t upperz, fixed_t checkradius, FPortalGroupArray &out) +bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out) { // Keep this temporary work stuff static. This function can never be called recursively // and this would have to be reallocated for each call otherwise. @@ -1172,15 +1131,9 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t FDisplacement &disp = Displacements(thisgroup, othergroup); if (!disp.isSet) continue; // no connection. - FBoundingBox box(position.x + disp.pos.x, position.y + disp.pos.y, checkradius); + FBoundingBox box(position.X + disp.pos.X, position.Y + disp.pos.Y, checkradius); - if (box.Right() <= ld->bbox[BOXLEFT] - || box.Left() >= ld->bbox[BOXRIGHT] - || box.Top() <= ld->bbox[BOXBOTTOM] - || box.Bottom() >= ld->bbox[BOXTOP]) - continue; // not touched - - if (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]); } bool foundone = true; @@ -1203,29 +1156,25 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t } if (out.method != FPortalGroupArray::PGA_NoSectorPortals) { - sector_t *sec = P_PointInSector(position.x, position.y); + sector_t *sec = P_PointInSector(position); sector_t *wsec = sec; - while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->SkyBoxes[sector_t::ceiling]->threshold) + while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->SkyBoxes[sector_t::ceiling]->specialf1) { sector_t *othersec = wsec->SkyBoxes[sector_t::ceiling]->Sector; - fixedvec2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup); - fixed_t dx = position.x + pos.x; - fixed_t dy = position.y + pos.y; + DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position; processMask.setBit(othersec->PortalGroup); out.Add(othersec->PortalGroup | FPortalGroupArray::UPPER); - wsec = P_PointInSector(dx, dy); // get upper sector at the exact spot we want to check and repeat + wsec = P_PointInSector(pos); // get upper sector at the exact spot we want to check and repeat retval = true; } wsec = sec; - while (!wsec->PortalBlocksMovement(sector_t::floor) && position.z < wsec->SkyBoxes[sector_t::floor]->threshold) + while (!wsec->PortalBlocksMovement(sector_t::floor) && position.Z < wsec->SkyBoxes[sector_t::floor]->specialf1) { sector_t *othersec = wsec->SkyBoxes[sector_t::floor]->Sector; - fixedvec2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup); - fixed_t dx = position.x + pos.x; - fixed_t dy = position.y + pos.y; + DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position; processMask.setBit(othersec->PortalGroup | FPortalGroupArray::LOWER); out.Add(othersec->PortalGroup); - wsec = P_PointInSector(dx, dy); // get lower sector at the exact spot we want to check and repeat + wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat retval = true; } if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals) @@ -1235,19 +1184,13 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t int thisgroup = startgroup; for (unsigned i = 0; i < groupsToCheck.Size();i++) { - fixedvec2 disp = Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT); - FBoundingBox box(position.x + disp.x, position.y + disp.y, checkradius); + DVector2 disp = Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT); + FBoundingBox box(position.X + disp.X, position.Y + disp.Y, checkradius); FBlockLinesIterator it(box); line_t *ld; while ((ld = it.Next())) { - if (box.Right() <= ld->bbox[BOXLEFT] - || box.Left() >= ld->bbox[BOXRIGHT] - || box.Top() <= ld->bbox[BOXBOTTOM] - || box.Bottom() >= ld->bbox[BOXTOP]) - continue; - - if (box.BoxOnLineSide(ld) != -1) + if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) continue; if (!(thisgroup & FPortalGroupArray::LOWER)) @@ -1257,7 +1200,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t sector_t *sec = s ? ld->backsector : ld->frontsector; if (sec && !(sec->PortalBlocksMovement(sector_t::ceiling))) { - if (sec->SkyBoxes[sector_t::ceiling]->threshold < upperz) + if (sec->SkyBoxes[sector_t::ceiling]->specialf1 < upperz) { int grp = sec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup; if (!(processMask.getBit(grp))) @@ -1276,7 +1219,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t sector_t *sec = s ? ld->backsector : ld->frontsector; if (sec && !(sec->PortalBlocksMovement(sector_t::floor))) { - if (sec->SkyBoxes[sector_t::floor]->threshold > position.z) + if (sec->SkyBoxes[sector_t::floor]->specialf1 > position.Z) { int grp = sec->SkyBoxes[sector_t::floor]->Sector->PortalGroup; if (!(processMask.getBit(grp))) @@ -1309,7 +1252,7 @@ CCMD(dumplinktable) for (int y = 1; y < Displacements.size; y++) { FDisplacement &disp = Displacements(x, y); - Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, disp.pos.x >> FRACBITS, disp.pos.y >> FRACBITS); + Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y)); } Printf("\n"); } diff --git a/src/portal.h b/src/portal.h index d5a781f2d..2868521bc 100644 --- a/src/portal.h +++ b/src/portal.h @@ -26,7 +26,7 @@ struct FPortalGroupArray; struct FDisplacement { - fixedvec2 pos; + DVector2 pos; bool isSet; BYTE indirect; // just for illustration. @@ -54,15 +54,16 @@ struct FDisplacementTable return data[x + size*y]; } - fixedvec2 getOffset(int x, int y) const + DVector2 getOffset(int x, int y) const { if (x == y) { - fixedvec2 nulvec = { 0,0 }; + DVector2 nulvec = { 0,0 }; return nulvec; // shortcut for the most common case } return data[x + size*y].pos; } + }; extern FDisplacementTable Displacements; @@ -173,15 +174,14 @@ struct FLinePortal { line_t *mOrigin; line_t *mDestination; - fixed_t mXDisplacement; - fixed_t mYDisplacement; + DVector2 mDisplacement; BYTE mType; BYTE mFlags; BYTE mDefFlags; BYTE mAlign; - angle_t mAngleDiff; - fixed_t mSinRot; - fixed_t mCosRot; + DAngle mAngleDiff; + double mSinRot; + double mCosRot; }; extern TArray linePortals; @@ -191,7 +191,7 @@ void P_SpawnLinePortal(line_t* line); void P_FinalizePortals(); bool P_ChangePortal(line_t *ln, int thisid, int destid); void P_CreateLinkedPortals(); -bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t upperz, fixed_t checkradius, FPortalGroupArray &out); +bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out); void P_CollectLinkedPortals(); inline int P_NumPortalGroups() { @@ -200,13 +200,12 @@ inline int P_NumPortalGroups() /* code ported from prototype */ -bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial = true, bool samebehind = true); -void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y); -void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy); -void P_TranslatePortalAngle(line_t* src, angle_t& angle); -void P_TranslatePortalZ(line_t* src, fixed_t& z); -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); +bool P_ClipLineToPortal(line_t* line, line_t* portal, DVector2 view, bool partial = true, bool samebehind = true); +void P_TranslatePortalXY(line_t* src, double& vx, double& vy); +void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely); +void P_TranslatePortalAngle(line_t* src, DAngle& angle); +void P_TranslatePortalZ(line_t* src, double& vz); +DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy); + #endif \ No newline at end of file diff --git a/src/posix/cocoa/i_timer.cpp b/src/posix/cocoa/i_timer.cpp index b08a43139..901657eb9 100644 --- a/src/posix/cocoa/i_timer.cpp +++ b/src/posix/cocoa/i_timer.cpp @@ -186,7 +186,7 @@ unsigned int I_FPSTime() } -fixed_t I_GetTimeFrac(uint32* ms) +double I_GetTimeFrac(uint32* ms) { const uint32_t now = I_MSTime(); @@ -196,8 +196,8 @@ fixed_t I_GetTimeFrac(uint32* ms) } return 0 == s_ticStart - ? FRACUNIT - : clamp( (now - s_ticStart) * FRACUNIT * TICRATE / 1000, 0, FRACUNIT); + ? 1. + : clamp( (now - s_ticStart) * TICRATE / 1000., 0, 1); } diff --git a/src/posix/i_system.h b/src/posix/i_system.h index 391503602..0515f2d85 100644 --- a/src/posix/i_system.h +++ b/src/posix/i_system.h @@ -62,7 +62,7 @@ extern int (*I_WaitForTic) (int); // tic will never arrive (unless it's the current one). extern void (*I_FreezeTime) (bool frozen); -fixed_t I_GetTimeFrac (uint32 *ms); +double I_GetTimeFrac (uint32 *ms); // Return a seed value for the RNG. unsigned int I_MakeRNGSeed(); diff --git a/src/posix/sdl/i_main.cpp b/src/posix/sdl/i_main.cpp index 7c08dacdb..54d2c2705 100644 --- a/src/posix/sdl/i_main.cpp +++ b/src/posix/sdl/i_main.cpp @@ -180,10 +180,10 @@ static int DoomSpecificInfo (char *buffer, char *end) } else { - p += snprintf (buffer+p, size-p, "\n\nviewx = %d", (int)viewx); - p += snprintf (buffer+p, size-p, "\nviewy = %d", (int)viewy); - p += snprintf (buffer+p, size-p, "\nviewz = %d", (int)viewz); - p += snprintf (buffer+p, size-p, "\nviewangle = %x", (unsigned int)viewangle); + p += snprintf (buffer+p, size-p, "\n\nviewx = %f", ViewPos.X); + p += snprintf (buffer+p, size-p, "\nviewy = %f", ViewPos.Y); + p += snprintf (buffer+p, size-p, "\nviewz = %f", ViewPos.Z); + p += snprintf (buffer+p, size-p, "\nviewangle = %f", ViewAngle.Degrees); } } buffer[p++] = '\n'; diff --git a/src/posix/sdl/i_timer.cpp b/src/posix/sdl/i_timer.cpp index 6255c8a96..cad3000ba 100644 --- a/src/posix/sdl/i_timer.cpp +++ b/src/posix/sdl/i_timer.cpp @@ -178,18 +178,17 @@ void I_SelectTimer() } // Returns the fractional amount of a tic passed since the most recent tic -fixed_t I_GetTimeFrac (uint32 *ms) +double I_GetTimeFrac (uint32 *ms) { DWORD now = SDL_GetTicks (); if (ms) *ms = TicStart + (1000 / TICRATE); if (TicStart == 0) { - return FRACUNIT; + return 1; } else { - fixed_t frac = clamp ((now - TicStart)*FRACUNIT*TICRATE/1000, 0, FRACUNIT); - return frac; + return clamp((now - TicStart) * TICRATE / 1000., 0, 1); } } diff --git a/src/r_3dfloors.cpp b/src/r_3dfloors.cpp index fbdc34edc..590d65515 100644 --- a/src/r_3dfloors.cpp +++ b/src/r_3dfloors.cpp @@ -52,12 +52,12 @@ void R_3D_AddHeight(secplane_t *add, sector_t *sec) { HeightLevel *near; HeightLevel *curr; - fixed_t height; - height = add->ZatPoint(viewx, viewy); - if(height >= sec->CenterCeiling()) return; - if(height <= sec->CenterFloor()) return; + double fheight = add->ZatPoint(ViewPos); + if(fheight >= sec->CenterCeiling()) return; + if(fheight <= sec->CenterFloor()) return; + fixed_t height = FLOAT2FIXED(fheight); fakeActive = 1; if(height_max >= 0) { diff --git a/src/r_3dfloors.h b/src/r_3dfloors.h index 1a16e36a5..e95d35045 100644 --- a/src/r_3dfloors.h +++ b/src/r_3dfloors.h @@ -49,7 +49,6 @@ enum extern int fake3D; extern F3DFloor *fakeFloor; -extern fixed_t fakeHeight; extern fixed_t fakeAlpha; extern int fakeActive; extern fixed_t sclipBottom; diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 97ac7e5e3..4f664d1bc 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -38,6 +38,7 @@ #include "p_lnspec.h" #include "p_setup.h" +#include "r_local.h" #include "r_main.h" #include "r_plane.h" #include "r_draw.h" @@ -394,8 +395,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, } } - fixed_t refceilz = s->ceilingplane.ZatPoint (viewx, viewy); - fixed_t orgceilz = sec->ceilingplane.ZatPoint (viewx, viewy); + fixed_t refceilz = s->ceilingplane.ZatPointFixed (viewx, viewy); + fixed_t orgceilz = sec->ceilingplane.ZatPointFixed(viewx, viewy); #if 1 // [RH] Allow viewing underwater areas through doors/windows that @@ -404,8 +405,8 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, // sectors at the same time. if (back && !r_fakingunderwater && curline->frontsector->heightsec == NULL) { - if (rw_frontcz1 <= s->floorplane.ZatPoint (curline->v1->x, curline->v1->y) && - rw_frontcz2 <= s->floorplane.ZatPoint (curline->v2->x, curline->v2->y)) + if (rw_frontcz1 <= s->floorplane.ZatPointFixed (curline->v1) && + rw_frontcz2 <= s->floorplane.ZatPointFixed(curline->v2)) { // Check that the window is actually visible for (int z = WallC.sx1; z < WallC.sx2; ++z) @@ -426,7 +427,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, tempsec->floorplane = sec->floorplane; tempsec->ceilingplane = s->floorplane; tempsec->ceilingplane.FlipVert (); - tempsec->ceilingplane.ChangeHeight (-1); + tempsec->ceilingplane.ChangeHeight(-1 / 65536.); tempsec->ColorMap = s->ColorMap; } @@ -438,12 +439,12 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, tempsec->ceilingplane = s->floorplane; tempsec->ceilingplane.FlipVert (); - tempsec->ceilingplane.ChangeHeight (-1); + tempsec->ceilingplane.ChangeHeight (-1 / 65536.); if (s->GetTexture(sector_t::ceiling) == skyflatnum) { tempsec->floorplane = tempsec->ceilingplane; tempsec->floorplane.FlipVert (); - tempsec->floorplane.ChangeHeight (+1); + tempsec->floorplane.ChangeHeight (+1 / 65536.); tempsec->SetTexture(sector_t::ceiling, tempsec->GetTexture(sector_t::floor), false); tempsec->planes[sector_t::ceiling].xform = tempsec->planes[sector_t::floor].xform; } @@ -475,7 +476,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, tempsec->ceilingplane = s->ceilingplane; tempsec->floorplane = s->ceilingplane; tempsec->floorplane.FlipVert (); - tempsec->floorplane.ChangeHeight (+1); + tempsec->floorplane.ChangeHeight (+1 / 65536.); tempsec->ColorMap = s->ColorMap; tempsec->ColorMap = s->ColorMap; @@ -529,10 +530,10 @@ void R_AddLine (seg_t *line) // [RH] Color if not texturing line dc_color = (((int)(line - segs) * 8) + 4) & 255; - tx1 = line->v1->x - viewx; - tx2 = line->v2->x - viewx; - ty1 = line->v1->y - viewy; - ty2 = line->v2->y - viewy; + tx1 = line->v1->fixX() - viewx; + tx2 = line->v2->fixX() - viewx; + ty1 = line->v1->fixY() - viewy; + ty2 = line->v2->fixY() - viewy; // Reject lines not facing viewer if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) @@ -555,7 +556,7 @@ void R_AddLine (seg_t *line) // reject lines that aren't seen from the portal (if any) // [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes. - if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, viewx, viewy)) + if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, ViewPos)) return; vertex_t *v1, *v2; @@ -573,17 +574,17 @@ void R_AddLine (seg_t *line) { swapvalues (v1, v2); } - WallT.InitFromLine(v1->x - viewx, v1->y - viewy, v2->x - viewx, v2->y - viewy); + WallT.InitFromLine(v1->fixX() - viewx, v1->fixY() - viewy, v2->fixX() - viewx, v2->fixY() - viewy); } if (!(fake3D & FAKE3D_FAKEBACK)) { backsector = line->backsector; } - rw_frontcz1 = frontsector->ceilingplane.ZatPoint (line->v1->x, line->v1->y); - rw_frontfz1 = frontsector->floorplane.ZatPoint (line->v1->x, line->v1->y); - rw_frontcz2 = frontsector->ceilingplane.ZatPoint (line->v2->x, line->v2->y); - rw_frontfz2 = frontsector->floorplane.ZatPoint (line->v2->x, line->v2->y); + rw_frontcz1 = frontsector->ceilingplane.ZatPointFixed(line->v1); + rw_frontfz1 = frontsector->floorplane.ZatPointFixed(line->v1); + rw_frontcz2 = frontsector->ceilingplane.ZatPointFixed(line->v2); + rw_frontfz2 = frontsector->floorplane.ZatPointFixed(line->v2); rw_mustmarkfloor = rw_mustmarkceiling = false; rw_havehigh = rw_havelow = false; @@ -602,10 +603,10 @@ void R_AddLine (seg_t *line) } doorclosed = 0; // killough 4/16/98 - rw_backcz1 = backsector->ceilingplane.ZatPoint (line->v1->x, line->v1->y); - rw_backfz1 = backsector->floorplane.ZatPoint (line->v1->x, line->v1->y); - rw_backcz2 = backsector->ceilingplane.ZatPoint (line->v2->x, line->v2->y); - rw_backfz2 = backsector->floorplane.ZatPoint (line->v2->x, line->v2->y); + rw_backcz1 = backsector->ceilingplane.ZatPointFixed (line->v1); + rw_backfz1 = backsector->floorplane.ZatPointFixed(line->v1); + rw_backcz2 = backsector->ceilingplane.ZatPointFixed(line->v2); + rw_backfz2 = backsector->floorplane.ZatPointFixed(line->v2); // Cannot make these walls solid, because it can result in // sprite clipping problems for sprites near the wall @@ -1168,7 +1169,7 @@ void R_Subsector (subsector_t *sub) fakeFloor = frontsector->e->XFloor.ffloors[i]; if (!(fakeFloor->flags & FF_EXISTS)) continue; if (!fakeFloor->model) continue; - if (fakeFloor->bottom.plane->a || fakeFloor->bottom.plane->b) continue; + if (fakeFloor->bottom.plane->isSlope()) continue; if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES|FF_RENDERSIDES))) { R_3D_AddHeight(fakeFloor->top.plane, frontsector); @@ -1176,14 +1177,14 @@ void R_Subsector (subsector_t *sub) if (!(fakeFloor->flags & FF_RENDERPLANES)) continue; if (fakeFloor->alpha == 0) continue; if (fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR) continue; - fakeAlpha = MIN(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE); + fakeAlpha = MIN(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE); if (fakeFloor->validcount != validcount) { fakeFloor->validcount = validcount; R_3D_NewClip(); } - fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot); - if (fakeHeight < viewz && + double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot); + if (fakeHeight < ViewPos.Z && fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot)) { fake3D = FAKE3D_FAKEFLOOR; @@ -1229,7 +1230,7 @@ void R_Subsector (subsector_t *sub) fakeFloor = frontsector->e->XFloor.ffloors[i]; if (!(fakeFloor->flags & FF_EXISTS)) continue; if (!fakeFloor->model) continue; - if (fakeFloor->top.plane->a || fakeFloor->top.plane->b) continue; + if (fakeFloor->top.plane->isSlope()) continue; if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES|FF_RENDERSIDES))) { R_3D_AddHeight(fakeFloor->bottom.plane, frontsector); @@ -1237,15 +1238,15 @@ void R_Subsector (subsector_t *sub) if (!(fakeFloor->flags & FF_RENDERPLANES)) continue; if (fakeFloor->alpha == 0) continue; if (!(fakeFloor->flags & FF_THISINSIDE) && (fakeFloor->flags & (FF_SWIMMABLE|FF_INVERTSECTOR)) == (FF_SWIMMABLE|FF_INVERTSECTOR)) continue; - fakeAlpha = MIN(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE); + fakeAlpha = MIN(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE); if (fakeFloor->validcount != validcount) { fakeFloor->validcount = validcount; R_3D_NewClip(); } - fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot); - if (fakeHeight > viewz && + double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot); + if (fakeHeight > ViewPos.Z && fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot)) { fake3D = FAKE3D_FAKECEILING; @@ -1260,14 +1261,14 @@ void R_Subsector (subsector_t *sub) } else position = sector_t::ceiling; frontsector = &tempsec; - tempsec.ceilingplane.ChangeHeight(-1); + tempsec.ceilingplane.ChangeHeight(-1 / 65536.); if (fixedlightlev < 0 && sub->sector->e->XFloor.lightlist.Size()) { light = P_GetPlaneLight(sub->sector, &frontsector->ceilingplane, false); basecolormap = light->extra_colormap; ceilinglightlevel = *light->p_lightlevel; } - tempsec.ceilingplane.ChangeHeight(1); + tempsec.ceilingplane.ChangeHeight(1 / 65536.); floorplane = NULL; ceilingplane = R_FindPlane(frontsector->ceilingplane, // killough 3/8/98 diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 565fb2498..a159e22bc 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -52,8 +52,8 @@ class DSectorPlaneInterpolation : public DInterpolation DECLARE_CLASS(DSectorPlaneInterpolation, DInterpolation) sector_t *sector; - fixed_t oldheight, oldtexz; - fixed_t bakheight, baktexz; + double oldheight, oldtexz; + double bakheight, baktexz; bool ceiling; TArray attached; @@ -65,7 +65,7 @@ public: void Destroy(); void UpdateInterpolation(); void Restore(); - void Interpolate(fixed_t smoothratio); + void Interpolate(double smoothratio); void Serialize(FArchive &arc); size_t PointerSubstitution (DObject *old, DObject *notOld); size_t PropagateMark(); @@ -82,8 +82,8 @@ class DSectorScrollInterpolation : public DInterpolation DECLARE_CLASS(DSectorScrollInterpolation, DInterpolation) sector_t *sector; - fixed_t oldx, oldy; - fixed_t bakx, baky; + double oldx, oldy; + double bakx, baky; bool ceiling; public: @@ -93,7 +93,7 @@ public: void Destroy(); void UpdateInterpolation(); void Restore(); - void Interpolate(fixed_t smoothratio); + void Interpolate(double smoothratio); void Serialize(FArchive &arc); }; @@ -110,8 +110,8 @@ class DWallScrollInterpolation : public DInterpolation side_t *side; int part; - fixed_t oldx, oldy; - fixed_t bakx, baky; + double oldx, oldy; + double bakx, baky; public: @@ -120,7 +120,7 @@ public: void Destroy(); void UpdateInterpolation(); void Restore(); - void Interpolate(fixed_t smoothratio); + void Interpolate(double smoothratio); void Serialize(FArchive &arc); }; @@ -135,9 +135,9 @@ class DPolyobjInterpolation : public DInterpolation DECLARE_CLASS(DPolyobjInterpolation, DInterpolation) FPolyObj *poly; - TArray oldverts, bakverts; - fixed_t oldcx, oldcy; - fixed_t bakcx, bakcy; + TArray oldverts, bakverts; + double oldcx, oldcy; + double bakcx, bakcy; public: @@ -146,7 +146,7 @@ public: void Destroy(); void UpdateInterpolation(); void Restore(); - void Interpolate(fixed_t smoothratio); + void Interpolate(double smoothratio); void Serialize(FArchive &arc); }; @@ -251,9 +251,9 @@ void FInterpolator::RemoveInterpolation(DInterpolation *interp) // //========================================================================== -void FInterpolator::DoInterpolations(fixed_t smoothratio) +void FInterpolator::DoInterpolations(double smoothratio) { - if (smoothratio == FRACUNIT) + if (smoothratio >= 1.) { didInterp = false; return; @@ -440,13 +440,13 @@ void DSectorPlaneInterpolation::UpdateInterpolation() { if (!ceiling) { - oldheight = sector->floorplane.d; - oldtexz = sector->GetPlaneTexZ(sector_t::floor); + oldheight = sector->floorplane.fD(); + oldtexz = sector->GetPlaneTexZF(sector_t::floor); } else { - oldheight = sector->ceilingplane.d; - oldtexz = sector->GetPlaneTexZ(sector_t::ceiling); + oldheight = sector->ceilingplane.fD(); + oldtexz = sector->GetPlaneTexZF(sector_t::ceiling); } } @@ -460,12 +460,12 @@ void DSectorPlaneInterpolation::Restore() { if (!ceiling) { - sector->floorplane.d = bakheight; + sector->floorplane.setD(bakheight); sector->SetPlaneTexZ(sector_t::floor, baktexz); } else { - sector->ceilingplane.d = bakheight; + sector->ceilingplane.setD(bakheight); sector->SetPlaneTexZ(sector_t::ceiling, baktexz); } P_RecalculateAttached3DFloors(sector); @@ -478,24 +478,24 @@ void DSectorPlaneInterpolation::Restore() // //========================================================================== -void DSectorPlaneInterpolation::Interpolate(fixed_t smoothratio) +void DSectorPlaneInterpolation::Interpolate(double smoothratio) { - fixed_t *pheight; + secplane_t *pplane; int pos; if (!ceiling) { - pheight = §or->floorplane.d; + pplane = §or->floorplane; pos = sector_t::floor; } else { - pheight = §or->ceilingplane.d; + pplane = §or->ceilingplane; pos = sector_t::ceiling; } - bakheight = *pheight; - baktexz = sector->GetPlaneTexZ(pos); + bakheight = pplane->fD(); + baktexz = sector->GetPlaneTexZF(pos); if (refcount == 0 && oldheight == bakheight) { @@ -503,8 +503,8 @@ void DSectorPlaneInterpolation::Interpolate(fixed_t smoothratio) } else { - *pheight = oldheight + FixedMul(bakheight - oldheight, smoothratio); - sector->SetPlaneTexZ(pos, oldtexz + FixedMul(baktexz - oldtexz, smoothratio)); + pplane->setD(oldheight + (bakheight - oldheight) * smoothratio); + sector->SetPlaneTexZ(pos, oldtexz + (baktexz - oldtexz) * smoothratio); P_RecalculateAttached3DFloors(sector); sector->CheckPortalPlane(pos); } @@ -604,8 +604,8 @@ void DSectorScrollInterpolation::Destroy() void DSectorScrollInterpolation::UpdateInterpolation() { - oldx = sector->GetXOffset(ceiling); - oldy = sector->GetYOffset(ceiling, false); + oldx = sector->GetXOffsetF(ceiling); + oldy = sector->GetYOffsetF(ceiling, false); } //========================================================================== @@ -626,10 +626,10 @@ void DSectorScrollInterpolation::Restore() // //========================================================================== -void DSectorScrollInterpolation::Interpolate(fixed_t smoothratio) +void DSectorScrollInterpolation::Interpolate(double smoothratio) { - bakx = sector->GetXOffset(ceiling); - baky = sector->GetYOffset(ceiling, false); + bakx = sector->GetXOffsetF(ceiling); + baky = sector->GetYOffsetF(ceiling, false); if (refcount == 0 && oldx == bakx && oldy == baky) { @@ -637,8 +637,8 @@ void DSectorScrollInterpolation::Interpolate(fixed_t smoothratio) } else { - sector->SetXOffset(ceiling, oldx + FixedMul(bakx - oldx, smoothratio)); - sector->SetYOffset(ceiling, oldy + FixedMul(baky - oldy, smoothratio)); + sector->SetXOffset(ceiling, oldx + (bakx - oldx) * smoothratio); + sector->SetYOffset(ceiling, oldy + (baky - oldy) * smoothratio); } } @@ -695,8 +695,8 @@ void DWallScrollInterpolation::Destroy() void DWallScrollInterpolation::UpdateInterpolation() { - oldx = side->GetTextureXOffset(part); - oldy = side->GetTextureYOffset(part); + oldx = side->GetTextureXOffsetF(part); + oldy = side->GetTextureYOffsetF(part); } //========================================================================== @@ -717,10 +717,10 @@ void DWallScrollInterpolation::Restore() // //========================================================================== -void DWallScrollInterpolation::Interpolate(fixed_t smoothratio) +void DWallScrollInterpolation::Interpolate(double smoothratio) { - bakx = side->GetTextureXOffset(part); - baky = side->GetTextureYOffset(part); + bakx = side->GetTextureXOffsetF(part); + baky = side->GetTextureYOffsetF(part); if (refcount == 0 && oldx == bakx && oldy == baky) { @@ -728,8 +728,8 @@ void DWallScrollInterpolation::Interpolate(fixed_t smoothratio) } else { - side->SetTextureXOffset(part, oldx + FixedMul(bakx - oldx, smoothratio)); - side->SetTextureYOffset(part, oldy + FixedMul(baky - oldy, smoothratio)); + side->SetTextureXOffset(part, oldx + (bakx - oldx) * smoothratio); + side->SetTextureYOffset(part, oldy + (baky - oldy) * smoothratio); } } @@ -788,11 +788,11 @@ void DPolyobjInterpolation::UpdateInterpolation() { for(unsigned int i = 0; i < poly->Vertices.Size(); i++) { - oldverts[i*2 ] = poly->Vertices[i]->x; - oldverts[i*2+1] = poly->Vertices[i]->y; + oldverts[i*2 ] = poly->Vertices[i]->fX(); + oldverts[i*2+1] = poly->Vertices[i]->fY(); } - oldcx = poly->CenterSpot.x; - oldcy = poly->CenterSpot.y; + oldcx = poly->CenterSpot.pos.X; + oldcy = poly->CenterSpot.pos.Y; } //========================================================================== @@ -805,11 +805,10 @@ void DPolyobjInterpolation::Restore() { for(unsigned int i = 0; i < poly->Vertices.Size(); i++) { - poly->Vertices[i]->x = bakverts[i*2 ]; - poly->Vertices[i]->y = bakverts[i*2+1]; + poly->Vertices[i]->set(bakverts[i*2 ], bakverts[i*2+1]); } - poly->CenterSpot.x = bakcx; - poly->CenterSpot.y = bakcy; + poly->CenterSpot.pos.X = bakcx; + poly->CenterSpot.pos.Y = bakcy; poly->ClearSubsectorLinks(); } @@ -819,22 +818,20 @@ void DPolyobjInterpolation::Restore() // //========================================================================== -void DPolyobjInterpolation::Interpolate(fixed_t smoothratio) +void DPolyobjInterpolation::Interpolate(double smoothratio) { bool changed = false; for(unsigned int i = 0; i < poly->Vertices.Size(); i++) { - fixed_t *px = &poly->Vertices[i]->x; - fixed_t *py = &poly->Vertices[i]->y; - - bakverts[i*2 ] = *px; - bakverts[i*2+1] = *py; + bakverts[i*2 ] = poly->Vertices[i]->fX(); + bakverts[i*2+1] = poly->Vertices[i]->fY(); if (bakverts[i * 2] != oldverts[i * 2] || bakverts[i * 2 + 1] != oldverts[i * 2 + 1]) { changed = true; - *px = oldverts[i * 2] + FixedMul(bakverts[i * 2] - oldverts[i * 2], smoothratio); - *py = oldverts[i * 2 + 1] + FixedMul(bakverts[i * 2 + 1] - oldverts[i * 2 + 1], smoothratio); + poly->Vertices[i]->set( + oldverts[i * 2] + (bakverts[i * 2] - oldverts[i * 2]) * smoothratio, + oldverts[i * 2 + 1] + (bakverts[i * 2 + 1] - oldverts[i * 2 + 1]) * smoothratio); } } if (refcount == 0 && !changed) @@ -843,10 +840,10 @@ void DPolyobjInterpolation::Interpolate(fixed_t smoothratio) } else { - bakcx = poly->CenterSpot.x; - bakcy = poly->CenterSpot.y; - poly->CenterSpot.x = bakcx + FixedMul(bakcx - oldcx, smoothratio); - poly->CenterSpot.y = bakcy + FixedMul(bakcy - oldcy, smoothratio); + bakcx = poly->CenterSpot.pos.X; + bakcy = poly->CenterSpot.pos.Y; + poly->CenterSpot.pos.X = bakcx + (bakcx - oldcx) * smoothratio; + poly->CenterSpot.pos.Y = bakcy + (bakcy - oldcy) * smoothratio; poly->ClearSubsectorLinks(); } diff --git a/src/r_data/r_interpolate.h b/src/r_data/r_interpolate.h index 4da89451c..e49500e57 100644 --- a/src/r_data/r_interpolate.h +++ b/src/r_data/r_interpolate.h @@ -30,7 +30,7 @@ public: virtual void Destroy(); virtual void UpdateInterpolation() = 0; virtual void Restore() = 0; - virtual void Interpolate(fixed_t smoothratio) = 0; + virtual void Interpolate(double smoothratio) = 0; virtual void Serialize(FArchive &arc); }; @@ -58,7 +58,7 @@ public: void UpdateInterpolations(); void AddInterpolation(DInterpolation *); void RemoveInterpolation(DInterpolation *); - void DoInterpolations(fixed_t smoothratio); + void DoInterpolations(double smoothratio); void RestoreInterpolations(); void ClearInterpolations(); }; diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index 3cea74cf2..37a3fb854 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -310,7 +310,7 @@ FNativePalette *FRemapTable::GetNative() void FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2) { - fixed_t palcol, palstep; + double palcol, palstep; if (start > end) { @@ -326,11 +326,11 @@ void FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2) Palette[start].a = start == 0 ? 0 : 255; return; } - palcol = pal1 << FRACBITS; - palstep = ((pal2 << FRACBITS) - palcol) / (end - start); + palcol = pal1; + palstep = (pal2 - palcol) / (end - start); for (int i = start; i <= end; palcol += palstep, ++i) { - int j = GPalette.Remap[i], k = GPalette.Remap[palcol >> FRACBITS]; + int j = GPalette.Remap[i], k = GPalette.Remap[int(palcol)]; Remap[j] = k; Palette[j] = GPalette.BaseColors[k]; Palette[j].a = j == 0 ? 0 : 255; @@ -345,14 +345,14 @@ void FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2) void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, int _r2, int _g2, int _b2) { - fixed_t r1 = _r1 << FRACBITS; - fixed_t g1 = _g1 << FRACBITS; - fixed_t b1 = _b1 << FRACBITS; - fixed_t r2 = _r2 << FRACBITS; - fixed_t g2 = _g2 << FRACBITS; - fixed_t b2 = _b2 << FRACBITS; - fixed_t r, g, b; - fixed_t rs, gs, bs; + double r1 = _r1; + double g1 = _g1; + double b1 = _b1; + double r2 = _r2; + double g2 = _g2; + double b2 = _b2; + double r, g, b; + double rs, gs, bs; if (start > end) { @@ -376,9 +376,8 @@ void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, in if (start == end) { start = GPalette.Remap[start]; - Remap[start] = ColorMatcher.Pick(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS); - Palette[start] = PalEntry(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS); - Palette[start].a = start == 0 ? 0 : 255; + Palette[start] = PalEntry(start == 0 ? 0 : 255, int(r), int(g), int(b)); + Remap[start] = ColorMatcher.Pick(Palette[start]); } else { @@ -388,8 +387,8 @@ void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, in for (int i = start; i <= end; ++i) { int j = GPalette.Remap[i]; - Remap[j] = ColorMatcher.Pick(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS); - Palette[j] = PalEntry(j == 0 ? 0 : 255, r >> FRACBITS, g >> FRACBITS, b >> FRACBITS); + Palette[j] = PalEntry(j == 0 ? 0 : 255, int(r), int(g), int(b)); + Remap[j] = ColorMatcher.Pick(Palette[j]); r += rs; g += gs; b += bs; diff --git a/src/r_data/renderstyle.cpp b/src/r_data/renderstyle.cpp index 6372a7afd..fdd20aa17 100644 --- a/src/r_data/renderstyle.cpp +++ b/src/r_data/renderstyle.cpp @@ -105,6 +105,18 @@ FArchive &operator<< (FArchive &arc, FRenderStyle &style) return arc; } +double GetAlpha(int type, double alpha) +{ + switch (type) + { + case STYLEALPHA_Zero: return 0; + case STYLEALPHA_One: return OPAQUE; + case STYLEALPHA_Src: return alpha; + case STYLEALPHA_InvSrc: return 1. - alpha; + default: return 0; + } +} + //========================================================================== // // FRenderStyle :: IsVisible @@ -114,7 +126,7 @@ FArchive &operator<< (FArchive &arc, FRenderStyle &style) // //========================================================================== -bool FRenderStyle::IsVisible(fixed_t alpha) const throw() +bool FRenderStyle::IsVisible(double alpha) const throw() { if (BlendOp == STYLEOP_None) { @@ -124,13 +136,13 @@ bool FRenderStyle::IsVisible(fixed_t alpha) const throw() { if (Flags & STYLEF_Alpha1) { - alpha = FRACUNIT; + alpha = 1.; } else { - alpha = clamp(alpha, 0, FRACUNIT); + alpha = clamp(alpha, 0., 1.); } - return GetAlpha(SrcAlpha, alpha) != 0 || GetAlpha(DestAlpha, alpha) != FRACUNIT; + return GetAlpha(SrcAlpha, alpha) != 0 || GetAlpha(DestAlpha, alpha) != 1; } // Treat anything else as visible. return true; @@ -186,16 +198,3 @@ void FRenderStyle::CheckFuzz() BlendOp = STYLEOP_Fuzz; } } - -fixed_t GetAlpha(int type, fixed_t alpha) -{ - switch (type) - { - case STYLEALPHA_Zero: return 0; - case STYLEALPHA_One: return FRACUNIT; - case STYLEALPHA_Src: return alpha; - case STYLEALPHA_InvSrc: return FRACUNIT - alpha; - default: return 0; - } -} - diff --git a/src/r_data/renderstyle.h b/src/r_data/renderstyle.h index 613505821..c103610ef 100644 --- a/src/r_data/renderstyle.h +++ b/src/r_data/renderstyle.h @@ -35,6 +35,20 @@ ** */ +// also #defines OPAQUE +#ifdef OPAQUE +#undef OPAQUE +#endif + +enum +{ + OPAQUE = 65536, + TRANSLUC25 = (OPAQUE / 4), + TRANSLUC33 = (OPAQUE / 3), + TRANSLUC66 = ((OPAQUE * 2) / 3), + TRANSLUC75 = ((OPAQUE * 3) / 4), +}; + // Legacy render styles enum ERenderStyle { @@ -127,7 +141,7 @@ union FRenderStyle operator uint32() const { return AsDWORD; } bool operator==(const FRenderStyle &o) const { return AsDWORD == o.AsDWORD; } void CheckFuzz(); - bool IsVisible(fixed_t alpha) const throw(); + bool IsVisible(double alpha) const throw(); private: // Code that compares an actor's render style with a legacy render // style value should be updated. Making these conversion operators @@ -151,6 +165,5 @@ inline FRenderStyle &FRenderStyle::operator= (ERenderStyle legacy) class FArchive; FArchive &operator<< (FArchive &arc, FRenderStyle &style); -fixed_t GetAlpha(int type, fixed_t alpha); #endif diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 903bdd404..62bb4ba1c 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -594,8 +594,8 @@ void R_InitSkins (void) } else if (0 == stricmp (key, "scale")) { - skins[i].ScaleX = clamp (FLOAT2FIXED(atof (sc.String)), 1, 256*FRACUNIT); - skins[i].ScaleY = skins[i].ScaleX; + skins[i].Scale.X = clamp(atof (sc.String), 1./65536, 256.); + skins[i].Scale.Y = skins[i].Scale.X; } else if (0 == stricmp (key, "game")) { @@ -935,8 +935,7 @@ void R_InitSprites () PClassPlayerPawn *type = PlayerClasses[0].Type; skins[i].range0start = type->ColorRangeStart; skins[i].range0end = type->ColorRangeEnd; - skins[i].ScaleX = GetDefaultByType (type)->scaleX; - skins[i].ScaleY = GetDefaultByType (type)->scaleY; + skins[i].Scale = GetDefaultByType (type)->Scale; } R_InitSpriteDefs (); @@ -965,8 +964,7 @@ void R_InitSprites () } skins[i].range0start = basetype->ColorRangeStart; skins[i].range0end = basetype->ColorRangeEnd; - skins[i].ScaleX = GetDefaultByType (basetype)->scaleX; - skins[i].ScaleY = GetDefaultByType (basetype)->scaleY; + skins[i].Scale = GetDefaultByType (basetype)->Scale; skins[i].sprite = GetDefaultByType (basetype)->SpawnState->sprite; skins[i].namespc = ns_global; diff --git a/src/r_data/sprites.h b/src/r_data/sprites.h index 28feb433e..d882ee981 100644 --- a/src/r_data/sprites.h +++ b/src/r_data/sprites.h @@ -1,6 +1,8 @@ #ifndef __RES_SPRITES_H #define __RES_SPRITES_H +#include "vectors.h" + #define MAX_SPRITE_FRAMES 29 // [RH] Macro-ized as in BOOM. // @@ -51,8 +53,7 @@ public: BYTE range0start; BYTE range0end; bool othergame; // [GRB] - fixed_t ScaleX; - fixed_t ScaleY; + DVector2 Scale; int sprite; int crouchsprite; int namespc; // namespace for this skin diff --git a/src/r_data/voxels.cpp b/src/r_data/voxels.cpp index 48a5744ba..8ca6d4f5f 100644 --- a/src/r_data/voxels.cpp +++ b/src/r_data/voxels.cpp @@ -71,13 +71,13 @@ TDeletingArray VoxelDefs; struct VoxelOptions { VoxelOptions() - : DroppedSpin(0), PlacedSpin(0), Scale(FRACUNIT), AngleOffset(ANGLE_90), OverridePalette(false) + : DroppedSpin(0), PlacedSpin(0), Scale(1.), AngleOffset(90.), OverridePalette(false) {} int DroppedSpin; int PlacedSpin; - fixed_t Scale; - angle_t AngleOffset; + double Scale; + DAngle AngleOffset; bool OverridePalette; }; @@ -213,9 +213,9 @@ FVoxel *R_LoadKVX(int lumpnum) mipl->SizeX = GetInt(rawmip + 0); mipl->SizeY = GetInt(rawmip + 4); mipl->SizeZ = GetInt(rawmip + 8); - mipl->PivotX = GetInt(rawmip + 12); - mipl->PivotY = GetInt(rawmip + 16); - mipl->PivotZ = GetInt(rawmip + 20); + mipl->Pivot.X = GetInt(rawmip + 12) / 256.; + mipl->Pivot.Y = GetInt(rawmip + 16) / 256.; + mipl->Pivot.Z = GetInt(rawmip + 20) / 256.; // How much space do we have for voxdata? int offsetsize = (mipl->SizeX + 1) * 4 + mipl->SizeX * (mipl->SizeY + 1) * 2; @@ -300,9 +300,7 @@ FVoxel *R_LoadKVX(int lumpnum) // Fix pivot data for submips, since some tools seem to like to just center these. for (i = 1; i < mip; ++i) { - voxel->Mips[i].PivotX = voxel->Mips[0].PivotX >> i; - voxel->Mips[i].PivotY = voxel->Mips[0].PivotY >> i; - voxel->Mips[i].PivotZ = voxel->Mips[0].PivotZ >> i; + voxel->Mips[i].Pivot = voxel->Mips[i - 1].Pivot / 2; } for (i = 0; i < mip; ++i) @@ -339,9 +337,9 @@ FVoxelDef *R_LoadVoxelDef(int lumpnum, int spin) { FVoxelDef *voxdef = new FVoxelDef; voxdef->Voxel = vox; - voxdef->Scale = FRACUNIT; + voxdef->Scale = 1.; voxdef->DroppedSpin = voxdef->PlacedSpin = spin; - voxdef->AngleOffset = ANGLE_90; + voxdef->AngleOffset = 90.; Voxels.Push(vox); VoxelDefs.Push(voxdef); @@ -358,7 +356,7 @@ FVoxelDef *R_LoadVoxelDef(int lumpnum, int spin) FVoxelMipLevel::FVoxelMipLevel() { SizeZ = SizeY = SizeX = 0; - PivotZ = PivotY = PivotX = 0; + Pivot.Zero(); OffsetX = NULL; OffsetXY = NULL; SlabData = NULL; @@ -499,7 +497,7 @@ static void VOX_ReadOptions(FScanner &sc, VoxelOptions &opts) { sc.MustGetToken('='); sc.MustGetToken(TK_FloatConst); - opts.Scale = FLOAT2FIXED(sc.Float); + opts.Scale = sc.Float; } else if (sc.Compare("spin")) { @@ -531,7 +529,7 @@ static void VOX_ReadOptions(FScanner &sc, VoxelOptions &opts) { sc.TokenMustBe(TK_FloatConst); } - opts.AngleOffset = ANGLE_90 + FLOAT2ANGLE(sc.Float); + opts.AngleOffset = sc.Float + 90.; } else if (sc.Compare("overridepalette")) { diff --git a/src/r_data/voxels.h b/src/r_data/voxels.h index 221cddb2f..85095c52f 100644 --- a/src/r_data/voxels.h +++ b/src/r_data/voxels.h @@ -23,9 +23,7 @@ struct FVoxelMipLevel int SizeX; int SizeY; int SizeZ; - fixed_t PivotX; // 24.8 fixed point - fixed_t PivotY; // "" - fixed_t PivotZ; // "" + DVector3 Pivot; int *OffsetX; short *OffsetXY; BYTE *SlabData; @@ -51,8 +49,8 @@ struct FVoxelDef int PlacedSpin; // degrees/sec to spin actors without MF_DROPPED set int DroppedSpin; // degrees/sec to spin actors with MF_DROPPED set int VoxeldefIndex; // Needed by GZDoom - fixed_t Scale; - angle_t AngleOffset; // added to actor's angle to compensate for wrong-facing voxels + double Scale; + DAngle AngleOffset;// added to actor's angle to compensate for wrong-facing voxels }; extern TDeletingArray Voxels; // used only to auto-delete voxels on exit. diff --git a/src/r_defs.h b/src/r_defs.h index d04afbf88..2719ff7ee 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -26,6 +26,7 @@ #include "doomdef.h" #include "templates.h" #include "memarena.h" +#include "m_bbox.h" // Some more or less basic data types // we depend on. @@ -87,21 +88,74 @@ enum }; struct vertexdata_t { - fixed_t zCeiling, zFloor; + double zCeiling, zFloor; DWORD flags; }; + +#ifdef USE_FLOAT +typedef float vtype; +#elif !defined USE_FIXED +typedef double vtype; +#endif + + struct vertex_t { - fixed_t x, y; +private: + DVector2 p; + +public: + + void set(fixed_t x, fixed_t y) + { + p.X = x / 65536.; + p.Y = y / 65536.; + } + + void set(double x, double y) + { + p.X = x; + p.Y = y; + } + + double fX() const + { + return p.X; + } + + double fY() const + { + return p.Y; + } + + fixed_t fixX() const + { + return FLOAT2FIXED(p.X); + } + + fixed_t fixY() const + { + return FLOAT2FIXED(p.Y); + } + + DVector2 fPos() + { + return { p.X, p.Y }; + } bool operator== (const vertex_t &other) { - return x == other.x && y == other.y; + return p == other.p; + } + + bool operator!= (const vertex_t &other) + { + return p != other.p; } void clear() { - x = y = 0; + p.Zero(); } }; @@ -225,142 +279,182 @@ class ASkyViewpoint; struct secplane_t { + friend FArchive &operator<< (FArchive &arc, secplane_t &plane); // the plane is defined as a*x + b*y + c*z + d = 0 // ic is 1/c, for faster Z calculations - fixed_t a, b, c, d, ic; +private: + DVector3 normal; + double D, negiC; // negative iC because that also saves a negation in all methods using this. +public: + + void set(double aa, double bb, double cc, double dd) + { + normal.X = aa; + normal.Y = bb; + normal.Z = cc; + D = dd; + negiC = -1 / cc; + } + + void setD(double dd) + { + D = dd; + } + + double fC() const + { + return normal.Z; + } + double fD() const + { + return D; + } + + bool isSlope() const + { + return !normal.XY().isZero(); + } + + DVector3 Normal() const + { + return normal; + } // Returns < 0 : behind; == 0 : on; > 0 : in front int PointOnSide (fixed_t x, fixed_t y, fixed_t z) const { - return TMulScale16(a,x, b,y, c,z) + d; + return PointOnSide(DVector3(FIXED2DBL(x), FIXED2DBL(y), FIXED2DBL(z))); + } + + int PointOnSide(const DVector3 &pos) const + { + double v = (normal | pos) + D; + return v < -EQUAL_EPSILON ? -1 : v > EQUAL_EPSILON ? 1 : 0; } // Returns the value of z at (0,0) This is used by the 3D floor code which does not handle slopes fixed_t Zat0 () const { - 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)); + return FLOAT2FIXED(negiC*D); } // 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 = delete; // it is not allowed to call this. + + fixed_t ZatPointFixed(fixed_t x, fixed_t y) const { - return FixedMul (ic, -d - DMulScale16 (a, x, b, y)); + return FLOAT2FIXED(ZatPoint(FIXED2DBL(x), FIXED2DBL(y))); } + // This is for the software renderer + fixed_t ZatPointFixed(const DVector2 &pos) const + { + return FLOAT2FIXED(ZatPoint(pos)); + } + + fixed_t ZatPointFixed(const vertex_t *v) const + { + return FLOAT2FIXED(ZatPoint(v)); + } + + // Returns the value of z at (x,y) as a double double ZatPoint (double x, double y) const { - return (d + a*x + b*y) * ic / (-65536.0 * 65536.0); + return (D + normal.X*x + normal.Y*y) * negiC; } - // Returns the value of z at vertex v - fixed_t ZatPoint (const vertex_t *v) const + double ZatPoint(const DVector2 &pos) const { - return FixedMul (ic, -d - DMulScale16 (a, v->x, b, v->y)); + return (D + normal.X*pos.X + normal.Y*pos.Y) * negiC; } - fixed_t ZatPoint (const AActor *ac) const + + double ZatPoint(const vertex_t *v) const { - return FixedMul (ic, -d - DMulScale16 (a, ac->X(), b, ac->Y())); + return (D + normal.X*v->fX() + normal.Y*v->fY()) * negiC; } - // Returns the value of z at (x,y) if d is equal to dist - fixed_t ZatPointDist (fixed_t x, fixed_t y, fixed_t dist) const + double ZatPoint(const AActor *ac) const { - return FixedMul (ic, -dist - DMulScale16 (a, x, b, y)); + return (D + normal.X*ac->X() + normal.Y*ac->Y()) * negiC; } // Returns the value of z at vertex v if d is equal to dist - fixed_t ZatPointDist (const vertex_t *v, fixed_t dist) + double ZatPointDist(const vertex_t *v, double dist) { - return FixedMul (ic, -dist - DMulScale16 (a, v->x, b, v->y)); + return (dist + normal.X*v->fX() + normal.Y*v->fY()) * negiC; } - // Flips the plane's vertical orientiation, so that if it pointed up, // it will point down, and vice versa. void FlipVert () { - a = -a; - b = -b; - c = -c; - d = -d; - ic = -ic; + normal = -normal; + D = -D; + negiC = -negiC; } // Returns true if 2 planes are the same bool operator== (const secplane_t &other) const { - return a == other.a && b == other.b && c == other.c && d == other.d; + return normal == other.normal && D == other.D; } // Returns true if 2 planes are different bool operator!= (const secplane_t &other) const { - return a != other.a || b != other.b || c != other.c || d != other.d; + return normal != other.normal || D != other.D; } // Moves a plane up/down by hdiff units - void ChangeHeight (fixed_t hdiff) + void ChangeHeight(double hdiff) { - d = d - FixedMul (hdiff, c); + D = D - hdiff * normal.Z; } // Moves a plane up/down by hdiff units - fixed_t GetChangedHeight (fixed_t hdiff) + double GetChangedHeight(double hdiff) { - return d - FixedMul (hdiff, c); + return D - hdiff * normal.Z; } // Returns how much this plane's height would change if d were set to oldd - fixed_t HeightDiff (fixed_t oldd) const + double HeightDiff(double oldd) const { - return FixedMul (oldd - d, ic); + return (D - oldd) * negiC; } // Returns how much this plane's height would change if d were set to oldd - fixed_t HeightDiff (fixed_t oldd, fixed_t newd) const + double HeightDiff(double oldd, double newd) const { - return FixedMul (oldd - newd, ic); + return (newd - oldd) * negiC; } - fixed_t PointToDist (fixed_t x, fixed_t y, fixed_t z) const + double PointToDist(const DVector2 &xy, double z) const { - return -TMulScale16 (a, x, y, b, z, c); + return -(normal.X * xy.X + normal.Y * xy.Y + normal.Z * z); } - fixed_t PointToDist(fixedvec2 xy, fixed_t z) const + double PointToDist(const vertex_t *v, double z) const { - return -TMulScale16(a, xy.x, xy.y, b, z, c); + return -(normal.X * v->fX() + normal.Y * v->fY() + normal.Z * z); } - fixed_t PointToDist (const vertex_t *v, fixed_t z) const + void SetAtHeight(double height, int ceiling) { - return -TMulScale16 (a, v->x, b, v->y, z, c); - } - - void SetAtHeight(fixed_t height, int ceiling) - { - a = b = 0; + normal.X = normal.Y = 0; if (ceiling) { - c = ic = -FRACUNIT; - d = height; + normal.Z = -1; + negiC = 1; + D = height; } else { - c = ic = FRACUNIT; - d = -height; + normal.Z = 1; + negiC = -1; + D = -height; } } @@ -521,29 +615,31 @@ struct sector_t { // Member functions bool IsLinked(sector_t *other, bool ceiling) const; - fixed_t FindLowestFloorSurrounding (vertex_t **v) const; - fixed_t FindHighestFloorSurrounding (vertex_t **v) const; - fixed_t FindNextHighestFloor (vertex_t **v) const; - fixed_t FindNextLowestFloor (vertex_t **v) const; - fixed_t FindLowestCeilingSurrounding (vertex_t **v) const; // jff 2/04/98 - fixed_t FindHighestCeilingSurrounding (vertex_t **v) const; // jff 2/04/98 - fixed_t FindNextLowestCeiling (vertex_t **v) const; // jff 2/04/98 - fixed_t FindNextHighestCeiling (vertex_t **v) const; // jff 2/04/98 - fixed_t FindShortestTextureAround () const; // jff 2/04/98 - fixed_t FindShortestUpperAround () const; // jff 2/04/98 - sector_t *FindModelFloorSector (fixed_t floordestheight) const; // jff 2/04/98 - sector_t *FindModelCeilingSector (fixed_t floordestheight) const; // jff 2/04/98 + double FindLowestFloorSurrounding(vertex_t **v) const; + double FindHighestFloorSurrounding(vertex_t **v) const; + double FindNextHighestFloor(vertex_t **v) const; + double FindNextLowestFloor(vertex_t **v) const; + double FindLowestCeilingSurrounding(vertex_t **v) const; // jff 2/04/98 + double FindHighestCeilingSurrounding(vertex_t **v) const; // jff 2/04/98 + double FindNextLowestCeiling(vertex_t **v) const; // jff 2/04/98 + double FindNextHighestCeiling(vertex_t **v) const; // jff 2/04/98 + double FindShortestTextureAround() const; // jff 2/04/98 + double FindShortestUpperAround() const; // jff 2/04/98 + sector_t *FindModelFloorSector(double floordestheight) const; // jff 2/04/98 + sector_t *FindModelCeilingSector(double floordestheight) const; // jff 2/04/98 int FindMinSurroundingLight (int max) const; sector_t *NextSpecialSector (int type, sector_t *prev) const; // [RH] - fixed_t FindLowestCeilingPoint (vertex_t **v) const; - fixed_t FindHighestFloorPoint (vertex_t **v) const; + double FindLowestCeilingPoint(vertex_t **v) const; + double FindHighestFloorPoint(vertex_t **v) const; + void AdjustFloorClip () const; void SetColor(int r, int g, int b, int desat); void SetFade(int r, int g, int b); - void ClosestPoint(fixed_t x, fixed_t y, fixed_t &ox, fixed_t &oy) const; + void ClosestPoint(const DVector2 &pos, DVector2 &out) const; int GetFloorLight () const; int GetCeilingLight () const; sector_t *GetHeightSec() const; + double GetFriction(int plane = sector_t::floor, double *movefac = NULL) const; DInterpolation *SetInterpolation(int position, bool attach); @@ -569,14 +665,14 @@ struct sector_t splane planes[2]; - void SetXOffset(int pos, fixed_t o) + void SetXOffset(int pos, double o) { - planes[pos].xform.xoffs = o; + planes[pos].xform.xoffs = FLOAT2FIXED(o); } - void AddXOffset(int pos, fixed_t o) + void AddXOffset(int pos, double o) { - planes[pos].xform.xoffs += o; + planes[pos].xform.xoffs += FLOAT2FIXED(o); } fixed_t GetXOffset(int pos) const @@ -584,14 +680,19 @@ struct sector_t return planes[pos].xform.xoffs; } - void SetYOffset(int pos, fixed_t o) + double GetXOffsetF(int pos) const { - planes[pos].xform.yoffs = o; + return FIXED2DBL(planes[pos].xform.xoffs); } - void AddYOffset(int pos, fixed_t o) + void SetYOffset(int pos, double o) { - planes[pos].xform.yoffs += o; + planes[pos].xform.yoffs = FLOAT2FIXED(o); + } + + void AddYOffset(int pos, double o) + { + planes[pos].xform.yoffs += FLOAT2FIXED(o); } fixed_t GetYOffset(int pos, bool addbase = true) const @@ -606,9 +707,21 @@ struct sector_t } } - void SetXScale(int pos, fixed_t o) + double GetYOffsetF(int pos, bool addbase = true) const { - planes[pos].xform.xscale = o; + if (!addbase) + { + return FIXED2DBL(planes[pos].xform.yoffs); + } + else + { + return FIXED2DBL(planes[pos].xform.yoffs + planes[pos].xform.base_yoffs); + } + } + + void SetXScale(int pos, double o) + { + planes[pos].xform.xscale = FLOAT2FIXED(o); } fixed_t GetXScale(int pos) const @@ -616,9 +729,14 @@ struct sector_t return planes[pos].xform.xscale; } - void SetYScale(int pos, fixed_t o) + double GetXScaleF(int pos) const { - planes[pos].xform.yscale = o; + return FIXED2DBL(planes[pos].xform.xscale); + } + + void SetYScale(int pos, double o) + { + planes[pos].xform.yscale = FLOAT2FIXED(o); } fixed_t GetYScale(int pos) const @@ -626,9 +744,14 @@ struct sector_t return planes[pos].xform.yscale; } - void SetAngle(int pos, angle_t o) + double GetYScaleF(int pos) const { - planes[pos].xform.angle = o; + return FIXED2DBL(planes[pos].xform.yscale); + } + + void SetAngle(int pos, DAngle o) + { + planes[pos].xform.angle = o.BAMs(); } angle_t GetAngle(int pos, bool addbase = true) const @@ -643,15 +766,27 @@ struct sector_t } } - void SetBase(int pos, fixed_t y, angle_t o) + DAngle GetAngleF(int pos, bool addbase = true) const { - planes[pos].xform.base_yoffs = y; - planes[pos].xform.base_angle = o; + if (!addbase) + { + return ANGLE2DBL(planes[pos].xform.angle); + } + else + { + return ANGLE2DBL(planes[pos].xform.angle + planes[pos].xform.base_angle); + } } - void SetAlpha(int pos, fixed_t o) + void SetBase(int pos, double y, DAngle o) { - planes[pos].alpha = o; + planes[pos].xform.base_yoffs = FLOAT2FIXED(y); + planes[pos].xform.base_angle = o.BAMs(); + } + + void SetAlpha(int pos, double o) + { + planes[pos].alpha = FLOAT2FIXED(o); } fixed_t GetAlpha(int pos) const @@ -659,7 +794,12 @@ struct sector_t return planes[pos].alpha; } - int GetFlags(int pos) const + double GetAlphaF(int pos) const + { + return FIXED2DBL(planes[pos].alpha); + } + + int GetFlags(int pos) const { return planes[pos].Flags; } @@ -697,14 +837,19 @@ struct sector_t return planes[pos].TexZ; } - void SetPlaneTexZ(int pos, fixed_t val) + double GetPlaneTexZF(int pos) const { - planes[pos].TexZ = val; + return FIXED2DBL(planes[pos].TexZ); } - void ChangePlaneTexZ(int pos, fixed_t val) + void SetPlaneTexZ(int pos, double val) { - planes[pos].TexZ += val; + planes[pos].TexZ = FLOAT2FIXED(val); + } + + void ChangePlaneTexZ(int pos, double val) + { + planes[pos].TexZ += FLOAT2FIXED(val); } static inline short ClampLight(int level) @@ -789,12 +934,12 @@ struct sector_t } // These may only be called if the portal has been validated - fixedvec2 FloorDisplacement() + DVector2 FloorDisplacement() { return Displacements.getOffset(PortalGroup, SkyBoxes[sector_t::floor]->Sector->PortalGroup); } - fixedvec2 CeilingDisplacement() + DVector2 CeilingDisplacement() { return Displacements.getOffset(PortalGroup, SkyBoxes[sector_t::ceiling]->Sector->PortalGroup); } @@ -807,25 +952,26 @@ struct sector_t bool PlaneMoving(int pos); // Portal-aware height calculation - fixed_t HighestCeilingAt(fixed_t x, fixed_t y, sector_t **resultsec = NULL); - fixed_t LowestFloorAt(fixed_t x, fixed_t y, sector_t **resultsec = NULL); + double HighestCeilingAt(const DVector2 &a, sector_t **resultsec = NULL); + double LowestFloorAt(const DVector2 &a, sector_t **resultsec = NULL); - fixed_t HighestCeilingAt(AActor *a, sector_t **resultsec = NULL) + + double HighestCeilingAt(AActor *a, sector_t **resultsec = NULL) { - return HighestCeilingAt(a->X(), a->Y(), resultsec); + return HighestCeilingAt(a->Pos(), resultsec); } - fixed_t LowestFloorAt(AActor *a, sector_t **resultsec = NULL) + double LowestFloorAt(AActor *a, sector_t **resultsec = NULL) { - return LowestFloorAt(a->X(), a->Y(), resultsec); + return LowestFloorAt(a->Pos(), resultsec); } - fixed_t NextHighestCeilingAt(fixed_t x, fixed_t y, fixed_t bottomz, fixed_t topz, int flags = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL); - fixed_t NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags = 0, fixed_t steph = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL); + double NextHighestCeilingAt(double x, double y, double bottomz, double topz, int flags = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL); + double NextLowestFloorAt(double x, double y, double z, int flags = 0, double steph = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL); // Member variables - fixed_t CenterFloor () const { return floorplane.ZatPoint (centerspot); } - fixed_t CenterCeiling () const { return ceilingplane.ZatPoint (centerspot); } + double CenterFloor() const { return floorplane.ZatPoint(centerspot); } + double CenterCeiling() const { return ceilingplane.ZatPoint(centerspot); } // [RH] store floor and ceiling planes instead of heights secplane_t floorplane, ceilingplane; @@ -843,14 +989,14 @@ struct sector_t int sky; FNameNoInit SeqName; // Sound sequence name. Setting seqType non-negative will override this. - fixedvec2 centerspot; // origin for any sounds played by the sector + DVector2 centerspot; // origin for any sounds played by the sector int validcount; // if == validcount, already checked AActor* thinglist; // list of mobjs in sector // killough 8/28/98: friction is a sector property, not an mobj property. // these fields used to be in AActor, but presented performance problems // when processed as mobj properties. Fix is to make them sector properties. - fixed_t friction, movefactor; + double friction, movefactor; int terrainnum[2]; @@ -888,7 +1034,7 @@ struct sector_t // thinglist is a subset of touching_thinglist struct msecnode_t *touching_thinglist; // phares 3/14/98 - float gravity; // [RH] Sector gravity (1.0 is normal) + double gravity; // [RH] Sector gravity (1.0 is normal) FNameNoInit damagetype; // [RH] Means-of-death for applied damage int damageamount; // [RH] Damage to do while standing on floor short damageinterval; // Interval for damage application @@ -998,14 +1144,32 @@ struct side_t textures[mid].xoffset = textures[bottom].xoffset = offset; } + void SetTextureXOffset(int which, double offset) + { + textures[which].xoffset = FLOAT2FIXED(offset); + } + void SetTextureXOffset(double offset) + { + textures[top].xoffset = + textures[mid].xoffset = + textures[bottom].xoffset = FLOAT2FIXED(offset); + } fixed_t GetTextureXOffset(int which) const { return textures[which].xoffset; } + double GetTextureXOffsetF(int which) const + { + return FIXED2DBL(textures[which].xoffset); + } void AddTextureXOffset(int which, fixed_t delta) { textures[which].xoffset += delta; } + void AddTextureXOffset(int which, double delta) + { + textures[which].xoffset += FLOAT2FIXED(delta); + } void SetTextureYOffset(int which, fixed_t offset) { @@ -1017,30 +1181,56 @@ struct side_t textures[mid].yoffset = textures[bottom].yoffset = offset; } + void SetTextureYOffset(int which, double offset) + { + textures[which].yoffset = FLOAT2FIXED(offset); + } + void SetTextureYOffset(double offset) + { + textures[top].yoffset = + textures[mid].yoffset = + textures[bottom].yoffset = FLOAT2FIXED(offset); + } fixed_t GetTextureYOffset(int which) const { return textures[which].yoffset; } + double GetTextureYOffsetF(int which) const + { + return FIXED2DBL(textures[which].yoffset); + } void AddTextureYOffset(int which, fixed_t delta) { textures[which].yoffset += delta; } + void AddTextureYOffset(int which, double delta) + { + textures[which].yoffset += FLOAT2FIXED(delta); + } void SetTextureXScale(int which, fixed_t scale) { textures[which].xscale = scale == 0 ? FRACUNIT : scale; } + void SetTextureXScale(int which, double scale) + { + textures[which].xscale = scale == 0 ? FRACUNIT : FLOAT2FIXED(scale); + } void SetTextureXScale(fixed_t scale) { textures[top].xscale = textures[mid].xscale = textures[bottom].xscale = scale == 0 ? FRACUNIT : scale; } + void SetTextureXScale(double scale) + { + textures[top].xscale = textures[mid].xscale = textures[bottom].xscale = scale == 0 ? FRACUNIT : FLOAT2FIXED(scale); + } fixed_t GetTextureXScale(int which) const { return textures[which].xscale; } - void MultiplyTextureXScale(int which, fixed_t delta) + void MultiplyTextureXScale(int which, double delta) { - textures[which].xscale = FixedMul(textures[which].xscale, delta); + textures[which].xscale = fixed_t(textures[which].xscale * delta); } @@ -1048,17 +1238,31 @@ struct side_t { textures[which].yscale = scale == 0 ? FRACUNIT : scale; } + + void SetTextureYScale(int which, double scale) + { + textures[which].yscale = scale == 0 ? FRACUNIT : FLOAT2FIXED(scale); + } + void SetTextureYScale(fixed_t scale) { textures[top].yscale = textures[mid].yscale = textures[bottom].yscale = scale == 0 ? FRACUNIT : scale; } + void SetTextureYScale(double scale) + { + textures[top].yscale = textures[mid].yscale = textures[bottom].yscale = scale == 0 ? FRACUNIT : FLOAT2FIXED(scale); + } fixed_t GetTextureYScale(int which) const { return textures[which].yscale; } - void MultiplyTextureYScale(int which, fixed_t delta) + double GetTextureYScaleF(int which) const { - textures[which].yscale = FixedMul(textures[which].yscale, delta); + return FIXED2DBL(textures[which].yscale); + } + void MultiplyTextureYScale(int which, double delta) + { + textures[which].yscale = fixed_t(textures[which].yscale * delta); } DInterpolation *SetInterpolation(int position); @@ -1073,19 +1277,36 @@ FArchive &operator<< (FArchive &arc, side_t::part &p); struct line_t { vertex_t *v1, *v2; // vertices, from v1 to v2 - fixed_t dx, dy; // precalculated v2 - v1 for side checking +private: + DVector2 delta; // precalculated v2 - v1 for side checking +public: DWORD flags; DWORD activation; // activation type int special; fixed_t Alpha; // <--- translucency (0=invisibile, FRACUNIT=opaque) int args[5]; // <--- hexen-style arguments (expanded to ZDoom's full width) side_t *sidedef[2]; - fixed_t bbox[4]; // bounding box, for the extent of the LineDef. + double bbox[4]; // bounding box, for the extent of the LineDef. sector_t *frontsector, *backsector; int validcount; // if == validcount, already checked int locknumber; // [Dusk] lock number for special unsigned portalindex; + DVector2 Delta() const + { + return delta; + } + + void setDelta(double x, double y) + { + delta = { x, y }; + } + + void setAlpha(double a) + { + Alpha = FLOAT2FIXED(a); + } + FLinePortal *getPortal() const { return portalindex >= linePortals.Size() ? (FLinePortal*)NULL : &linePortals[portalindex]; @@ -1240,7 +1461,7 @@ typedef BYTE lighttable_t; // This could be wider for >8 bit display. struct visstyle_t { lighttable_t *colormap; - fixed_t alpha; + float Alpha; FRenderStyle RenderStyle; }; @@ -1251,46 +1472,60 @@ struct visstyle_t // not the same as R_PointInSubsector // //---------------------------------------------------------------------------------- -subsector_t *P_PointInSubsector(fixed_t x, fixed_t y); -inline sector_t *P_PointInSector(fixed_t x, fixed_t y) +subsector_t *P_PointInSubsector(double x, double y); + +inline sector_t *P_PointInSector(const DVector2 &pos) { - return P_PointInSubsector(x, y)->sector; + return P_PointInSubsector(pos.X, pos.Y)->sector; } -inline fixedvec3 AActor::PosRelative(int portalgroup) const +inline sector_t *P_PointInSector(double X, double Y) { - return __pos + Displacements.getOffset(Sector->PortalGroup, portalgroup); + return P_PointInSubsector(X, Y)->sector; } -inline fixedvec3 AActor::PosRelative(const AActor *other) const +inline DVector3 AActor::PosRelative(int portalgroup) const { - return __pos + Displacements.getOffset(Sector->PortalGroup, other->Sector->PortalGroup); + return Pos() + Displacements.getOffset(Sector->PortalGroup, portalgroup); } -inline fixedvec3 AActor::PosRelative(sector_t *sec) const +inline DVector3 AActor::PosRelative(const AActor *other) const { - return __pos + Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup); + return Pos() + Displacements.getOffset(Sector->PortalGroup, other->Sector->PortalGroup); } -inline fixedvec3 AActor::PosRelative(line_t *line) const +inline DVector3 AActor::PosRelative(sector_t *sec) const { - return __pos + Displacements.getOffset(Sector->PortalGroup, line->frontsector->PortalGroup); + return Pos() + Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup); } -inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refsec = NULL) +inline DVector3 AActor::PosRelative(line_t *line) const +{ + return Pos() + Displacements.getOffset(Sector->PortalGroup, line->frontsector->PortalGroup); +} + +inline DVector3 PosRelative(const DVector3 &pos, line_t *line, sector_t *refsec = NULL) { return pos + Displacements.getOffset(refsec->PortalGroup, line->frontsector->PortalGroup); } + inline void AActor::ClearInterpolation() { - PrevX = X(); - PrevY = Y(); - PrevZ = Z(); - PrevAngle = angle; + Prev = Pos(); + PrevAngles = Angles; if (Sector) PrevPortalGroup = Sector->PortalGroup; else PrevPortalGroup = 0; } +inline bool FBoundingBox::inRange(const line_t *ld) const +{ + return Left() < ld->bbox[BOXRIGHT] && + Right() > ld->bbox[BOXLEFT] && + Top() > ld->bbox[BOXBOTTOM] && + Bottom() < ld->bbox[BOXTOP]; +} + + #endif diff --git a/src/r_draw.cpp b/src/r_draw.cpp index a3cb0de03..24a48e3b3 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -2349,6 +2349,18 @@ static bool R_SetBlendFunc (int op, fixed_t fglevel, fixed_t bglevel, int flags) } } +static fixed_t GetAlpha(int type, fixed_t alpha) +{ + switch (type) + { + case STYLEALPHA_Zero: return 0; + case STYLEALPHA_One: return OPAQUE; + case STYLEALPHA_Src: return alpha; + case STYLEALPHA_InvSrc: return OPAQUE - alpha; + default: return 0; + } +} + ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, DWORD color) { fixed_t fglevel, bglevel; @@ -2358,13 +2370,13 @@ ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, if (style.BlendOp == STYLEOP_Shadow) { style = LegacyRenderStyles[STYLE_TranslucentStencil]; - alpha = FRACUNIT*3/10; + alpha = TRANSLUC33; color = 0; } if (style.Flags & STYLEF_TransSoulsAlpha) { - alpha = fixed_t(transsouls * FRACUNIT); + alpha = fixed_t(transsouls * OPAQUE); } else if (style.Flags & STYLEF_Alpha1) { @@ -2372,7 +2384,7 @@ ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, } else { - alpha = clamp (alpha, 0, FRACUNIT); + alpha = clamp (alpha, 0, OPAQUE); } dc_translation = NULL; diff --git a/src/r_draw.h b/src/r_draw.h index 819306d2e..326ce217b 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -269,6 +269,10 @@ enum ESPSResult DoDraw1, // draw this as if r_columnmethod is 1 }; ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, DWORD color); +inline ESPSResult R_SetPatchStyle(FRenderStyle style, float alpha, int translation, DWORD color) +{ + return R_SetPatchStyle(style, FLOAT2FIXED(alpha), translation, color); +} // Call this after finished drawing the current thing, in case its // style was STYLE_Shade diff --git a/src/r_main.cpp b/src/r_main.cpp index 44ed781bb..3577b3c3b 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -68,6 +68,7 @@ #define TEST_ANGLE 2468347904 #endif + // TYPES ------------------------------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -702,22 +703,22 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) vertex_t *v1 = pds->src->v1; // Reflect the current view behind the mirror. - if (pds->src->dx == 0) + if (pds->src->Delta().X == 0) { // vertical mirror - viewx = v1->x - startx + v1->x; + viewx = v1->fixX() - startx + v1->fixX(); } - else if (pds->src->dy == 0) + else if (pds->src->Delta().Y == 0) { // horizontal mirror - viewy = v1->y - starty + v1->y; + viewy = v1->fixY() - starty + v1->fixY(); } else { // any mirror--use floats to avoid integer overflow vertex_t *v2 = pds->src->v2; - double dx = FIXED2DBL(v2->x - v1->x); - double dy = FIXED2DBL(v2->y - v1->y); - double x1 = FIXED2DBL(v1->x); - double y1 = FIXED2DBL(v1->y); + double dx = v2->fX() - v1->fX(); + double dy = v2->fY() - v1->fY(); + double x1 = v1->fX(); + double y1 = v1->fY(); double x = FIXED2DBL(startx); double y = FIXED2DBL(starty); @@ -727,16 +728,22 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) viewx = FLOAT2FIXED((x1 + r * dx)*2 - x); viewy = FLOAT2FIXED((y1 + r * dy)*2 - y); } - viewangle = 2*R_PointToAngle2 (pds->src->v1->x, pds->src->v1->y, - pds->src->v2->x, pds->src->v2->y) - startang; - + viewangle = pds->src->Delta().Angle().BAMs() - startang; + ViewAngle = AngleToFloat(viewangle); } else { - P_TranslatePortalXY(pds->src, viewx, viewy); - P_TranslatePortalZ(pds->src, viewz); - P_TranslatePortalAngle(pds->src, viewangle); + DVector3 view(FIXED2DBL(viewx), FIXED2DBL(viewy), FIXED2DBL(viewz)); + DAngle va = ANGLE2DBL(viewangle); + P_TranslatePortalXY(pds->src, view.X, view.Y); + P_TranslatePortalZ(pds->src, view.Z); + P_TranslatePortalAngle(pds->src, va); + viewx = FLOAT2FIXED(view.X); + viewy = FLOAT2FIXED(view.Y); + viewz = FLOAT2FIXED(view.Z); + viewangle = va.BAMs(); } + ViewAngle = AngleToFloat(viewangle); viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; @@ -815,6 +822,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) viewx = startx; viewy = starty; viewz = startz; + ViewAngle = AngleToFloat(viewangle); } //========================================================================== diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 15653a1e8..e24bbe0b6 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -91,7 +91,7 @@ visplane_t *ceilingplane; // Empirically verified to be fairly uniform: #define visplane_hash(picnum,lightlevel,height) \ - ((unsigned)((picnum)*3+(lightlevel)+((height).d)*7) & (MAXVISPLANES-1)) + ((unsigned)((picnum)*3+(lightlevel)+(FLOAT2FIXED((height).fD()))*7) & (MAXVISPLANES-1)) // These are copies of the main parameters used when drawing stacked sectors. // When you change the main parameters, you should copy them here too *unless* @@ -601,13 +601,11 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl angle = 0; alpha = 0; additive = false; - plane.a = plane.b = plane.d = 0; // [RH] Map floor skies and ceiling skies to separate visplanes. This isn't // always necessary, but it is needed if a floor and ceiling sky are in the // same column but separated by a wall. If they both try to reside in the // same visplane, then only the floor sky will be drawn. - plane.c = height.c; - plane.ic = height.ic; + plane.set(0., 0., height.fC(), 0.); isskybox = skybox != NULL && !skybox->bInSkybox; } else if (skybox != NULL && skybox->bAlways && !skybox->bInSkybox) @@ -625,7 +623,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl if (fake3D & (FAKE3D_FAKEFLOOR|FAKE3D_FAKECEILING)) sky = 0x80000000 | fakeAlpha; else sky = 0; // not skyflatnum so it can't be a sky skybox = NULL; - alpha = FRACUNIT; + alpha = OPAQUE; } // New visplane algorithm uses hash table -- killough @@ -957,7 +955,7 @@ static void R_DrawSky (visplane_t *pl) rw_pic = frontskytex; rw_offset = 0; - frontyScale = rw_pic->yScale; + frontyScale = FLOAT2FIXED(rw_pic->Scale.Y); dc_texturemid = MulScale16 (skymid, frontyScale); if (1 << frontskytex->HeightBits == frontskytex->GetHeight()) @@ -1003,6 +1001,7 @@ static void R_DrawSkyStriped (visplane_t *pl) yl = 0; yh = (short)MulScale32 ((frontskytex->GetHeight() << FRACBITS) - topfrac, frontyScale); dc_texturemid = topfrac - iscale * (1-centery); + fixed_t yScale = FLOAT2FIXED(rw_pic->Scale.Y); while (yl < viewheight) { @@ -1015,7 +1014,7 @@ static void R_DrawSkyStriped (visplane_t *pl) { lastskycol[x] = 0xffffffff; } - wallscan (pl->left, pl->right, top, bot, swall, lwall, rw_pic->yScale, + wallscan (pl->left, pl->right, top, bot, swall, lwall, yScale, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns); yl = yh; yh += drawheight; @@ -1083,6 +1082,7 @@ void R_DrawHeightPlanes(fixed_t height) viewy = pl->viewy; viewz = pl->viewz; viewangle = pl->viewangle; + ViewAngle = AngleToFloat(viewangle); MirrorFlags = pl->MirrorFlags; R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, pl->Additive, true); } @@ -1093,6 +1093,7 @@ void R_DrawHeightPlanes(fixed_t height) viewy = oViewY; viewz = oViewZ; viewangle = oViewAngle; + ViewAngle = AngleToFloat(viewangle); } @@ -1106,8 +1107,6 @@ void R_DrawHeightPlanes(fixed_t height) void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked) { -// pl->angle = pa<left >= pl->right) return; @@ -1138,14 +1137,14 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske masked = false; } R_SetupSpanBits(tex); - pl->xscale = MulScale16 (pl->xscale, tex->xScale); - pl->yscale = MulScale16 (pl->yscale, tex->yScale); + pl->xscale = fixed_t(pl->xscale * tex->Scale.X); + pl->yscale = fixed_t(pl->yscale * tex->Scale.Y); ds_source = tex->GetPixels (); basecolormap = pl->colormap; planeshade = LIGHT2SHADE(pl->lightlevel); - if (r_drawflat || ((pl->height.a == 0 && pl->height.b == 0) && !tilt)) + if (r_drawflat || (!pl->height.isSlope() && !tilt)) { R_DrawNormalPlane (pl, alpha, additive, masked); } @@ -1239,11 +1238,11 @@ void R_DrawSkyBoxes () extralight = 0; R_SetVisibility (sky->args[0] * 0.25f); - fixedvec3 viewpos = sky->InterpolatedPosition(r_TicFrac); - viewx = viewpos.x; - viewy = viewpos.y; - viewz = viewpos.z; - viewangle = savedangle + sky->PrevAngle + FixedMul(r_TicFrac, sky->angle - sky->PrevAngle); + DVector3 viewpos = sky->InterpolatedPosition(r_TicFracF); + viewx = FLOAT2FIXED(viewpos.X); + viewy = FLOAT2FIXED(viewpos.Y); + viewz = FLOAT2FIXED(viewpos.Z); + viewangle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF).BAMs(); R_CopyStackedViewParameters(); } @@ -1251,11 +1250,12 @@ void R_DrawSkyBoxes () { extralight = pl->extralight; R_SetVisibility (pl->visibility); - viewx = pl->viewx - sky->Mate->X() + sky->X(); - viewy = pl->viewy - sky->Mate->Y() + sky->Y(); + viewx = pl->viewx + FLOAT2FIXED(-sky->Mate->X() + sky->X()); + viewy = pl->viewy + FLOAT2FIXED(-sky->Mate->Y() + sky->Y()); viewz = pl->viewz; viewangle = pl->viewangle; } + ViewAngle = AngleToFloat(viewangle); sky->bInSkybox = true; if (mate != NULL) mate->bInSkybox = true; @@ -1370,6 +1370,7 @@ void R_DrawSkyBoxes () R_SetVisibility (savedvisibility); extralight = savedextralight; viewangle = savedangle; + ViewAngle = AngleToFloat(viewangle); R_SetViewAngle (); CurrentPortalInSkybox = false; @@ -1478,7 +1479,8 @@ void R_DrawSkyPlane (visplane_t *pl) // allow old sky textures to be used. skyflip = l->args[2] ? 0u : ~0u; - frontcyl = MAX(frontskytex->GetWidth(), frontskytex->xScale >> (16 - 10)); + int frontxscale = int(frontskytex->Scale.X * 1024); + frontcyl = MAX(frontskytex->GetWidth(), frontxscale); if (skystretch) { skymid = Scale(skymid, frontskytex->GetScaledHeight(), SKYSTRETCH_HEIGHT); @@ -1533,7 +1535,7 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske yscale = pl->yscale << (16 - ds_ybits); if (planeang != 0) { - double rad = ANGLE2RAD(planeang); + double rad = planeang * (M_PI / ANGLE_180); double cosine = cos(rad), sine = sin(rad); pviewx = xs_RoundToInt(pl->xoffs + viewx * cosine - viewy * sine); @@ -1566,7 +1568,7 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske basexfrac = FixedMul (xscale, finecosine[planeang]) + x*xstepscale; baseyfrac = FixedMul (yscale, -finesine[planeang]) + x*ystepscale; - planeheight = abs (FixedMul (pl->height.d, -pl->height.ic) - viewz); + planeheight = abs (pl->height.Zat0() - viewz); GlobVis = FixedDiv (r_FloorVisibility, planeheight); if (fixedlightlev >= 0) @@ -1670,29 +1672,29 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske // p is the texture origin in view space // Don't add in the offsets at this stage, because doing so can result in // errors if the flat is rotated. - ang = ANGLE2RAD(ANG270 - viewangle); + ang = (ANG270 - viewangle) * (M_PI / ANGLE_180); p[0] = vx * cos(ang) - vy * sin(ang); p[2] = vx * sin(ang) + vy * cos(ang); p[1] = pl->height.ZatPoint(0.0, 0.0) - vz; // m is the v direction vector in view space - ang = ANGLE2RAD(ANG180 - viewangle - pl->angle); + ang = (ANG180 - viewangle - pl->angle) * (M_PI / ANGLE_180); m[0] = yscale * cos(ang); m[2] = yscale * sin(ang); -// m[1] = FIXED2FLOAT(pl->height.ZatPoint (0, iyscale) - pl->height.ZatPoint (0,0)); +// m[1] = pl->height.ZatPointF (0, iyscale) - pl->height.ZatPointF (0,0)); // VectorScale2 (m, 64.f/VectorLength(m)); // n is the u direction vector in view space ang += PI/2; n[0] = -xscale * cos(ang); n[2] = -xscale * sin(ang); -// n[1] = FIXED2FLOAT(pl->height.ZatPoint (ixscale, 0) - pl->height.ZatPoint (0,0)); +// n[1] = pl->height.ZatPointF (ixscale, 0) - pl->height.ZatPointF (0,0)); // VectorScale2 (n, 64.f/VectorLength(n)); // This code keeps the texture coordinates constant across the x,y plane no matter // how much you slope the surface. Use the commented-out code above instead to keep // the textures a constant size across the surface's plane instead. - ang = ANGLE2RAD(pl->angle); + ang = pl->angle * (M_PI / ANGLE_180); m[1] = pl->height.ZatPoint(vx + yscale * sin(ang), vy + yscale * cos(ang)) - zeroheight; ang += PI/2; n[1] = pl->height.ZatPoint(vx + xscale * sin(ang), vy + xscale * cos(ang)) - zeroheight; @@ -1722,7 +1724,7 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske planelightfloat = (r_TiltVisibility * lxscale * lyscale) / (fabs(pl->height.ZatPoint(FIXED2DBL(viewx), FIXED2DBL(viewy)) - FIXED2DBL(viewz))) / 65536.0; - if (pl->height.c > 0) + if (pl->height.fC() > 0) planelightfloat = -planelightfloat; if (fixedlightlev >= 0) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index eca7adc88..3acc90993 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -243,7 +243,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) ESPSResult drawmode; drawmode = R_SetPatchStyle (LegacyRenderStyles[curline->linedef->flags & ML_ADDTRANS ? STYLE_Add : STYLE_Translucent], - MIN(curline->linedef->Alpha, FRACUNIT), 0, 0); + MIN(curline->linedef->Alpha, OPAQUE), 0, 0); if ((drawmode == DontDraw && !ds->bFogBoundary && !ds->bFakeBoundary)) { @@ -274,7 +274,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) { if (!(fake3D & FAKE3D_CLIPTOP)) { - sclipTop = sec->ceilingplane.ZatPoint(viewx, viewy); + sclipTop = sec->ceilingplane.ZatPointFixed(viewx, viewy); } for (i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) { @@ -601,8 +601,8 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) scaledside = rover->master->sidedef[0]; scaledpart = side_t::mid; } - xscale = FixedMul(rw_pic->xScale, scaledside->GetTextureXScale(scaledpart)); - yscale = FixedMul(rw_pic->yScale, scaledside->GetTextureYScale(scaledpart)); + xscale = fixed_t(rw_pic->Scale.X * scaledside->GetTextureXScale(scaledpart)); + yscale = fixed_t(rw_pic->Scale.Y * scaledside->GetTextureYScale(scaledpart)); fixed_t rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureYOffset(side_t::mid); dc_texturemid = rover->model->GetPlaneTexZ(sector_t::ceiling); @@ -687,16 +687,16 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) frontsector = sec; } - floorheight = backsector->CenterFloor(); - ceilingheight = backsector->CenterCeiling(); + floorheight = FLOAT2FIXED(backsector->CenterFloor()); + ceilingheight = FLOAT2FIXED(backsector->CenterCeiling()); // maybe fix clipheights if (!(fake3D & FAKE3D_CLIPBOTTOM)) sclipBottom = floorheight; if (!(fake3D & FAKE3D_CLIPTOP)) sclipTop = ceilingheight; // maybe not visible - if (sclipBottom >= frontsector->CenterCeiling()) return; - if (sclipTop <= frontsector->CenterFloor()) return; + if (sclipBottom >= FLOAT2FIXED(frontsector->CenterCeiling())) return; + if (sclipTop <= FLOAT2FIXED(frontsector->CenterFloor())) return; if (fake3D & FAKE3D_DOWN2UP) { // bottom to viewz @@ -708,9 +708,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) // visible? passed = 0; - if (!(rover->flags & FF_RENDERSIDES) || - rover->top.plane->a || rover->top.plane->b || - rover->bottom.plane->a || rover->bottom.plane->b || + if (!(rover->flags & FF_RENDERSIDES) || rover->top.plane->isSlope() || rover->bottom.plane->isSlope() || rover->top.plane->Zat0() <= sclipBottom || rover->bottom.plane->Zat0() >= ceilingheight || rover->top.plane->Zat0() <= floorheight) @@ -745,7 +743,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) if (!(fover->flags & FF_EXISTS)) continue; if (!(fover->flags & FF_RENDERSIDES)) continue; // no sloped walls, it's bugged - if (fover->top.plane->a || fover->top.plane->b || fover->bottom.plane->a || fover->bottom.plane->b) continue; + if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; // visible? if (fover->top.plane->Zat0() <= sclipBottom) continue; // no @@ -798,7 +796,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) if (!(fover->flags & FF_EXISTS)) continue; if (!(fover->flags & FF_RENDERSIDES)) continue; // no sloped walls, it's bugged - if (fover->top.plane->a || fover->top.plane->b || fover->bottom.plane->a || fover->bottom.plane->b) continue; + if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; // visible? if (fover->top.plane->Zat0() <= sclipBottom) continue; // no @@ -893,8 +891,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) // visible? passed = 0; if (!(rover->flags & FF_RENDERSIDES) || - rover->top.plane->a || rover->top.plane->b || - rover->bottom.plane->a || rover->bottom.plane->b || + rover->top.plane->isSlope() || rover->bottom.plane->isSlope() || rover->bottom.plane->Zat0() >= sclipTop || rover->top.plane->Zat0() <= floorheight || rover->bottom.plane->Zat0() >= ceilingheight) @@ -923,7 +920,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) if (!(fover->flags & FF_EXISTS)) continue; if (!(fover->flags & FF_RENDERSIDES)) continue; // no sloped walls, it's bugged - if (fover->top.plane->a || fover->top.plane->b || fover->bottom.plane->a || fover->bottom.plane->b) continue; + if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; // visible? if (fover->bottom.plane->Zat0() >= sclipTop) continue; // no @@ -975,7 +972,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) if (!(fover->flags & FF_EXISTS)) continue; if (!(fover->flags & FF_RENDERSIDES)) continue; // no sloped walls, its bugged - if(fover->top.plane->a || fover->top.plane->b || fover->bottom.plane->a || fover->bottom.plane->b) continue; + if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; // visible? if (fover->bottom.plane->Zat0() >= sclipTop) continue; // no @@ -1388,10 +1385,10 @@ static void wallscan_np2_ds(drawseg_t *ds, int x1, int x2, short *uwal, short *d { if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits) { - fixed_t frontcz1 = ds->curline->frontsector->ceilingplane.ZatPoint(ds->curline->v1->x, ds->curline->v1->y); - fixed_t frontfz1 = ds->curline->frontsector->floorplane.ZatPoint(ds->curline->v1->x, ds->curline->v1->y); - fixed_t frontcz2 = ds->curline->frontsector->ceilingplane.ZatPoint(ds->curline->v2->x, ds->curline->v2->y); - fixed_t frontfz2 = ds->curline->frontsector->floorplane.ZatPoint(ds->curline->v2->x, ds->curline->v2->y); + fixed_t frontcz1 = ds->curline->frontsector->ceilingplane.ZatPointFixed(ds->curline->v1); + fixed_t frontfz1 = ds->curline->frontsector->floorplane.ZatPointFixed(ds->curline->v1); + fixed_t frontcz2 = ds->curline->frontsector->ceilingplane.ZatPointFixed(ds->curline->v2); + fixed_t frontfz2 = ds->curline->frontsector->floorplane.ZatPointFixed(ds->curline->v2); fixed_t top = MAX(frontcz1, frontcz2); fixed_t bot = MIN(frontfz1, frontfz2); if (fake3D & FAKE3D_CLIPTOP) @@ -1861,8 +1858,8 @@ void R_RenderSegLoop () { dc_texturemid = rw_midtexturemid; rw_pic = midtexture; - xscale = FixedMul(rw_pic->xScale, rw_midtexturescalex); - yscale = FixedMul(rw_pic->yScale, rw_midtexturescaley); + xscale = fixed_t(rw_pic->Scale.X * rw_midtexturescalex); + yscale = fixed_t(rw_pic->Scale.Y * rw_midtexturescaley); if (xscale != lwallscale) { PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2); @@ -1904,8 +1901,8 @@ void R_RenderSegLoop () { dc_texturemid = rw_toptexturemid; rw_pic = toptexture; - xscale = FixedMul(rw_pic->xScale, rw_toptexturescalex); - yscale = FixedMul(rw_pic->yScale, rw_toptexturescaley); + xscale = fixed_t(rw_pic->Scale.X * rw_toptexturescalex); + yscale = fixed_t(rw_pic->Scale.Y * rw_toptexturescaley); if (xscale != lwallscale) { PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2); @@ -1950,8 +1947,8 @@ void R_RenderSegLoop () { dc_texturemid = rw_bottomtexturemid; rw_pic = bottomtexture; - xscale = FixedMul(rw_pic->xScale, rw_bottomtexturescalex); - yscale = FixedMul(rw_pic->yScale, rw_bottomtexturescaley); + xscale = fixed_t(rw_pic->Scale.X * rw_bottomtexturescalex); + yscale = fixed_t(rw_pic->Scale.Y * rw_bottomtexturescaley); if (xscale != lwallscale) { PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2); @@ -2021,7 +2018,7 @@ void R_NewWall (bool needlights) rowoffset = sidedef->GetTextureYOffset(side_t::mid); rw_midtexturescalex = sidedef->GetTextureXScale(side_t::mid); rw_midtexturescaley = sidedef->GetTextureYScale(side_t::mid); - yrepeat = FixedMul(midtexture->yScale, rw_midtexturescaley); + yrepeat = fixed_t(midtexture->Scale.Y * rw_midtexturescaley); if (yrepeat >= 0) { // normal orientation if (linedef->flags & ML_DONTPEGBOTTOM) @@ -2176,7 +2173,7 @@ void R_NewWall (bool needlights) rowoffset = sidedef->GetTextureYOffset(side_t::top); rw_toptexturescalex = sidedef->GetTextureXScale(side_t::top); rw_toptexturescaley = sidedef->GetTextureYScale(side_t::top); - yrepeat = FixedMul(toptexture->yScale, rw_toptexturescaley); + yrepeat = fixed_t(toptexture->Scale.Y * rw_toptexturescaley); if (yrepeat >= 0) { // normal orientation if (linedef->flags & ML_DONTPEGTOP) @@ -2221,7 +2218,7 @@ void R_NewWall (bool needlights) rowoffset = sidedef->GetTextureYOffset(side_t::bottom); rw_bottomtexturescalex = sidedef->GetTextureXScale(side_t::bottom); rw_bottomtexturescaley = sidedef->GetTextureYScale(side_t::bottom); - yrepeat = FixedMul(bottomtexture->yScale, rw_bottomtexturescaley); + yrepeat = fixed_t(bottomtexture->Scale.Y * rw_bottomtexturescaley); if (yrepeat >= 0) { // normal orientation if (linedef->flags & ML_DONTPEGBOTTOM) @@ -2269,7 +2266,7 @@ void R_NewWall (bool needlights) int planeside; planeside = frontsector->floorplane.PointOnSide(viewx, viewy, viewz); - if (frontsector->floorplane.c < 0) // 3D floors have the floor backwards + if (frontsector->floorplane.fC() < 0) // 3D floors have the floor backwards planeside = -planeside; if (planeside <= 0) // above view plane markfloor = false; @@ -2277,7 +2274,7 @@ void R_NewWall (bool needlights) if (frontsector->GetTexture(sector_t::ceiling) != skyflatnum) { planeside = frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz); - if (frontsector->ceilingplane.c > 0) // 3D floors have the ceiling backwards + if (frontsector->ceilingplane.fC() > 0) // 3D floors have the ceiling backwards planeside = -planeside; if (planeside <= 0) // below view plane markceiling = false; @@ -2292,9 +2289,9 @@ void R_NewWall (bool needlights) if (needlights && (segtextured || (backsector && IsFogBoundary(frontsector, backsector)))) { lwallscale = - midtex ? FixedMul(midtex->xScale, sidedef->GetTextureXScale(side_t::mid)) : - toptexture ? FixedMul(toptexture->xScale, sidedef->GetTextureXScale(side_t::top)) : - bottomtexture ? FixedMul(bottomtexture->xScale, sidedef->GetTextureXScale(side_t::bottom)) : + midtex ? int(midtex->Scale.X * sidedef->GetTextureXScale(side_t::mid)) : + toptexture ? int(toptexture->Scale.X * sidedef->GetTextureXScale(side_t::top)) : + bottomtexture ? int(bottomtexture->Scale.X * sidedef->GetTextureXScale(side_t::bottom)) : FRACUNIT; PrepWall (swall, lwall, sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2); @@ -2507,7 +2504,7 @@ void R_StoreWallRange (int start, int stop) lwal = (fixed_t *)(openings + ds_p->maskedtexturecol); swal = (fixed_t *)(openings + ds_p->swall); FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid), true); - fixed_t yrepeat = FixedMul(pic->yScale, sidedef->GetTextureYScale(side_t::mid)); + fixed_t yrepeat = int(pic->Scale.X * sidedef->GetTextureYScale(side_t::mid)); fixed_t xoffset = sidedef->GetTextureXOffset(side_t::mid); if (pic->bWorldPanning) @@ -2767,9 +2764,9 @@ int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc) int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) { - if ((plane.a | plane.b) == 0) + if (!plane.isSlope()) { - return OWallMost (mostbuf, ((plane.c < 0) ? plane.d : -plane.d) - viewz, wallc); + return OWallMost (mostbuf, plane.Zat0() - viewz, wallc); } fixed_t x, y, den, z1, z2, oz1, oz2; @@ -2778,27 +2775,27 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) if (MirrorFlags & RF_XFLIP) { - x = curline->v2->x; - y = curline->v2->y; + x = curline->v2->fixX(); + y = curline->v2->fixY(); if (wallc->sx1 == 0 && 0 != (den = wallc->tx1 - wallc->tx2 + wallc->ty1 - wallc->ty2)) { int frac = SafeDivScale30 (wallc->ty1 + wallc->tx1, den); - x -= MulScale30 (frac, x - curline->v1->x); - y -= MulScale30 (frac, y - curline->v1->y); + x -= MulScale30 (frac, x - curline->v1->fixX()); + y -= MulScale30 (frac, y - curline->v1->fixY()); } - z1 = viewz - plane.ZatPoint (x, y); + z1 = viewz - plane.ZatPointFixed(x, y); if (wallc->sx2 > wallc->sx1 + 1) { - x = curline->v1->x; - y = curline->v1->y; + x = curline->v1->fixX(); + y = curline->v1->fixY(); if (wallc->sx2 == viewwidth && 0 != (den = wallc->tx1 - wallc->tx2 - wallc->ty1 + wallc->ty2)) { int frac = SafeDivScale30 (wallc->ty2 - wallc->tx2, den); - x += MulScale30 (frac, curline->v2->x - x); - y += MulScale30 (frac, curline->v2->y - y); + x += MulScale30 (frac, curline->v2->fixX() - x); + y += MulScale30 (frac, curline->v2->fixY() - y); } - z2 = viewz - plane.ZatPoint (x, y); + z2 = viewz - plane.ZatPointFixed(x, y); } else { @@ -2807,27 +2804,27 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) } else { - x = curline->v1->x; - y = curline->v1->y; + x = curline->v1->fixX(); + y = curline->v1->fixY(); if (wallc->sx1 == 0 && 0 != (den = wallc->tx1 - wallc->tx2 + wallc->ty1 - wallc->ty2)) { int frac = SafeDivScale30 (wallc->ty1 + wallc->tx1, den); - x += MulScale30 (frac, curline->v2->x - x); - y += MulScale30 (frac, curline->v2->y - y); + x += MulScale30 (frac, curline->v2->fixX() - x); + y += MulScale30 (frac, curline->v2->fixY() - y); } - z1 = viewz - plane.ZatPoint (x, y); + z1 = viewz - plane.ZatPointFixed(x, y); if (wallc->sx2 > wallc->sx1 + 1) { - x = curline->v2->x; - y = curline->v2->y; + x = curline->v2->fixX(); + y = curline->v2->fixY(); if (wallc->sx2 == viewwidth && 0 != (den = wallc->tx1 - wallc->tx2 - wallc->ty1 + wallc->ty2)) { int frac = SafeDivScale30 (wallc->ty2 - wallc->tx2, den); - x -= MulScale30 (frac, x - curline->v1->x); - y -= MulScale30 (frac, y - curline->v1->y); + x -= MulScale30 (frac, x - curline->v1->fixX()); + y -= MulScale30 (frac, y - curline->v1->fixY()); } - z2 = viewz - plane.ZatPoint (x, y); + z2 = viewz - plane.ZatPointFixed(x, y); } else { @@ -3022,7 +3019,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, fixed_t xscale, yscale; fixed_t topoff; BYTE flipx; - fixed_t zpos; + double zpos; int needrepeat = 0; sector_t *front, *back; bool calclighting; @@ -3044,36 +3041,36 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, case RF_RELUPPER: if (curline->linedef->flags & ML_DONTPEGTOP) { - zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling); + zpos = decal->Z + front->GetPlaneTexZF(sector_t::ceiling); } else { - zpos = decal->Z + back->GetPlaneTexZ(sector_t::ceiling); + zpos = decal->Z + back->GetPlaneTexZF(sector_t::ceiling); } break; case RF_RELLOWER: if (curline->linedef->flags & ML_DONTPEGBOTTOM) { - zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling); + zpos = decal->Z + front->GetPlaneTexZF(sector_t::ceiling); } else { - zpos = decal->Z + back->GetPlaneTexZ(sector_t::floor); + zpos = decal->Z + back->GetPlaneTexZF(sector_t::floor); } break; case RF_RELMID: if (curline->linedef->flags & ML_DONTPEGBOTTOM) { - zpos = decal->Z + front->GetPlaneTexZ(sector_t::floor); + zpos = decal->Z + front->GetPlaneTexZF(sector_t::floor); } else { - zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling); + zpos = decal->Z + front->GetPlaneTexZF(sector_t::ceiling); } } - xscale = decal->ScaleX; - yscale = decal->ScaleY; + xscale = FLOAT2FIXED(decal->ScaleX); + yscale = FLOAT2FIXED(decal->ScaleY); WallSpriteTile = TexMan(decal->PicNum, true); flipx = (BYTE)(decal->RenderFlags & RF_XFLIP); @@ -3096,9 +3093,12 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, x1 *= xscale; x2 *= xscale; - decal->GetXY (wall, decalx, decaly); + double dcx, dcy; + decal->GetXY(wall, dcx, dcy); + decalx = FLOAT2FIXED(dcx); + decaly = FLOAT2FIXED(dcy); - angle_t ang = R_PointToAngle2 (curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y) >> ANGLETOFINESHIFT; + angle_t ang = R_PointToAngle2 (curline->v1->fixX(), curline->v1->fixY(), curline->v2->fixX(), curline->v2->fixY()) >> ANGLETOFINESHIFT; lx = decalx - FixedMul (x1, finecosine[ang]) - viewx; lx2 = decalx + FixedMul (x2, finecosine[ang]) - viewx; ly = decaly - FixedMul (x1, finesine[ang]) - viewy; @@ -3169,8 +3169,10 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, break; } + fixed_t fzpos; + fzpos = FLOAT2FIXED(zpos); // pacify GCC topoff = WallSpriteTile->TopOffset << FRACBITS; - dc_texturemid = topoff + FixedDiv (zpos - viewz, yscale); + dc_texturemid = topoff + FixedDiv (fzpos - viewz, yscale); // Clip sprite to drawseg x1 = MAX(clipper->x1, x1); @@ -3235,7 +3237,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, dc_x = x1; ESPSResult mode; - mode = R_SetPatchStyle (decal->RenderStyle, decal->Alpha, decal->Translation, decal->AlphaColor); + mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor); // R_SetPatchStyle can modify basecolormap. if (rereadcolormap) diff --git a/src/r_sky.cpp b/src/r_sky.cpp index 00d3dfc66..f3bdbed35 100644 --- a/src/r_sky.cpp +++ b/src/r_sky.cpp @@ -107,7 +107,7 @@ void R_InitSkyMap () } else if (skyheight > 200) { - skytexturemid = FixedMul((200 - skyheight) << FRACBITS, skytex1->yScale); + skytexturemid = FLOAT2FIXED((200 - skyheight) * skytex1->Scale.Y); } if (viewwidth != 0 && viewheight != 0) @@ -131,8 +131,8 @@ void R_InitSkyMap () // giving a total sky width of 1024 pixels. So if the sky texture is no wider than 1024, // we map it to a cylinder with circumfrence 1024. For larger ones, we use the width of // the texture as the cylinder's circumfrence. - sky1cyl = MAX(skytex1->GetWidth(), skytex1->xScale >> (16 - 10)); - sky2cyl = MAX(skytex2->GetWidth(), skytex2->xScale >> (16 - 10)); + sky1cyl = MAX(skytex1->GetWidth(), fixed_t(skytex1->Scale.X * 1024)); + sky2cyl = MAX(skytex2->GetWidth(), fixed_t(skytex2->Scale.Y * 1024)); } diff --git a/src/r_state.h b/src/r_state.h index 60cbecebf..5a5501465 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -78,9 +78,6 @@ extern int numgamesubsectors; // // POV data. // -extern fixed_t viewz; -extern angle_t viewangle; - extern AActor* camera; // [RH] camera instead of viewplayer extern sector_t* viewsector; // [RH] keep track of sector viewing from diff --git a/src/r_things.cpp b/src/r_things.cpp index 644ca7899..465b6c30f 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -374,7 +374,7 @@ static inline bool R_ClipSpriteColumnWithPortals(fixed_t x, fixed_t y, vissprite line_t* line = seg->curline->linedef; // don't clip if the sprite is in front of the portal - if (!P_PointOnLineSidePrecise(x, y, line)) + if (!P_PointOnLineSidePrecise(FIXED2DBL(x), FIXED2DBL(y), line)) continue; // now if current column is covered by this drawseg, we clip it away @@ -408,7 +408,7 @@ void R_DrawVisSprite (vissprite_t *vis) dc_colormap = vis->Style.colormap; - mode = R_SetPatchStyle (vis->Style.RenderStyle, vis->Style.alpha, vis->Translation, vis->FillColor); + mode = R_SetPatchStyle (vis->Style.RenderStyle, vis->Style.Alpha, vis->Translation, vis->FillColor); if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Shaded]) { // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but @@ -564,7 +564,7 @@ void R_DrawWallSprite(vissprite_t *spr) dc_x = x1; ESPSResult mode; - mode = R_SetPatchStyle (spr->Style.RenderStyle, spr->Style.alpha, spr->Translation, spr->FillColor); + mode = R_SetPatchStyle (spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor); // R_SetPatchStyle can modify basecolormap. if (rereadcolormap) @@ -655,7 +655,7 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop // Do setup for blending. dc_colormap = spr->Style.colormap; - mode = R_SetPatchStyle(spr->Style.RenderStyle, spr->Style.alpha, spr->Translation, spr->FillColor); + mode = R_SetPatchStyle(spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor); if (mode == DontDraw) { @@ -728,7 +728,6 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop // void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling) { - fixed_t fx, fy, fz; fixed_t tr_x; fixed_t tr_y; @@ -755,7 +754,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor // Don't waste time projecting sprites that are definitely not visible. if (thing == NULL || (thing->renderflags & RF_INVISIBLE) || - !thing->RenderStyle.IsVisible(thing->alpha) || + !thing->RenderStyle.IsVisible(thing->Alpha) || !thing->IsVisibleToPlayer()) { return; @@ -763,30 +762,29 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor // [ZZ] Or less definitely not visible (hue) // [ZZ] 10.01.2016: don't try to clip stuff inside a skybox against the current portal. - if (!CurrentPortalInSkybox && CurrentPortal && !!P_PointOnLineSidePrecise(thing->X(), thing->Y(), CurrentPortal->dst)) + if (!CurrentPortalInSkybox && CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), CurrentPortal->dst)) return; // [RH] Interpolate the sprite's position to make it look smooth - fixedvec3 pos = thing->InterpolatedPosition(r_TicFrac); - fx = pos.x; - fy = pos.y; - fz = pos.z + thing->GetBobOffset(r_TicFrac); + DVector3 pos = thing->InterpolatedPosition(r_TicFracF); + const fixed_t fx = FLOAT2FIXED(pos.X); + const fixed_t fy = FLOAT2FIXED(pos.Y); + fixed_t fz = FLOAT2FIXED(pos.Z + thing->GetBobOffset(r_TicFracF)); tex = NULL; voxel = NULL; int spritenum = thing->sprite; - fixed_t spritescaleX = thing->scaleX; - fixed_t spritescaleY = thing->scaleY; + DVector2 spriteScale = thing->Scale; int renderflags = thing->renderflags; - if (spritescaleY < 0) + if (spriteScale.Y < 0) { - spritescaleY = -spritescaleY; + spriteScale.Y = -spriteScale.Y; renderflags ^= RF_YFLIP; } if (thing->player != NULL) { - P_CheckPlayerSprite(thing, spritenum, spritescaleX, spritescaleY); + P_CheckPlayerSprite(thing, spritenum, spriteScale); } if (thing->picnum.isValid()) @@ -803,15 +801,15 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor { // choose a different rotation based on player view spriteframe_t *sprframe = &SpriteFrames[tex->Rotations]; - angle_t ang = R_PointToAngle (fx, fy); + angle_t ang = R_PointToAngle2 (viewx, viewy, fx, fy); angle_t rot; if (sprframe->Texture[0] == sprframe->Texture[1]) { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9) >> 28; + rot = (ang - thing->Angles.Yaw.BAMs() + (angle_t)(ANGLE_45/2)*9) >> 28; } else { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; + rot = (ang - thing->Angles.Yaw.BAMs() + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; } picnum = sprframe->Texture[rot]; if (sprframe->Flip & (1 << rot)) @@ -842,15 +840,15 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor //picnum = SpriteFrames[sprdef->spriteframes + thing->frame].Texture[0]; // choose a different rotation based on player view spriteframe_t *sprframe = &SpriteFrames[sprdef->spriteframes + thing->frame]; - angle_t ang = R_PointToAngle (fx, fy); + angle_t ang = R_PointToAngle2 (viewx, viewy, fx, fy); angle_t rot; if (sprframe->Texture[0] == sprframe->Texture[1]) { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9) >> 28; + rot = (ang - thing->Angles.Yaw.BAMs() + (angle_t)(ANGLE_45/2)*9) >> 28; } else { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; + rot = (ang - thing->Angles.Yaw.BAMs() + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; } picnum = sprframe->Texture[rot]; if (sprframe->Flip & (1 << rot)) @@ -864,9 +862,9 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } } } - if (spritescaleX < 0) + if (spriteScale.X < 0) { - spritescaleX = -spritescaleX; + spriteScale.X = -spriteScale.X; renderflags ^= RF_XFLIP; } if (voxel == NULL && (tex == NULL || tex->UseType == FTexture::TEX_Null)) @@ -874,6 +872,8 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor return; } + fixed_t spritescaleX = FLOAT2FIXED(spriteScale.X); + fixed_t spritescaleY = FLOAT2FIXED(spriteScale.Y); if ((renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) { R_ProjectWallSprite(thing, fx, fy, fz, picnum, spritescaleX, spritescaleY, renderflags); @@ -917,10 +917,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } else { - xscale = FixedMul(spritescaleX, voxel->Scale); - yscale = FixedMul(spritescaleY, voxel->Scale); - gzt = fz + MulScale8(yscale, voxel->Voxel->Mips[0].PivotZ) - thing->floorclip; - gzb = fz + MulScale8(yscale, voxel->Voxel->Mips[0].PivotZ - (voxel->Voxel->Mips[0].SizeZ << 8)); + xscale = fixed_t(spritescaleX * voxel->Scale); + yscale = fixed_t(spritescaleY * voxel->Scale); + fixed_t piv = fixed_t(voxel->Voxel->Mips[0].Pivot.Z*256.); + gzt = fz + MulScale8(yscale, piv) - FLOAT2FIXED(thing->Floorclip); + gzb = fz + MulScale8(yscale, piv - (voxel->Voxel->Mips[0].SizeZ << 8)); if (gzt <= gzb) return; } @@ -935,19 +936,19 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor { if (fakeside == FAKED_AboveCeiling) { - if (gzt < heightsec->ceilingplane.ZatPoint (fx, fy)) + if (gzt < heightsec->ceilingplane.ZatPointFixed(pos)) return; } else if (fakeside == FAKED_BelowFloor) { - if (gzb >= heightsec->floorplane.ZatPoint (fx, fy)) + if (gzb >= heightsec->floorplane.ZatPointFixed(pos)) return; } else { - if (gzt < heightsec->floorplane.ZatPoint (fx, fy)) + if (gzt < heightsec->floorplane.ZatPointFixed(pos)) return; - if (!(heightsec->MoreFlags & SECF_FAKEFLOORONLY) && gzb >= heightsec->ceilingplane.ZatPoint (fx, fy)) + if (!(heightsec->MoreFlags & SECF_FAKEFLOORONLY) && gzb >= heightsec->ceilingplane.ZatPointFixed(pos)) return; } } @@ -967,7 +968,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor renderflags ^= MirrorFlags & RF_XFLIP; // calculate edges of the shape - const fixed_t thingxscalemul = DivScale16(spritescaleX, tex->xScale); + const fixed_t thingxscalemul = fixed_t(spritescaleX / tex->Scale.X); tx -= ((renderflags & RF_XFLIP) ? (tex->GetWidth() - tex->LeftOffset - 1) : tex->LeftOffset) * thingxscalemul; x1 = centerx + MulScale32 (tx, xscale); @@ -983,10 +984,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor if ((x2 < WindowLeft || x2 <= x1)) return; - xscale = FixedDiv(FixedMul(spritescaleX, xscale), tex->xScale); + xscale = fixed_t(FixedMul(spritescaleX, xscale) / tex->Scale.X); iscale = (tex->GetWidth() << FRACBITS) / (x2 - x1); - fixed_t yscale = SafeDivScale16(spritescaleY, tex->yScale); + fixed_t yscale = fixed_t(spritescaleY / tex->Scale.Y); // store information in a vissprite vis = R_NewVisSprite(); @@ -995,11 +996,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->xscale = xscale; vis->yscale = Scale(InvZtoScale, yscale, tz << 4); vis->idepth = (unsigned)DivScale32(1, tz) >> 1; // tz is 20.12, so idepth ought to be 12.20, but signed math makes it 13.19 - vis->floorclip = FixedDiv (thing->floorclip, yscale); - vis->texturemid = (tex->TopOffset << FRACBITS) - FixedDiv (viewz - fz + thing->floorclip, yscale); + vis->floorclip = FixedDiv (FLOAT2FIXED(thing->Floorclip), yscale); + vis->texturemid = (tex->TopOffset << FRACBITS) - FixedDiv (viewz - fz + FLOAT2FIXED(thing->Floorclip), yscale); vis->x1 = x1 < WindowLeft ? WindowLeft : x1; vis->x2 = x2 > WindowRight ? WindowRight : x2; - vis->angle = thing->angle; + vis->angle = thing->Angles.Yaw.BAMs(); if (renderflags & RF_XFLIP) { @@ -1025,17 +1026,17 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->x1 = WindowLeft; vis->x2 = WindowRight; vis->idepth = (unsigned)DivScale32(1, MAX(tz, MINZ)) >> 1; - vis->floorclip = thing->floorclip; + vis->floorclip = FLOAT2FIXED(thing->Floorclip); - fz -= thing->floorclip; + fz -= FLOAT2FIXED(thing->Floorclip); - vis->angle = thing->angle + voxel->AngleOffset; + vis->angle = thing->Angles.Yaw.BAMs() + voxel->AngleOffset.BAMs(); int voxelspin = (thing->flags & MF_DROPPED) ? voxel->DroppedSpin : voxel->PlacedSpin; if (voxelspin != 0) { - double ang = double(I_FPSTime()) * voxelspin / 1000; - vis->angle -= FLOAT2ANGLE(ang); + DAngle ang = double(I_FPSTime()) * voxelspin / 1000; + vis->angle -= ang.BAMs(); } vis->vx = viewx; @@ -1062,7 +1063,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->FillColor = thing->fillcolor; vis->Translation = thing->Translation; // [RH] thing translation table vis->FakeFlatStat = fakeside; - vis->Style.alpha = thing->alpha; + vis->Style.Alpha = float(thing->Alpha); vis->fakefloor = fakefloor; vis->fakeceiling = fakeceiling; vis->ColormapNum = 0; @@ -1149,7 +1150,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f fixed_t lx1, lx2, ly1, ly2; fixed_t gzb, gzt, tz; FTexture *pic = TexMan(picnum, true); - angle_t ang = (thing->angle + ANGLE_90) >> ANGLETOFINESHIFT; + angle_t ang = (thing->Angles.Yaw.BAMs() + ANGLE_90) >> ANGLETOFINESHIFT; vissprite_t *vis; // Determine left and right edges of sprite. The sprite's angle is its normal, @@ -1203,7 +1204,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f vis->FillColor = thing->fillcolor; vis->Translation = thing->Translation; vis->FakeFlatStat = 0; - vis->Style.alpha = thing->alpha; + vis->Style.Alpha = float(thing->Alpha); vis->fakefloor = NULL; vis->fakeceiling = NULL; vis->ColormapNum = 0; @@ -1252,14 +1253,14 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) if(!(rover->flags & FF_SOLID) || rover->alpha != 255) continue; if(!fakefloor) { - if(!(rover->top.plane->a) && !(rover->top.plane->b)) + if(!rover->top.plane->isSlope()) { - if(rover->top.plane->Zat0() <= thing->Z()) fakefloor = rover; + if(rover->top.plane->ZatPoint(0., 0.) <= thing->Z()) fakefloor = rover; } } - if(!(rover->bottom.plane->a) && !(rover->bottom.plane->b)) + if(!rover->bottom.plane->isSlope()) { - if(rover->bottom.plane->Zat0() >= thing->Top()) fakeceiling = rover; + if(rover->bottom.plane->ZatPoint(0., 0.) >= thing->Top()) fakeceiling = rover; } } R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling); @@ -1333,7 +1334,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ vis->floorclip = 0; - vis->texturemid = MulScale16((BASEYCENTER<yScale) + (tex->TopOffset << FRACBITS); + vis->texturemid = int(((BASEYCENTER<Scale.Y) + (tex->TopOffset << FRACBITS); if (camera->player && (RenderTarget != screen || @@ -1349,12 +1350,11 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ { if (RenderTarget != screen || viewheight == RenderTarget->GetHeight()) { - vis->texturemid -= weapon->YAdjust; + vis->texturemid -= FLOAT2FIXED(weapon->YAdjust); } else { - vis->texturemid -= FixedMul (StatusBar->GetDisplacement (), - weapon->YAdjust); + vis->texturemid -= FLOAT2FIXED(StatusBar->GetDisplacement () * weapon->YAdjust); } } } @@ -1364,20 +1364,20 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ } vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth : x2; - vis->xscale = DivScale16(pspritexscale, tex->xScale); - vis->yscale = DivScale16(pspriteyscale, tex->yScale); + vis->xscale = fixed_t(pspritexscale / tex->Scale.X); + vis->yscale = fixed_t(pspriteyscale / tex->Scale.Y); vis->Translation = 0; // [RH] Use default colors vis->pic = tex; vis->ColormapNum = 0; if (flip) { - vis->xiscale = -MulScale16(pspritexiscale, tex->xScale); + vis->xiscale = -int(pspritexiscale * tex->Scale.X); vis->startfrac = (tex->GetWidth() << FRACBITS) - 1; } else { - vis->xiscale = MulScale16(pspritexiscale, tex->xScale); + vis->xiscale = int(pspritexiscale * tex->Scale.X); vis->startfrac = 0; } @@ -1387,7 +1387,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ noaccel = false; if (pspnum <= ps_flash) { - vis->Style.alpha = owner->alpha; + vis->Style.Alpha = float(owner->Alpha); vis->Style.RenderStyle = owner->RenderStyle; // The software renderer cannot invert the source without inverting the overlay @@ -1574,7 +1574,7 @@ void R_DrawPlayerSprites () if (camera->player != NULL) { fixed_t centerhack = centeryfrac; - fixed_t ofsx, ofsy; + float ofsx, ofsy; centery = viewheight >> 1; centeryfrac = centery << FRACBITS; @@ -1589,7 +1589,7 @@ void R_DrawPlayerSprites () // [RH] Don't draw the targeter's crosshair if the player already has a crosshair set. if (psp->state && (i != ps_targetcenter || CrosshairImage == NULL)) { - R_DrawPSprite (psp, i, camera, psp->sx + ofsx, psp->sy + ofsy); + R_DrawPSprite (psp, i, camera, FLOAT2FIXED(psp->sx + ofsx), FLOAT2FIXED(psp->sy + ofsy)); } // [RH] Don't bob the targeter. if (i == ps_flash) @@ -1664,7 +1664,7 @@ void R_DrawRemainingPlayerSprites() DTA_ClipTop, viewwindowy, DTA_ClipRight, viewwindowx + viewwidth, DTA_ClipBottom, viewwindowy + viewheight, - DTA_Alpha, vis->Style.alpha, + DTA_AlphaF, vis->Style.Alpha, DTA_RenderStyle, vis->Style.RenderStyle, DTA_FillColor, vis->FillColor, DTA_SpecialColormap, special, @@ -1930,7 +1930,7 @@ void R_DrawSprite (vissprite_t *spr) { if (!(fake3D & FAKE3D_CLIPTOP)) { - sclipTop = spr->sector->ceilingplane.ZatPoint(viewx, viewy); + sclipTop = spr->sector->ceilingplane.ZatPointFixed(viewx, viewy); } sector_t *sec = NULL; for (i = spr->sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) @@ -2030,7 +2030,7 @@ void R_DrawSprite (vissprite_t *spr) { // only things in specially marked sectors if (spr->FakeFlatStat != FAKED_AboveCeiling) { - fixed_t hz = spr->heightsec->floorplane.ZatPoint (spr->gx, spr->gy); + fixed_t hz = spr->heightsec->floorplane.ZatPointFixed(spr->gx, spr->gy); fixed_t h = (centeryfrac - FixedMul (hz-viewz, scale)) >> FRACBITS; if (spr->FakeFlatStat == FAKED_BelowFloor) @@ -2052,7 +2052,7 @@ void R_DrawSprite (vissprite_t *spr) } if (spr->FakeFlatStat != FAKED_BelowFloor && !(spr->heightsec->MoreFlags & SECF_FAKEFLOORONLY)) { - fixed_t hz = spr->heightsec->ceilingplane.ZatPoint (spr->gx, spr->gy); + fixed_t hz = spr->heightsec->ceilingplane.ZatPointFixed(spr->gx, spr->gy); fixed_t h = (centeryfrac - FixedMul (hz-viewz, scale)) >> FRACBITS; if (spr->FakeFlatStat == FAKED_AboveCeiling) @@ -2114,8 +2114,8 @@ void R_DrawSprite (vissprite_t *spr) if (spr->fakeceiling != NULL) { - fixed_t ceilingz = spr->fakeceiling->bottom.plane->Zat0(); - if (viewz < ceilingz && ceilingz == sclipTop) + fixed_t ceilingZ = spr->fakeceiling->bottom.plane->Zat0(); + if (viewz < ceilingZ && ceilingZ == sclipTop) { h = spr->fakeceiling->top.plane->Zat0(); } @@ -2210,8 +2210,8 @@ void R_DrawSprite (vissprite_t *spr) } // Check if sprite is in front of draw seg: if ((!spr->bWallSprite && neardepth > spr->depth) || ((spr->bWallSprite || fardepth > spr->depth) && - DMulScale32(spr->gy - ds->curline->v1->y, ds->curline->v2->x - ds->curline->v1->x, - ds->curline->v1->x - spr->gx, ds->curline->v2->y - ds->curline->v1->y) <= 0)) + DMulScale32(spr->gy - ds->curline->v1->fixY(), ds->curline->v2->fixX() - ds->curline->v1->fixX(), + ds->curline->v1->fixX() - spr->gx, ds->curline->v2->fixY() - ds->curline->v1->fixY()) <= 0)) { // seg is behind sprite, so draw the mid texture if it has one if (ds->CurrentPortalUniq == CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here @@ -2422,12 +2422,12 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, BYTE* map; // [ZZ] Particle not visible through the portal plane - if (CurrentPortal && !!P_PointOnLineSide(particle->x, particle->y, CurrentPortal->dst)) + if (CurrentPortal && !!P_PointOnLineSide(particle->Pos, CurrentPortal->dst)) return; // transform the origin point - tr_x = particle->x - viewx; - tr_y = particle->y - viewy; + tr_x = FLOAT2FIXED(particle->Pos.X - ViewPos.X); + tr_y = FLOAT2FIXED(particle->Pos.Y - ViewPos.Y); tz = DMulScale20 (tr_x, viewtancos, tr_y, viewtansin); @@ -2459,8 +2459,8 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, if (x1 >= x2) return; - yscale = MulScale16 (yaspectmul, xscale); - ty = particle->z - viewz; + yscale = MulScale16(yaspectmul, xscale); + ty = FLOAT2FIXED(particle->Pos.Z - ViewPos.Z); psize <<= 4; y1 = (centeryfrac - FixedMul (ty+psize, yscale)) >> FRACBITS; y2 = (centeryfrac - FixedMul (ty-psize, yscale)) >> FRACBITS; @@ -2521,9 +2521,9 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, map = sector->ColorMap->Maps; } - if (botpic != skyflatnum && particle->z < botplane->ZatPoint (particle->x, particle->y)) + if (botpic != skyflatnum && particle->Pos.Z < botplane->ZatPoint (particle->Pos)) return; - if (toppic != skyflatnum && particle->z >= topplane->ZatPoint (particle->x, particle->y)) + if (toppic != skyflatnum && particle->Pos.Z >= topplane->ZatPoint (particle->Pos)) return; // store information in a vissprite @@ -2535,9 +2535,9 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, vis->yscale = xscale; vis->depth = tz; vis->idepth = (DWORD)DivScale32 (1, tz) >> 1; - vis->gx = particle->x; - vis->gy = particle->y; - vis->gz = particle->z; // kg3D + vis->gx = FLOAT2FIXED(particle->Pos.X); + vis->gy = FLOAT2FIXED(particle->Pos.Y); + vis->gz = FLOAT2FIXED(particle->Pos.Z); vis->gzb = y1; vis->gzt = y2; vis->x1 = x1; @@ -2728,18 +2728,22 @@ void R_DrawVoxel(fixed_t globalposx, fixed_t globalposy, fixed_t globalposz, ang daxscalerecip = (1<<30) / daxscale; dayscalerecip = (1<<30) / dayscale; + fixed_t piv_x = fixed_t(mip->Pivot.X*256.); + fixed_t piv_y = fixed_t(mip->Pivot.Y*256.); + fixed_t piv_z = fixed_t(mip->Pivot.Z*256.); + x = FixedMul(globalposx - dasprx, daxscalerecip); y = FixedMul(globalposy - daspry, daxscalerecip); - backx = (DMulScale10(x, sprcosang, y, sprsinang) + mip->PivotX) >> 8; - backy = (DMulScale10(y, sprcosang, x, -sprsinang) + mip->PivotY) >> 8; + backx = (DMulScale10(x, sprcosang, y, sprsinang) + piv_x) >> 8; + backy = (DMulScale10(y, sprcosang, x, -sprsinang) + piv_y) >> 8; cbackx = clamp(backx, 0, mip->SizeX - 1); cbacky = clamp(backy, 0, mip->SizeY - 1); sprcosang = MulScale14(daxscale, sprcosang); sprsinang = MulScale14(daxscale, sprsinang); - x = (dasprx - globalposx) - DMulScale18(mip->PivotX, sprcosang, mip->PivotY, -sprsinang); - y = (daspry - globalposy) - DMulScale18(mip->PivotY, sprcosang, mip->PivotX, sprsinang); + x = (dasprx - globalposx) - DMulScale18(piv_x, sprcosang, piv_y, -sprsinang); + y = (daspry - globalposy) - DMulScale18(piv_y, sprcosang, piv_x, sprsinang); cosang = FixedMul(cosang, dayscalerecip); sinang = FixedMul(sinang, dayscalerecip); @@ -2759,7 +2763,7 @@ void R_DrawVoxel(fixed_t globalposx, fixed_t globalposy, fixed_t globalposz, ang ggyinc[i] = y; y += gyinc; } - syoff = DivScale21(globalposz - dasprz, FixedMul(dazscale, 0xE800)) + (mip->PivotZ << 7); + syoff = DivScale21(globalposz - dasprz, FixedMul(dazscale, 0xE800)) + (piv_z << 7); yoff = (abs(gxinc) + abs(gyinc)) >> 1; for (cnt = 0; cnt < 8; cnt++) diff --git a/src/r_utility.cpp b/src/r_utility.cpp index a5a422426..94c2b0c00 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -57,6 +57,8 @@ #include "r_utility.h" #include "d_player.h" #include "p_local.h" +#include "p_maputl.h" +#include "math/cmath.h" // EXTERNAL DATA DECLARATIONS ---------------------------------------------- @@ -68,12 +70,15 @@ EXTERN_CVAR (Bool, cl_capfps) struct InterpolationViewer { + struct instance + { + DVector3 Pos; + DRotator Angles; + }; + AActor *ViewActor; int otic; - fixed_t oviewx, oviewy, oviewz; - fixed_t nviewx, nviewy, nviewz; - int oviewpitch, nviewpitch; - angle_t oviewangle, nviewangle; + instance Old, New; }; // PRIVATE DATA DECLARATIONS ----------------------------------------------- @@ -81,7 +86,7 @@ static TArray PastViewers; static FRandom pr_torchflicker ("TorchFlicker"); static FRandom pr_hom; static bool NoInterpolateView; -static TArray InterpolationPath; +static TArray InterpolationPath; // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -100,10 +105,9 @@ DCanvas *RenderTarget; // [RH] canvas to render to int viewwindowx; int viewwindowy; -fixed_t viewx; -fixed_t viewy; -fixed_t viewz; -int viewpitch; +DVector3 ViewPos; +DAngle ViewAngle; +DAngle ViewPitch; extern "C" { @@ -116,7 +120,6 @@ extern "C" int otic; -angle_t viewangle; sector_t *viewsector; fixed_t viewcos, viewtancos; @@ -124,7 +127,7 @@ fixed_t viewsin, viewtansin; AActor *camera; // [RH] camera to draw from. doesn't have to be a player -fixed_t r_TicFrac; // [RH] Fractional tic to render +double r_TicFracF; // same as floating point DWORD r_FrameTime; // [RH] Time this frame started drawing (in ms) bool r_NoInterpolate; bool r_showviewer; @@ -146,6 +149,10 @@ int FieldOfView = 2048; // Fineangles in the SCREENWIDTH wide window FCanvasTextureInfo *FCanvasTextureInfo::List; +fixed_t viewx, viewy, viewz; +angle_t viewangle; +int viewpitch; + // CODE -------------------------------------------------------------------- static void R_Shutdown (); @@ -254,7 +261,7 @@ angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x, fixed_t y) else { // we have to use the slower but more precise floating point atan2 function here. - return xs_RoundToUInt(atan2(double(y), double(x)) * (ANGLE_180/M_PI)); + return xs_RoundToUInt(g_atan2(double(y), double(x)) * (ANGLE_180/M_PI)); } } @@ -273,7 +280,7 @@ void R_InitPointToAngle (void) // for (i = 0; i <= SLOPERANGE; i++) { - f = atan2 ((double)i, (double)SLOPERANGE) / (6.28318530718 /* 2*pi */); + f = g_atan2 ((double)i, (double)SLOPERANGE) / (6.28318530718 /* 2*pi */); tantoangle[i] = (angle_t)(0xffffffff*f); } } @@ -322,16 +329,16 @@ void R_InitTables (void) const double pimul = PI*2/FINEANGLES; // viewangle tangent table - finetangent[0] = (fixed_t)(FRACUNIT*tan ((0.5-FINEANGLES/4)*pimul)+0.5); + finetangent[0] = (fixed_t)(FRACUNIT*g_tan ((0.5-FINEANGLES/4)*pimul)+0.5); for (i = 1; i < FINEANGLES/2; i++) { - finetangent[i] = (fixed_t)(FRACUNIT*tan ((i-FINEANGLES/4)*pimul)+0.5); + finetangent[i] = (fixed_t)(FRACUNIT*g_tan ((i-FINEANGLES/4)*pimul)+0.5); } // finesine table for (i = 0; i < FINEANGLES/4; i++) { - finesine[i] = (fixed_t)(FRACUNIT * sin (i*pimul)); + finesine[i] = (fixed_t)(FRACUNIT * g_sin (i*pimul)); } for (i = 0; i < FINEANGLES/4; i++) { @@ -570,29 +577,22 @@ static void R_Shutdown () //CVAR (Int, tf, 0, 0) EXTERN_CVAR (Bool, cl_noprediction) -void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *iview) +void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *iview) { -// frac = tf; if (NoInterpolateView) { InterpolationPath.Clear(); NoInterpolateView = false; - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; + iview->Old = iview->New; } - int oldgroup = R_PointInSubsector(iview->oviewx, iview->oviewy)->sector->PortalGroup; - int newgroup = R_PointInSubsector(iview->nviewx, iview->nviewy)->sector->PortalGroup; + int oldgroup = R_PointInSubsector(iview->Old.Pos)->sector->PortalGroup; + int newgroup = R_PointInSubsector(iview->New.Pos)->sector->PortalGroup; - fixed_t oviewangle = iview->oviewangle; - fixed_t nviewangle = iview->nviewangle; - if ((iview->oviewx != iview->nviewx || iview->oviewy != iview->nviewy) && InterpolationPath.Size() > 0) + DAngle oviewangle = iview->Old.Angles.Yaw; + DAngle nviewangle = iview->New.Angles.Yaw; + if ((iview->Old.Pos.X != iview->New.Pos.X || iview->Old.Pos.Y != iview->New.Pos.Y) && InterpolationPath.Size() > 0) { - viewx = iview->nviewx; - viewy = iview->nviewy; - viewz = iview->nviewz; + DVector3 view = iview->New.Pos; // Interpolating through line portals is a messy affair. // What needs be done is to store the portal transitions of the camera actor as waypoints @@ -600,33 +600,33 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi // Needless to say, this doesn't work for chasecam mode. if (!r_showviewer) { - fixed_t pathlen = 0; - fixed_t zdiff = 0; - fixed_t totalzdiff = 0; - angle_t adiff = 0; - angle_t totaladiff = 0; - fixed_t oviewz = iview->oviewz; - fixed_t nviewz = iview->nviewz; - fixedvec3a oldpos = { iview->oviewx, iview->oviewy, 0, 0 }; - fixedvec3a newpos = { iview->nviewx, iview->nviewy, 0, 0 }; + double pathlen = 0; + double zdiff = 0; + double totalzdiff = 0; + DAngle adiff = 0.; + DAngle totaladiff = 0.; + double oviewz = iview->Old.Pos.Z; + double nviewz = iview->New.Pos.Z; + DVector3a oldpos = { { iview->Old.Pos.X, iview->Old.Pos.Y, 0 }, 0. }; + DVector3a newpos = { { iview->New.Pos.X, iview->New.Pos.Y, 0 }, 0. }; InterpolationPath.Push(newpos); // add this to the array to simplify the loops below for (unsigned i = 0; i < InterpolationPath.Size(); i += 2) { - fixedvec3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; - fixedvec3a &end = InterpolationPath[i]; - pathlen += xs_CRoundToInt(DVector2(end.x - start.x, end.y - start.y).Length()); - totalzdiff += start.z; + DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; + DVector3a &end = InterpolationPath[i]; + pathlen += (end.pos-start.pos).Length(); + totalzdiff += start.pos.Z; totaladiff += start.angle; } - fixed_t interpolatedlen = FixedMul(frac, pathlen); + double interpolatedlen = Frac * pathlen; for (unsigned i = 0; i < InterpolationPath.Size(); i += 2) { - fixedvec3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; - fixedvec3a &end = InterpolationPath[i]; - fixed_t fraglen = xs_CRoundToInt(DVector2(end.x - start.x, end.y - start.y).Length()); - zdiff += start.z; + DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; + DVector3a &end = InterpolationPath[i]; + double fraglen = (end.pos - start.pos).Length(); + zdiff += start.pos.Z; adiff += start.angle; if (fraglen <= interpolatedlen) { @@ -634,14 +634,13 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi } else { - fixed_t fragfrac = FixedDiv(interpolatedlen, fraglen); + double fragfrac = interpolatedlen / fraglen; oviewz += zdiff; nviewz -= totalzdiff - zdiff; oviewangle += adiff; nviewangle -= totaladiff - adiff; - viewx = start.x + FixedMul(fragfrac, end.x - start.x); - viewy = start.y + FixedMul(fragfrac, end.y - start.y); - viewz = oviewz + FixedMul(frac, nviewz - oviewz); + DVector2 viewpos = start.pos + (fragfrac * (end.pos - start.pos)); + ViewPos = { viewpos, oviewz + Frac * (nviewz - oviewz) }; break; } } @@ -650,18 +649,16 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi } else { - fixedvec2 disp = Displacements.getOffset(oldgroup, newgroup); - viewx = iview->oviewx + FixedMul(frac, iview->nviewx - iview->oviewx - disp.x); - viewy = iview->oviewy + FixedMul(frac, iview->nviewy - iview->oviewy - disp.y); - viewz = iview->oviewz + FixedMul(frac, iview->nviewz - iview->oviewz); + DVector2 disp = Displacements.getOffset(oldgroup, newgroup); + ViewPos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac; } if (player != NULL && !(player->cheats & CF_INTERPVIEW) && player - players == consoleplayer && camera == player->mo && !demoplayback && - iview->nviewx == camera->X() && - iview->nviewy == camera->Y() && + iview->New.Pos.X == camera->X() && + iview->New.Pos.Y == camera->Y() && !(player->cheats & (CF_TOTALLYFROZEN|CF_FROZEN)) && player->playerstate == PST_LIVE && player->mo->reactiontime == 0 && @@ -670,53 +667,26 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi (!netgame || !cl_noprediction) && !LocalKeyboardTurner) { - viewangle = nviewangle + (LocalViewAngle & 0xFFFF0000); - - fixed_t delta = player->centering ? 0 : -(signed)(LocalViewPitch & 0xFFFF0000); - - viewpitch = iview->nviewpitch; - if (delta > 0) - { - // Avoid overflowing viewpitch (can happen when a netgame is stalled) - if (viewpitch > INT_MAX - delta) - { - viewpitch = player->MaxPitch; - } - else - { - viewpitch = MIN(viewpitch + delta, player->MaxPitch); - } - } - else if (delta < 0) - { - // Avoid overflowing viewpitch (can happen when a netgame is stalled) - if (viewpitch < INT_MIN - delta) - { - viewpitch = player->MinPitch; - } - else - { - viewpitch = MAX(viewpitch + delta, player->MinPitch); - } - } + ViewAngle = (nviewangle + AngleToFloat(LocalViewAngle & 0xFFFF0000)).Normalized180(); + DAngle delta = player->centering ? DAngle(0.) : AngleToFloat(int(LocalViewPitch & 0xFFFF0000)); + ViewPitch = clamp((iview->New.Angles.Pitch - delta).Normalized180(), player->MinPitch, player->MaxPitch); } else { - viewpitch = iview->oviewpitch + FixedMul (frac, iview->nviewpitch - iview->oviewpitch); - viewangle = oviewangle + FixedMul (frac, nviewangle - oviewangle); + ViewPitch = (iview->Old.Angles.Pitch + deltaangle(iview->Old.Angles.Pitch, iview->New.Angles.Pitch) * Frac).Normalized180(); + ViewAngle = (oviewangle + deltaangle(oviewangle, nviewangle) * Frac).Normalized180(); } // Due to interpolation this is not necessarily the same as the sector the camera is in. - viewsector = R_PointInSubsector(viewx, viewy)->sector; + viewsector = R_PointInSubsector(ViewPos)->sector; bool moved = false; while (!viewsector->PortalBlocksMovement(sector_t::ceiling)) { AActor *point = viewsector->SkyBoxes[sector_t::ceiling]; - if (viewz > point->threshold) + if (ViewPos.Z > point->specialf1) { - viewx += point->scaleX; - viewy += point->scaleY; - viewsector = R_PointInSubsector(viewx, viewy)->sector; + ViewPos += point->Scale; + viewsector = R_PointInSubsector(ViewPos)->sector; moved = true; } else break; @@ -726,11 +696,10 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi while (!viewsector->PortalBlocksMovement(sector_t::floor)) { AActor *point = viewsector->SkyBoxes[sector_t::floor]; - if (viewz < point->threshold) + if (ViewPos.Z < point->specialf1) { - viewx += point->scaleX; - viewy += point->scaleY; - viewsector = R_PointInSubsector(viewx, viewy)->sector; + ViewPos += point->Scale; + viewsector = R_PointInSubsector(ViewPos)->sector; moved = true; } else break; @@ -758,10 +727,8 @@ void R_ResetViewInterpolation () void R_SetViewAngle () { - angle_t ang = viewangle >> ANGLETOFINESHIFT; - - viewsin = finesine[ang]; - viewcos = finecosine[ang]; + viewsin = FLOAT2FIXED(ViewAngle.Sin()); + viewcos = FLOAT2FIXED(ViewAngle.Cos()); viewtansin = FixedMul (FocalTangent, viewsin); viewtancos = FixedMul (FocalTangent, viewcos); @@ -784,7 +751,8 @@ static InterpolationViewer *FindPastViewer (AActor *actor) } // Not found, so make a new one - InterpolationViewer iview = { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + InterpolationViewer iview; + memset(&iview, 0, sizeof(iview)); iview.ViewActor = actor; iview.otic = -1; InterpolationPath.Clear(); @@ -848,11 +816,7 @@ void R_RebuildViewInterpolation(player_t *player) InterpolationViewer *iview = FindPastViewer(player->camera); - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; + iview->Old = iview->New; InterpolationPath.Clear(); } @@ -885,7 +849,7 @@ void R_ClearInterpolationPath() // //========================================================================== -void R_AddInterpolationPoint(const fixedvec3a &vec) +void R_AddInterpolationPoint(const DVector3a &vec) { InterpolationPath.Push(vec); } @@ -896,19 +860,18 @@ void R_AddInterpolationPoint(const fixedvec3a &vec) // //========================================================================== -static fixed_t QuakePower(fixed_t factor, fixed_t intensity, fixed_t offset, fixed_t falloff, fixed_t wfalloff) +static double QuakePower(double factor, double intensity, double offset, double falloff, double wfalloff) { - fixed_t randumb; + double randumb; if (intensity == 0) { randumb = 0; } else { - randumb = pr_torchflicker(intensity * 2) - intensity; + randumb = pr_torchflicker.GenRand_Real2() * (intensity * 2) - intensity; } - fixed_t rn2 = (FixedMul(wfalloff,offset) + FixedMul(falloff, randumb)); - return FixedMul(factor, rn2); + return factor * (wfalloff * offset + falloff * randumb); } //========================================================================== @@ -953,130 +916,113 @@ void R_SetupFrame (AActor *actor) if (iview->otic != -1 && nowtic > iview->otic) { iview->otic = nowtic; - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; + iview->Old = iview->New; } if (player != NULL && gamestate != GS_TITLELEVEL && ((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0))) { - sector_t *oldsector = R_PointInSubsector(iview->oviewx, iview->oviewy)->sector; + sector_t *oldsector = R_PointInSubsector(iview->Old.Pos)->sector; // [RH] Use chasecam view - P_AimCamera (camera, iview->nviewx, iview->nviewy, iview->nviewz, viewsector, unlinked); + DVector3 campos; + P_AimCamera (camera, campos, viewsector, unlinked); // fixme: This needs to translate the angle, too. + iview->New.Pos = campos; r_showviewer = true; // Interpolating this is a very complicated thing because nothing keeps track of the aim camera's movement, so whenever we detect a portal transition // it's probably best to just reset the interpolation for this move. // Note that this can still cause problems with unusually linked portals - if (viewsector->PortalGroup != oldsector->PortalGroup || (unlinked && P_AproxDistance(iview->oviewx - iview->nviewx, iview->oviewy - iview->nviewy) > 256 * FRACUNIT)) + if (viewsector->PortalGroup != oldsector->PortalGroup || (unlinked && ((iview->New.Pos.XY() - iview->Old.Pos.XY()).LengthSquared()) > 256*256)) { iview->otic = nowtic; - iview->oviewx = iview->nviewx; - iview->oviewy = iview->nviewy; - iview->oviewz = iview->nviewz; - iview->oviewpitch = iview->nviewpitch; - iview->oviewangle = iview->nviewangle; + iview->Old = iview->New; } } else { - iview->nviewx = camera->X(); - iview->nviewy = camera->Y(); - iview->nviewz = camera->player ? camera->player->viewz : camera->Z() + camera->GetCameraHeight(); + iview->New.Pos = { camera->Pos().XY(), camera->player ? camera->player->viewz : camera->Z() + camera->GetCameraHeight() }; viewsector = camera->Sector; r_showviewer = false; } - iview->nviewpitch = camera->pitch; + iview->New.Angles = camera->Angles; if (camera->player != 0) { player = camera->player; } - iview->nviewangle = camera->angle; if (iview->otic == -1 || r_NoInterpolate) { R_ResetViewInterpolation (); iview->otic = nowtic; } - r_TicFrac = I_GetTimeFrac (&r_FrameTime); + r_TicFracF = I_GetTimeFrac (&r_FrameTime); if (cl_capfps || r_NoInterpolate) { - r_TicFrac = FRACUNIT; + r_TicFracF = 1.; } - - R_InterpolateView (player, r_TicFrac, iview); - -#ifdef TEST_X - viewx = TEST_X; - viewy = TEST_Y; - viewz = TEST_Z; - viewangle = TEST_ANGLE; -#endif + R_InterpolateView (player, r_TicFracF, iview); R_SetViewAngle (); - interpolator.DoInterpolations (r_TicFrac); + interpolator.DoInterpolations (r_TicFracF); // Keep the view within the sector's floor and ceiling if (viewsector->PortalBlocksMovement(sector_t::ceiling)) { - fixed_t theZ = viewsector->ceilingplane.ZatPoint(viewx, viewy) - 4 * FRACUNIT; - if (viewz > theZ) + double theZ = viewsector->ceilingplane.ZatPoint(ViewPos) - 4; + if (ViewPos.Z > theZ) { - viewz = theZ; + ViewPos.Z = theZ; } } if (viewsector->PortalBlocksMovement(sector_t::floor)) { - fixed_t theZ = viewsector->floorplane.ZatPoint(viewx, viewy) + 4 * FRACUNIT; - if (viewz < theZ) + double theZ = viewsector->floorplane.ZatPoint(ViewPos) + 4; + if (ViewPos.Z < theZ) { - viewz = theZ; + ViewPos.Z = theZ; } } if (!paused) { - FQuakeJiggers jiggers = { 0, }; + FQuakeJiggers jiggers; + memset(&jiggers, 0, sizeof(jiggers)); if (DEarthquake::StaticGetQuakeIntensities(camera, jiggers) > 0) { - fixed_t quakefactor = FLOAT2FIXED(r_quakeintensity); + double quakefactor = r_quakeintensity; + DAngle an; - if ((jiggers.RelIntensityX | jiggers.RelOffsetX) != 0) + if (jiggers.RelIntensity.X != 0 || jiggers.RelOffset.X != 0) { - int ang = (camera->angle) >> ANGLETOFINESHIFT; - fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityX, jiggers.RelOffsetX, jiggers.Falloff, jiggers.WFalloff); - viewx += FixedMul(finecosine[ang], power); - viewy += FixedMul(finesine[ang], power); + an = camera->Angles.Yaw; + double power = QuakePower(quakefactor, jiggers.RelIntensity.X, jiggers.RelOffset.X, jiggers.Falloff, jiggers.WFalloff); + ViewPos += an.ToVector(power); } - if ((jiggers.RelIntensityY | jiggers.RelOffsetY) != 0) + if (jiggers.RelIntensity.Y != 0 || jiggers.RelOffset.Y != 0) { - int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT; - fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityY, jiggers.RelOffsetY, jiggers.Falloff, jiggers.WFalloff); - viewx += FixedMul(finecosine[ang], power); - viewy += FixedMul(finesine[ang], power); + an = camera->Angles.Yaw + 90; + double power = QuakePower(quakefactor, jiggers.RelIntensity.Y, jiggers.RelOffset.Y, jiggers.Falloff, jiggers.WFalloff); + ViewPos += an.ToVector(power); } // FIXME: Relative Z is not relative - if ((jiggers.RelIntensityZ | jiggers.RelOffsetZ) != 0) + if (jiggers.RelIntensity.Z != 0 || jiggers.RelOffset.Z != 0) { - viewz += QuakePower(quakefactor, jiggers.RelIntensityZ, jiggers.RelOffsetZ, jiggers.Falloff, jiggers.WFalloff); + ViewPos.Z += QuakePower(quakefactor, jiggers.RelIntensity.Z, jiggers.RelOffset.Z, jiggers.Falloff, jiggers.WFalloff); } - if ((jiggers.IntensityX | jiggers.OffsetX) != 0) + if (jiggers.Intensity.X != 0 || jiggers.Offset.X != 0) { - viewx += QuakePower(quakefactor, jiggers.IntensityX, jiggers.OffsetX, jiggers.Falloff, jiggers.WFalloff); + ViewPos.X += QuakePower(quakefactor, jiggers.Intensity.X, jiggers.Offset.X, jiggers.Falloff, jiggers.WFalloff); } - if ((jiggers.IntensityY | jiggers.OffsetY) != 0) + if (jiggers.Intensity.Y != 0 || jiggers.Offset.Y != 0) { - viewy += QuakePower(quakefactor, jiggers.IntensityY, jiggers.OffsetY, jiggers.Falloff, jiggers.WFalloff); + ViewPos.Y += QuakePower(quakefactor, jiggers.Intensity.Y, jiggers.Offset.Y, jiggers.Falloff, jiggers.WFalloff); } - if ((jiggers.IntensityZ | jiggers.OffsetZ) != 0) + if (jiggers.Intensity.Z != 0 || jiggers.Offset.Z != 0) { - viewz += QuakePower(quakefactor, jiggers.IntensityZ, jiggers.OffsetZ, jiggers.Falloff, jiggers.WFalloff); + ViewPos.Z += QuakePower(quakefactor, jiggers.Intensity.Z, jiggers.Offset.Z, jiggers.Falloff, jiggers.WFalloff); } } } @@ -1095,10 +1041,10 @@ void R_SetupFrame (AActor *actor) secplane_t *plane; int viewside; plane = (i < lightlist.Size()-1) ? &lightlist[i+1].plane : &viewsector->floorplane; - viewside = plane->PointOnSide(viewx, viewy, viewz); + viewside = plane->PointOnSide(ViewPos); // Reverse the direction of the test if the plane was downward facing. // We want to know if the view is above it, whatever its orientation may be. - if (plane->c < 0) + if (plane->fC() < 0) viewside = -viewside; if (viewside > 0) { @@ -1117,9 +1063,9 @@ void R_SetupFrame (AActor *actor) const sector_t *s = viewsector->GetHeightSec(); if (s != NULL) { - newblend = s->floorplane.PointOnSide(viewx, viewy, viewz) < 0 + newblend = s->floorplane.PointOnSide(ViewPos) < 0 ? s->bottommap - : s->ceilingplane.PointOnSide(viewx, viewy, viewz) < 0 + : s->ceilingplane.PointOnSide(ViewPos) < 0 ? s->topmap : s->midmap; if (APART(newblend) == 0 && newblend >= numfakecmaps) @@ -1149,6 +1095,12 @@ void R_SetupFrame (AActor *actor) } } + viewx = FLOAT2FIXED(ViewPos.X); + viewy = FLOAT2FIXED(ViewPos.Y); + viewz = FLOAT2FIXED(ViewPos.Z); + viewangle = ViewAngle.BAMs(); + viewpitch = ViewPitch.BAMs(); + Renderer->CopyStackedViewParameters(); Renderer->SetupFrame(player); diff --git a/src/r_utility.h b/src/r_utility.h index 5c953c7ab..9e2ccf3cf 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -2,6 +2,7 @@ #define __R_UTIL_H #include "r_state.h" +#include "vectors.h" // // Stuff from r_main.h that's needed outside the rendering code. @@ -11,10 +12,13 @@ extern DCanvas *RenderTarget; -extern fixed_t viewx; -extern fixed_t viewy; -extern fixed_t viewz; -extern int viewpitch; +extern DVector3 ViewPos; +extern DAngle ViewAngle; +extern DAngle ViewPitch; + +extern fixed_t viewx, viewy, viewz; +extern angle_t viewangle; +extern int viewpitch; extern "C" int centerx, centerxwide; extern "C" int centery; @@ -33,7 +37,7 @@ extern int LocalViewPitch; // [RH] Used directly instead of consoleplayer's extern bool LocalKeyboardTurner; // [RH] The local player used the keyboard to turn, so interpolate extern int WidescreenRatio; -extern fixed_t r_TicFrac; +extern double r_TicFracF; extern DWORD r_FrameTime; extern int extralight; extern unsigned int R_OldBlend; @@ -55,29 +59,40 @@ inline int R_PointOnSide (fixed_t x, fixed_t y, const node_t *node) { return DMulScale32 (y-node->y, node->dx, node->x-x, node->dy) > 0; } +inline int R_PointOnSide(double x, double y, const node_t *node) +{ + return DMulScale32(FLOAT2FIXED(y) - node->y, node->dx, node->x - FLOAT2FIXED(x), node->dy) > 0; +} +inline int R_PointOnSide(const DVector2 &pos, const node_t *node) +{ + return DMulScale32(FLOAT2FIXED(pos.Y) - node->y, node->dx, node->x - FLOAT2FIXED(pos.X), node->dy) > 0; +} angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); -inline angle_t R_PointToAngle (fixed_t x, fixed_t y) { return R_PointToAngle2 (viewx, viewy, x, y); } inline angle_t R_PointToAnglePrecise (fixed_t viewx, fixed_t viewy, fixed_t x, fixed_t y) { - return xs_RoundToUInt(atan2(double(y-viewy), double(x-viewx)) * (ANGLE_180/M_PI)); + return xs_RoundToUInt(g_atan2(double(y-viewy), double(x-viewx)) * (ANGLE_180/M_PI)); } // Used for interpolation waypoints. -struct fixedvec3a +struct DVector3a { - fixed_t x, y, z; - angle_t angle; + DVector3 pos; + DAngle angle; }; subsector_t *R_PointInSubsector (fixed_t x, fixed_t y); +inline subsector_t *R_PointInSubsector(const DVector2 &pos) +{ + return R_PointInSubsector(FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y)); +} fixed_t R_PointToDist2 (fixed_t dx, fixed_t dy); void R_ResetViewInterpolation (); void R_RebuildViewInterpolation(player_t *player); bool R_GetViewInterpolationStatus(); void R_ClearInterpolationPath(); -void R_AddInterpolationPoint(const fixedvec3a &vec); +void R_AddInterpolationPoint(const DVector3a &vec); void R_SetViewSize (int blocks); void R_SetFOV (float fov); float R_GetFOV (); diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 2b1ff7c8b..7995f2655 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -162,8 +162,8 @@ enum SICommands struct FBloodSFX { DWORD RelVol; // volume, 0-255 - fixed_t Pitch; // pitch change - fixed_t PitchRange; // range of random pitch + int Pitch; // pitch change + int PitchRange; // range of random pitch DWORD Format; // format of audio 1=11025 5=22050 SDWORD LoopStart; // loop position (-1 means no looping) char RawName[9]; // name of RAW resource @@ -2281,7 +2281,7 @@ void AAmbientSound::Activate (AActor *activator) Destroy (); return; } - amb->periodmin = Scale(S_GetMSLength(sndnum), TICRATE, 1000); + amb->periodmin = ::Scale(S_GetMSLength(sndnum), TICRATE, 1000); } NextCheck = level.maptime; diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index da1edca5d..06d5883b6 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -34,6 +34,7 @@ #define GetCommand(a) ((a) & 255) #define GetData(a) (SDWORD(a) >> 8 ) +#define GetFloatData(a) float((SDWORD(a) >> 8 )/65536.f) #define MakeCommand(a,b) ((a) | ((b) << 8)) #define HexenPlatSeq(a) (a) #define HexenDoorSeq(a) ((a) | 0x40) @@ -539,7 +540,7 @@ void S_ParseSndSeq (int levellump) int delaybase; float volumebase; int curseq = -1; - fixed_t val; + int val; // First free the old SNDSEQ data. This allows us to reload this for each level // and specify a level specific SNDSEQ lump! @@ -675,18 +676,18 @@ void S_ParseSndSeq (int levellump) case SS_STRING_VOLUME: // volume is in range 0..100 sc.MustGetFloat (); - ScriptTemp.Push(MakeCommand(SS_CMD_VOLUME, int(sc.Float * (FRACUNIT/100.f)))); + ScriptTemp.Push(MakeCommand(SS_CMD_VOLUME, int(sc.Float * (65536.f / 100.f)))); break; case SS_STRING_VOLUMEREL: sc.MustGetFloat (); - ScriptTemp.Push(MakeCommand(SS_CMD_VOLUMEREL, int(sc.Float * (FRACUNIT/100.f)))); + ScriptTemp.Push(MakeCommand(SS_CMD_VOLUMEREL, int(sc.Float * (65536.f / 100.f)))); break; case SS_STRING_VOLUMERAND: sc.MustGetFloat (); volumebase = float(sc.Float); - ScriptTemp.Push(MakeCommand(SS_CMD_VOLUMERAND, int(sc.Float * (FRACUNIT/100.f)))); + ScriptTemp.Push(MakeCommand(SS_CMD_VOLUMERAND, int(sc.Float * (65536.f / 100.f)))); sc.MustGetFloat (); ScriptTemp.Push(int((sc.Float - volumebase) * (256/100.f))); break; @@ -705,12 +706,12 @@ void S_ParseSndSeq (int levellump) case SS_STRING_ATTENUATION: if (sc.CheckFloat()) { - val = FLOAT2FIXED(sc.Float); + val = int(sc.Float*65536.); } else { sc.MustGetString (); - val = sc.MustMatchString(&Attenuations[0].name, sizeof(Attenuations[0])) << FRACBITS; + val = sc.MustMatchString(&Attenuations[0].name, sizeof(Attenuations[0])) * 65536; } ScriptTemp.Push(MakeCommand(SS_CMD_ATTENUATION, val)); break; @@ -1179,19 +1180,19 @@ void DSeqNode::Tick () return; case SS_CMD_VOLUME: - m_Volume = GetData(*m_SequencePtr) / float(FRACUNIT); + m_Volume = GetFloatData(*m_SequencePtr); m_SequencePtr++; break; case SS_CMD_VOLUMEREL: // like SS_CMD_VOLUME, but the new volume is added to the old volume - m_Volume += GetData(*m_SequencePtr) / float(FRACUNIT); + m_Volume += GetFloatData(*m_SequencePtr); m_SequencePtr++; break; case SS_CMD_VOLUMERAND: // like SS_CMD_VOLUME, but the new volume is chosen randomly from a range - m_Volume = GetData(m_SequencePtr[0]) / float(FRACUNIT) + (pr_sndseq() % m_SequencePtr[1]) / 255.f; + m_Volume = GetFloatData(m_SequencePtr[0]) + (pr_sndseq() % m_SequencePtr[1]) / 255.f; m_SequencePtr += 2; break; @@ -1200,7 +1201,7 @@ void DSeqNode::Tick () return; case SS_CMD_ATTENUATION: - m_Atten = FIXED2FLOAT(GetData(*m_SequencePtr)); + m_Atten = GetFloatData(*m_SequencePtr); m_SequencePtr++; break; diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 38a43a430..d1fee071e 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -104,8 +104,8 @@ static void S_ActivatePlayList(bool goBack); static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel); static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, const FPolyObj *poly, const float pt[3], int channel, int chanflags, FVector3 *pos, FVector3 *vel); -static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z); -static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z); +static void CalcSectorSoundOrg(const DVector3 &listenpos, const sector_t *sec, int channum, FVector3 &res); +static void CalcPolyobjSoundOrg(const DVector3 &listenpos, const FPolyObj *poly, FVector3 &res); static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly, const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo *rolloff); static void S_SetListener(SoundListener &listener, AActor *listenactor); @@ -173,9 +173,7 @@ void S_NoiseDebug (void) } - listener.X = FIXED2FLOAT(players[consoleplayer].camera->SoundX()); - listener.Y = FIXED2FLOAT(players[consoleplayer].camera->SoundZ()); - listener.Z = FIXED2FLOAT(players[consoleplayer].camera->SoundY()); + listener = players[consoleplayer].camera->SoundPos(); // Display the oldest channel first. for (chan = Channels; chan->NextChan != NULL; chan = chan->NextChan) @@ -660,26 +658,31 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, { if (pos != NULL) { - fixed_t x, y, z; + DVector3 listenpos; + int pgroup; + AActor *listener = players[consoleplayer].camera; - if (players[consoleplayer].camera != NULL) + if (listener != NULL) { - x = players[consoleplayer].camera->SoundX(); - y = players[consoleplayer].camera->SoundZ(); - z = players[consoleplayer].camera->SoundY(); + listenpos = listener->Pos(); + *pos = listener->SoundPos(); + pgroup = listener->Sector->PortalGroup; } else { - z = y = x = 0; + listenpos.Zero(); + pgroup = 0; } // [BL] Moved this case out of the switch statement to make code easier // on static analysis. if(type == SOURCE_Unattached) - { - pos->X = pt[0]; - pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : FIXED2FLOAT(y); - pos->Z = pt[2]; + { + sector_t *sec = P_PointInSector(pt[0], pt[2]); + DVector2 disp = Displacements.getOffset(pgroup, sec->PortalGroup); + pos->X = pt[0] + (float)disp.X; + pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : (float)listenpos.Z; + pos->Z = pt[2] + (float)disp.Y; } else { @@ -693,9 +696,9 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, //assert(actor != NULL); if (actor != NULL) { - x = actor->SoundX(); - y = actor->SoundZ(); - z = actor->SoundY(); + DVector2 disp = Displacements.getOffset(pgroup, actor->Sector->PortalGroup); + DVector3 posi = actor->Pos() + disp; + *pos = { (float)posi.X, (float)posi.Z, (float)posi.Y }; } break; @@ -703,14 +706,19 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, assert(sector != NULL); if (sector != NULL) { + DVector2 disp = Displacements.getOffset(pgroup, sector->PortalGroup); if (chanflags & CHAN_AREA) { - CalcSectorSoundOrg(sector, channum, &x, &z, &y); + // listener must be reversely offset to calculate the proper sound origin. + CalcSectorSoundOrg(listenpos-disp, sector, channum, *pos); + pos->X += (float)disp.X; + pos->Z += (float)disp.Y; } else { - x = sector->centerspot.x; - z = sector->centerspot.y; + + pos->X = (float)(sector->centerspot.X + disp.X); + pos->Z = (float)(sector->centerspot.Y + disp.Y); chanflags |= CHAN_LISTENERZ; } } @@ -718,17 +726,20 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, case SOURCE_Polyobj: assert(poly != NULL); - CalcPolyobjSoundOrg(poly, &x, &z, &y); + if (poly != NULL) + { + DVector2 disp = Displacements.getOffset(pgroup, poly->CenterSubsector->sector->PortalGroup); + CalcPolyobjSoundOrg(listenpos-disp, poly, *pos); + pos->X += (float)disp.X; + pos->Z += (float)disp.Y; + } break; } if ((chanflags & CHAN_LISTENERZ) && players[consoleplayer].camera != NULL) { - y = players[consoleplayer].camera != NULL ? players[consoleplayer].camera->SoundZ() : 0; + pos->Y = (float)listenpos.Z; } - pos->X = FIXED2FLOAT(x); - pos->Y = FIXED2FLOAT(y); - pos->Z = FIXED2FLOAT(z); } } if (vel != NULL) @@ -736,9 +747,9 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, // Only actors maintain velocity information. if (type == SOURCE_Actor && actor != NULL) { - vel->X = FIXED2FLOAT(actor->vel.x) * TICRATE; - vel->Y = FIXED2FLOAT(actor->vel.z) * TICRATE; - vel->Z = FIXED2FLOAT(actor->vel.y) * TICRATE; + vel->X = float(actor->Vel.X * TICRATE); + vel->Y = float(actor->Vel.Y * TICRATE); + vel->Z = float(actor->Vel.Z * TICRATE); } else { @@ -757,41 +768,44 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, // //========================================================================== -static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z) +static void CalcSectorSoundOrg(const DVector3 &listenpos, const sector_t *sec, int channum, FVector3 &pos) { if (!(i_compatflags & COMPATF_SECTORSOUNDS)) { // Are we inside the sector? If yes, the closest point is the one we're on. - if (P_PointInSector(*x, *y) == sec) + if (P_PointInSector(pos.X, pos.Y) == sec) { - *x = players[consoleplayer].camera->SoundX(); - *y = players[consoleplayer].camera->SoundY(); + pos.X = (float)listenpos.X; + pos.Z = (float)listenpos.Y; } else { // Find the closest point on the sector's boundary lines and use // that as the perceived origin of the sound. - sec->ClosestPoint(*x, *y, *x, *y); + DVector2 xy; + sec->ClosestPoint(listenpos, xy); + pos.X = (float)xy.X; + pos.Z = (float)xy.Y; } } else { - *x = sec->centerspot.x; - *y = sec->centerspot.y; + pos.X = float(sec->centerspot.X); + pos.Z = float(sec->centerspot.Y); } // Set sound vertical position based on channel. if (channum == CHAN_FLOOR) { - *z = MIN(sec->floorplane.ZatPoint(*x, *y), *z); + pos.Y = (float)MIN(sec->floorplane.ZatPoint(listenpos), listenpos.Z); } else if (channum == CHAN_CEILING) { - *z = MAX(sec->ceilingplane.ZatPoint(*x, *y), *z); + pos.Y = (float)MAX(sec->ceilingplane.ZatPoint(listenpos), listenpos.Z); } else if (channum == CHAN_INTERIOR) { - *z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y)); + pos.Y = (float)clamp(listenpos.Z, sec->floorplane.ZatPoint(listenpos), sec->ceilingplane.ZatPoint(listenpos)); } } @@ -806,14 +820,17 @@ static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fix // //========================================================================== -static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z) +static void CalcPolyobjSoundOrg(const DVector3 &listenpos, const FPolyObj *poly, FVector3 &pos) { side_t *side; sector_t *sec; - poly->ClosestPoint(*x, *y, *x, *y, &side); + DVector2 ppos; + poly->ClosestPoint(listenpos, ppos, &side); + pos.X = (float)ppos.X; + pos.Z = (float)ppos.Y; sec = side->sector; - *z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y)); + pos.Y = (float)clamp(listenpos.Z, sec->floorplane.ZatPoint(listenpos), sec->ceilingplane.ZatPoint(listenpos)); } //========================================================================== @@ -1258,10 +1275,11 @@ void S_Sound (const FPolyObj *poly, int channel, FSoundID sound_id, float volume // //========================================================================== -void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sound_id, float volume, float attenuation) +void S_Sound(const DVector3 &pos, int channel, FSoundID sound_id, float volume, float attenuation) { - FVector3 pt(FIXED2FLOAT(x), FIXED2FLOAT(z), FIXED2FLOAT(y)); - S_StartSound (NULL, NULL, NULL, &pt, channel, sound_id, volume, attenuation); + // The sound system switches Y and Z around. + FVector3 p((float)pos.X, (float)pos.Z, (float)pos.Y); + S_StartSound (NULL, NULL, NULL, &p, channel, sound_id, volume, attenuation); } //========================================================================== @@ -1568,9 +1586,10 @@ void S_RelinkSound (AActor *from, AActor *to) { chan->Actor = NULL; chan->SourceType = SOURCE_Unattached; - chan->Point[0] = FIXED2FLOAT(from->SoundX()); - chan->Point[1] = FIXED2FLOAT(from->SoundZ()); - chan->Point[2] = FIXED2FLOAT(from->SoundY()); + FVector3 p = from->SoundPos(); + chan->Point[0] = p.X; + chan->Point[1] = p.Y; + chan->Point[2] = p.Z; } else { @@ -1950,16 +1969,14 @@ static void S_SetListener(SoundListener &listener, AActor *listenactor) { if (listenactor != NULL) { - listener.angle = ANGLE2RADF(listenactor->angle); + listener.angle = (float)listenactor->Angles.Yaw.Radians(); /* listener.velocity.X = listenactor->vel.x * (TICRATE/65536.f); listener.velocity.Y = listenactor->vel.z * (TICRATE/65536.f); listener.velocity.Z = listenactor->vel.y * (TICRATE/65536.f); */ listener.velocity.Zero(); - listener.position.X = FIXED2FLOAT(listenactor->SoundX()); - listener.position.Y = FIXED2FLOAT(listenactor->SoundZ()); - listener.position.Z = FIXED2FLOAT(listenactor->SoundY()); + listener.position = listenactor->SoundPos(); listener.underwater = listenactor->waterlevel == 3; assert(zones != NULL); listener.Environment = zones[listenactor->Sector->ZoneNumber].Environment; @@ -2638,7 +2655,7 @@ CCMD (loopsound) } else { - AActor *icon = Spawn("SpeakerIcon", players[consoleplayer].mo->PosPlusZ(32*FRACUNIT), ALLOW_REPLACE); + AActor *icon = Spawn("SpeakerIcon", players[consoleplayer].mo->PosPlusZ(32.), ALLOW_REPLACE); if (icon != NULL) { S_Sound(icon, CHAN_BODY | CHAN_LOOP, id, 1.f, ATTN_IDLE); diff --git a/src/s_sound.h b/src/s_sound.h index 59307b707..ad06195e1 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -230,7 +230,7 @@ void S_Sound (AActor *ent, int channel, FSoundID sfxid, float volume, float atte void S_SoundMinMaxDist (AActor *ent, int channel, FSoundID sfxid, float volume, float mindist, float maxdist); void S_Sound (const FPolyObj *poly, int channel, FSoundID sfxid, float volume, float attenuation); void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation); -void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sfxid, float volume, float attenuation); +void S_Sound(const DVector3 &pos, int channel, FSoundID sfxid, float volume, float attenuation); // sound channels // channel 0 never willingly overrides diff --git a/src/sc_man_scanner.re b/src/sc_man_scanner.re index 7e82f19c1..92702f918 100644 --- a/src/sc_man_scanner.re +++ b/src/sc_man_scanner.re @@ -192,8 +192,6 @@ std2: /* other DECORATE top level keywords */ '#include' { RET(TK_Include); } - 'fixed_t' { RET(TK_Fixed_t); } - 'angle_t' { RET(TK_Angle_t); } L (L|D)* { RET(TK_Identifier); } diff --git a/src/sc_man_tokens.h b/src/sc_man_tokens.h index 7fda91330..246462940 100644 --- a/src/sc_man_tokens.h +++ b/src/sc_man_tokens.h @@ -111,8 +111,6 @@ xx(TK_Global, "'global'") xx(TK_Self, "'self'") xx(TK_Stop, "'stop'") xx(TK_Include, "'include'") -xx(TK_Fixed_t, "'fixed_t'") -xx(TK_Angle_t, "'angle_t'") xx(TK_Is, "'is'") xx(TK_Replaces, "'replaces'") diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 548dd7201..9b7de9e43 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -1357,7 +1357,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f))) { float gain = GetRolloff(rolloff, sqrtf(dist_sqr) * distscale); - dir.Resize((gain > 0.00001f) ? 1.f/gain : 100000.f); + dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f); } if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS) { @@ -1596,7 +1596,7 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f))) { float gain = GetRolloff(&chan->Rolloff, sqrtf(chan->DistanceSqr) * chan->DistanceScale); - dir.Resize((gain > 0.00001f) ? 1.f/gain : 100000.f); + dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f); } if(areasound && chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS) { diff --git a/src/tables.h b/src/tables.h index 6fe767a4f..085174892 100644 --- a/src/tables.h +++ b/src/tables.h @@ -100,7 +100,7 @@ typedef uint32 angle_t; // note: remove the call to 'abs' since unsigned values cannot be negative inline angle_t absangle(angle_t a) { - return (angle_t)abs((int32)a); + return (angle_t)abs((int32_t)a); } // Effective size is 2049; diff --git a/src/tarray.h b/src/tarray.h index bd28d86ab..4d16ddfe2 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -43,7 +43,7 @@ #if !defined(_WIN32) #include // for intptr_t -#elif !defined(_MSC_VER) +#else #include // for mingw #endif diff --git a/src/textures/bitmap.cpp b/src/textures/bitmap.cpp index 346ffd65e..7873e35cb 100644 --- a/src/textures/bitmap.cpp +++ b/src/textures/bitmap.cpp @@ -146,9 +146,9 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in a = TSrc::A(pin, tr, tg, tb); if (TBlend::ProcessAlpha0() || a) { - r = (TSrc::R(pin)*inf->blendcolor[0])>>FRACBITS; - g = (TSrc::G(pin)*inf->blendcolor[1])>>FRACBITS; - b = (TSrc::B(pin)*inf->blendcolor[2])>>FRACBITS; + r = (TSrc::R(pin)*inf->blendcolor[0])>>BLENDBITS; + g = (TSrc::G(pin)*inf->blendcolor[1])>>BLENDBITS; + b = (TSrc::B(pin)*inf->blendcolor[2])>>BLENDBITS; TBlend::OpC(pout[TDest::RED], r, a, inf); TBlend::OpC(pout[TDest::GREEN], g, a, inf); @@ -167,9 +167,9 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in a = TSrc::A(pin, tr, tg, tb); if (TBlend::ProcessAlpha0() || a) { - r = (TSrc::R(pin)*inf->blendcolor[3] + inf->blendcolor[0]) >> FRACBITS; - g = (TSrc::G(pin)*inf->blendcolor[3] + inf->blendcolor[1]) >> FRACBITS; - b = (TSrc::B(pin)*inf->blendcolor[3] + inf->blendcolor[2]) >> FRACBITS; + r = (TSrc::R(pin)*inf->blendcolor[3] + inf->blendcolor[0]) >> BLENDBITS; + g = (TSrc::G(pin)*inf->blendcolor[3] + inf->blendcolor[1]) >> BLENDBITS; + b = (TSrc::B(pin)*inf->blendcolor[3] + inf->blendcolor[2]) >> BLENDBITS; TBlend::OpC(pout[TDest::RED], r, a, inf); TBlend::OpC(pout[TDest::GREEN], g, a, inf); diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index 8519c8b80..27d3c0b4b 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -48,6 +48,14 @@ struct FClipRect bool Intersect(int ix, int iy, int iw, int ih); }; +typedef int blend_t; + +enum +{ + BLENDBITS = 16, + BLENDUNIT = (1<alpha) >> FRACBITS; } + static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = (s*i->alpha) >> BLENDBITS; } static __forceinline bool ProcessAlpha0() { return false; } }; @@ -380,28 +388,28 @@ struct bOverlay struct bBlend { - static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = (d*i->invalpha + s*i->alpha) >> FRACBITS; } + static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = (d*i->invalpha + s*i->alpha) >> BLENDBITS; } static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; struct bAdd { - static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = MIN((d*FRACUNIT + s*i->alpha) >> FRACBITS, 255); } + static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = MIN((d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 255); } static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; struct bSubtract { - static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = MAX((d*FRACUNIT - s*i->alpha) >> FRACBITS, 0); } + static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = MAX((d*BLENDUNIT - s*i->alpha) >> BLENDBITS, 0); } static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; struct bReverseSubtract { - static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = MAX((-d*FRACUNIT + s*i->alpha) >> FRACBITS, 0); } + static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = MAX((-d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 0); } static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index f33bfa702..89fe94757 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -180,7 +180,7 @@ protected: FRemapTable *Translation; PalEntry Blend; FTexture *Texture; - fixed_t Alpha; + blend_t Alpha; TexPart(); }; @@ -246,8 +246,8 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl Name = (char *)mtexture.d->name; CalcBitSize (); - xScale = mtexture.d->ScaleX ? mtexture.d->ScaleX*(FRACUNIT/8) : FRACUNIT; - yScale = mtexture.d->ScaleY ? mtexture.d->ScaleY*(FRACUNIT/8) : FRACUNIT; + Scale.X = mtexture.d->ScaleX ? mtexture.d->ScaleX / 8. : 1.; + Scale.Y = mtexture.d->ScaleY ? mtexture.d->ScaleY / 8. : 1.; if (mtexture.d->Flags & MAPTEXF_WORLDPANNING) { @@ -593,7 +593,7 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota memset (&info, 0, sizeof(info)); info.alpha = Parts[i].Alpha; - info.invalpha = FRACUNIT - info.alpha; + info.invalpha = BLENDUNIT - info.alpha; info.op = ECopyOp(Parts[i].op); PalEntry b = Parts[i].Blend; if (b.a == 0 && b != BLEND_NONE) @@ -604,14 +604,14 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota { if (b.a == 255) { - info.blendcolor[0] = b.r * FRACUNIT / 255; - info.blendcolor[1] = b.g * FRACUNIT / 255; - info.blendcolor[2] = b.b * FRACUNIT / 255; + info.blendcolor[0] = b.r * BLENDUNIT / 255; + info.blendcolor[1] = b.g * BLENDUNIT / 255; + info.blendcolor[2] = b.b * BLENDUNIT / 255; info.blend = BLEND_MODULATE; } else { - fixed_t blendalpha = b.a * FRACUNIT / 255; + blend_t blendalpha = b.a * BLENDUNIT / 255; info.blendcolor[0] = b.r * blendalpha; info.blendcolor[1] = b.g * blendalpha; info.blendcolor[2] = b.b * blendalpha; @@ -1165,7 +1165,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, bool silent, i else if (sc.Compare("alpha")) { sc.MustGetFloat(); - part.Alpha = clamp(FLOAT2FIXED(sc.Float), 0, FRACUNIT); + part.Alpha = clamp(int(sc.Float / BLENDUNIT), 0, BLENDUNIT); // bComplex is not set because it is only needed when the style is not OP_COPY. } else if (sc.Compare("style")) @@ -1243,14 +1243,14 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) if (sc.Compare("XScale")) { sc.MustGetFloat(); - xScale = FLOAT2FIXED(sc.Float); - if (xScale == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name.GetChars()); + Scale.X = sc.Float; + if (Scale.X == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name.GetChars()); } else if (sc.Compare("YScale")) { sc.MustGetFloat(); - yScale = FLOAT2FIXED(sc.Float); - if (yScale == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name.GetChars()); + Scale.Y = sc.Float; + if (Scale.Y == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name.GetChars()); } else if (sc.Compare("WorldPanning")) { diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index ae96605cf..7b90c295f 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -118,12 +118,12 @@ FTexture * FTexture::CreateTexture (int lumpnum, int usetype) // Now we're stuck with this stupid behaviour. if (w==128 && h==128) { - tex->xScale = tex->yScale = 2*FRACUNIT; + tex->Scale.X = tex->Scale.Y = 2; tex->bWorldPanning = true; } else if (w==256 && h==256) { - tex->xScale = tex->yScale = 4*FRACUNIT; + tex->Scale.X = tex->Scale.Y = 4; tex->bWorldPanning = true; } } @@ -147,7 +147,7 @@ FTexture * FTexture::CreateTexture (const char *name, int lumpnum, int usetype) FTexture::FTexture (const char *name, int lumpnum) : LeftOffset(0), TopOffset(0), - WidthBits(0), HeightBits(0), xScale(FRACUNIT), yScale(FRACUNIT), SourceLump(lumpnum), + WidthBits(0), HeightBits(0), Scale(1,1), SourceLump(lumpnum), UseType(TEX_Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false), bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bKeepAround(false), Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0), Native(NULL) @@ -562,11 +562,11 @@ FTexture *FTexture::GetRawTexture() void FTexture::SetScaledSize(int fitwidth, int fitheight) { - xScale = FLOAT2FIXED(float(Width) / fitwidth); - yScale = FLOAT2FIXED(float(Height) / fitheight); + Scale.X = double(Width) / fitwidth; + Scale.Y =double(Height) / fitheight; // compensate for roundoff errors - if (MulScale16(xScale, fitwidth) != Width) xScale++; - if (MulScale16(yScale, fitheight) != Height) yScale++; + if (int(Scale.X * fitwidth) != Width) Scale.X += (1 / 65536.); + if (int(Scale.Y * fitheight) != Height) Scale.Y += (1 / 65536.); } diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index a208d7b49..b2c7164e2 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -569,8 +569,8 @@ void FTextureManager::AddHiresTextures (int wadnum) // Replace the entire texture and adjust the scaling and offset factors. newtex->bWorldPanning = true; newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); - newtex->LeftOffset = FixedMul(oldtex->GetScaledLeftOffset(), newtex->xScale); - newtex->TopOffset = FixedMul(oldtex->GetScaledTopOffset(), newtex->yScale); + newtex->LeftOffset = int(oldtex->GetScaledLeftOffset() * newtex->Scale.X); + newtex->TopOffset = int(oldtex->GetScaledTopOffset() * newtex->Scale.Y); ReplaceTexture(tlist[i], newtex, true); } } @@ -658,8 +658,8 @@ void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) // Replace the entire texture and adjust the scaling and offset factors. newtex->bWorldPanning = true; newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); - newtex->LeftOffset = FixedMul(oldtex->GetScaledLeftOffset(), newtex->xScale); - newtex->TopOffset = FixedMul(oldtex->GetScaledTopOffset(), newtex->yScale); + newtex->LeftOffset = int(oldtex->GetScaledLeftOffset() * newtex->Scale.X); + newtex->TopOffset = int(oldtex->GetScaledTopOffset() * newtex->Scale.Y); ReplaceTexture(tlist[i], newtex, true); } } diff --git a/src/textures/textures.h b/src/textures/textures.h index 13f5b0eab..318e32644 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -2,6 +2,7 @@ #define __TEXTURES_H #include "doomtype.h" +#include "vectors.h" class FBitmap; struct FRemapTable; @@ -122,8 +123,7 @@ public: BYTE WidthBits, HeightBits; - fixed_t xScale; - fixed_t yScale; + DVector2 Scale; int SourceLump; FTextureID id; @@ -202,16 +202,16 @@ public: int GetWidth () { return Width; } int GetHeight () { return Height; } - int GetScaledWidth () { int foo = (Width << 17) / xScale; return (foo >> 1) + (foo & 1); } - int GetScaledHeight () { int foo = (Height << 17) / yScale; return (foo >> 1) + (foo & 1); } - int GetScaledHeight(fixed_t scale) { int foo = (Height << 17) / scale; return (foo >> 1) + (foo & 1); } - double GetScaledWidthDouble () { return (Width * 65536.) / xScale; } - double GetScaledHeightDouble () { return (Height * 65536.) / yScale; } + int GetScaledWidth () { int foo = int((Width * 2) / Scale.X); return (foo >> 1) + (foo & 1); } + int GetScaledHeight () { int foo = int((Height * 2) / Scale.Y); return (foo >> 1) + (foo & 1); } + double GetScaledWidthDouble () { return Width / Scale.X; } + double GetScaledHeightDouble () { return Height / Scale.Y; } + double GetScaleY() const { return Scale.Y; } - int GetScaledLeftOffset () { int foo = (LeftOffset << 17) / xScale; return (foo >> 1) + (foo & 1); } - int GetScaledTopOffset () { int foo = (TopOffset << 17) / yScale; return (foo >> 1) + (foo & 1); } - double GetScaledLeftOffsetDouble() { return (LeftOffset * 65536.) / xScale; } - double GetScaledTopOffsetDouble() { return (TopOffset * 65536.) / yScale; } + int GetScaledLeftOffset () { int foo = int((LeftOffset * 2) / Scale.X); return (foo >> 1) + (foo & 1); } + int GetScaledTopOffset () { int foo = int((TopOffset * 2) / Scale.Y); return (foo >> 1) + (foo & 1); } + double GetScaledLeftOffsetDouble() { return LeftOffset / Scale.X; } + double GetScaledTopOffsetDouble() { return TopOffset / Scale.Y; } virtual void SetFrontSkyLayer(); @@ -237,8 +237,7 @@ public: LeftOffset = BaseTexture->LeftOffset; WidthBits = BaseTexture->WidthBits; HeightBits = BaseTexture->HeightBits; - xScale = BaseTexture->xScale; - yScale = BaseTexture->yScale; + Scale = BaseTexture->Scale; WidthMask = (1 << WidthBits) - 1; } diff --git a/src/thingdef/olddecorations.cpp b/src/thingdef/olddecorations.cpp index c1610a521..5fa994262 100644 --- a/src/thingdef/olddecorations.cpp +++ b/src/thingdef/olddecorations.cpp @@ -63,7 +63,7 @@ struct FExtraInfo bool bSolidOnDeath, bSolidOnBurn; bool bBurnAway, bDiesAway, bGenericIceDeath; bool bExplosive; - fixed_t DeathHeight, BurnHeight; + double DeathHeight, BurnHeight; }; class AFakeInventory : public AInventory @@ -256,7 +256,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) if (extra.DeathHeight == 0) { - extra.DeathHeight = ((AActor*)(type->Defaults))->height; + extra.DeathHeight = ((AActor*)(type->Defaults))->Height; } type->DeathHeight = extra.DeathHeight; } @@ -296,7 +296,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) type->OwnedStates[extra.FireDeathStart].SetAction("A_ActiveAndUnblock"); } - if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->height; + if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->Height; type->BurnHeight = extra.BurnHeight; bag.statedef.SetStateLabel("Burn", &type->OwnedStates[extra.FireDeathStart]); @@ -440,12 +440,12 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults, else if (sc.Compare ("Alpha")) { sc.MustGetFloat (); - defaults->alpha = int(clamp (sc.Float, 0.0, 1.0) * OPAQUE); + defaults->Alpha = clamp (sc.Float, 0.0, 1.0); } else if (sc.Compare ("Scale")) { sc.MustGetFloat (); - defaults->scaleX = defaults->scaleY = FLOAT2FIXED(sc.Float); + defaults->Scale.X = defaults->Scale.Y = sc.Float; } else if (sc.Compare ("RenderStyle")) { @@ -455,22 +455,22 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults, else if (sc.Compare ("Radius")) { sc.MustGetFloat (); - defaults->radius = int(sc.Float * FRACUNIT); + defaults->radius = sc.Float; } else if (sc.Compare ("Height")) { sc.MustGetFloat (); - defaults->height = int(sc.Float * FRACUNIT); + defaults->Height = sc.Float; } else if (def == DEF_BreakableDecoration && sc.Compare ("DeathHeight")) { sc.MustGetFloat (); - extra.DeathHeight = int(sc.Float * FRACUNIT); + extra.DeathHeight = sc.Float; } else if (def == DEF_BreakableDecoration && sc.Compare ("BurnHeight")) { sc.MustGetFloat (); - extra.BurnHeight = int(sc.Float * FRACUNIT); + extra.BurnHeight = sc.Float; } else if (def == DEF_BreakableDecoration && sc.Compare ("Health")) { @@ -514,7 +514,7 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults, else if (def == DEF_Projectile && sc.Compare ("Speed")) { sc.MustGetFloat (); - defaults->Speed = fixed_t(sc.Float * 65536.f); + defaults->Speed = sc.Float; } else if (sc.Compare ("Mass")) { diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index d990b05f0..d522ad573 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -326,9 +326,6 @@ int MatchString (const char *in, const char **strings); #define PROP_DOUBLE_PARM(var, no) \ double var = params[(no)+1].d; -#define PROP_FIXED_PARM(var, no) \ - fixed_t var = FLOAT2FIXED(params[(no)+1].d); - #define PROP_COLOR_PARM(var, no) \ int var = params[(no)+1].i== 0? params[(no)+2].i : V_GetColor(NULL, params[(no)+2].s); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 653bac685..d0a157932 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -76,6 +76,7 @@ #include "d_player.h" #include "p_maputl.h" #include "p_spec.h" +#include "math/cmath.h" AActor *SingleActorFromTID(int tid, AActor *defactor); @@ -312,12 +313,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetDistance) } else { - fixedvec3 diff = self->Vec3To(target); + DVector3 diff = self->Vec3To(target); if (checkz) - diff.z += (target->height - self->height) / 2; + diff.Z += (target->Height - self->Height) / 2; - const double length = DVector3(FIXED2DBL(diff.x), FIXED2DBL(diff.y), (checkz) ? FIXED2DBL(diff.z) : 0).Length(); - ret->SetFloat(length); + ret->SetFloat(diff.Length()); } return 1; } @@ -598,7 +598,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnsetFloat) // //========================================================================== static void DoAttack (AActor *self, bool domelee, bool domissile, - int MeleeDamage, FSoundID MeleeSound, PClassActor *MissileType,fixed_t MissileHeight) + int MeleeDamage, FSoundID MeleeSound, PClassActor *MissileType,double MissileHeight) { if (self->target == NULL) return; @@ -613,9 +613,10 @@ static void DoAttack (AActor *self, bool domelee, bool domissile, else if (domissile && MissileType != NULL) { // This seemingly senseless code is needed for proper aiming. - self->AddZ(MissileHeight + self->GetBobOffset() - 32*FRACUNIT); - AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32*FRACUNIT), self, self->target, MissileType, false); - self->AddZ(-(MissileHeight + self->GetBobOffset() - 32*FRACUNIT)); + double add = MissileHeight + self->GetBobOffset() - 32; + self->AddZ(add); + AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32.), self, self->target, MissileType, false); + self->AddZ(-add); if (missile) { @@ -642,8 +643,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MissileAttack) { PARAM_ACTION_PROLOGUE; PClassActor *MissileType = PClass::FindActor(self->GetClass()->MissileName); - fixed_t MissileHeight = self->GetClass()->MissileHeight; - DoAttack(self, false, true, 0, 0, MissileType, MissileHeight); + DoAttack(self, false, true, 0, 0, MissileType, self->GetClass()->MissileHeight); return 0; } @@ -653,8 +653,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ComboAttack) int MeleeDamage = self->GetClass()->MeleeDamage; FSoundID MeleeSound = self->GetClass()->MeleeSound; PClassActor *MissileType = PClass::FindActor(self->GetClass()->MissileName); - fixed_t MissileHeight = self->GetClass()->MissileHeight; - DoAttack(self, true, true, MeleeDamage, MeleeSound, MissileType, MissileHeight); + DoAttack(self, true, true, MeleeDamage, MeleeSound, MissileType, self->GetClass()->MissileHeight); return 0; } @@ -664,7 +663,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BasicAttack) PARAM_INT (melee_damage); PARAM_SOUND (melee_sound); PARAM_CLASS (missile_type, AActor); - PARAM_FIXED (missile_height); + PARAM_FLOAT (missile_height); if (missile_type != NULL) { @@ -803,7 +802,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SeekerMissile) { self->tracer = P_RoughMonsterSearch (self, distance, true); } - if (!P_SeekerMissile(self, clamp(ang1, 0, 90) * ANGLE_1, clamp(ang2, 0, 90) * ANGLE_1, !!(flags & SMF_PRECISE), !!(flags & SMF_CURSPEED))) + if (!P_SeekerMissile(self, clamp(ang1, 0, 90), clamp(ang2, 0, 90), !!(flags & SMF_PRECISE), !!(flags & SMF_CURSPEED))) { if (flags & SMF_LOOK) { // This monster is no longer seekable, so let us look for another one next time. @@ -823,20 +822,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_BulletAttack) PARAM_ACTION_PROLOGUE; int i; - int bangle; - int slope; if (!self->target) return 0; A_FaceTarget (self); - bangle = self->angle; - slope = P_AimLineAttack (self, bangle, MISSILERANGE); + DAngle slope = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); for (i = self->GetMissileDamage (0, 1); i > 0; --i) { - int angle = bangle + (pr_cabullet.Random2() << 20); + DAngle angle = self->Angles.Yaw + pr_cabullet.Random2() * (5.625 / 256.); int damage = ((pr_cabullet()%5)+1)*3; P_LineAttack(self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); @@ -931,7 +927,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInsideMeleeRange) static int DoJumpIfCloser(AActor *target, VM_ARGS) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED (dist); + PARAM_FLOAT (dist); PARAM_STATE (jump); PARAM_BOOL_OPT(noz) { noz = false; } @@ -939,7 +935,7 @@ static int DoJumpIfCloser(AActor *target, VM_ARGS) { // No target - no jump ACTION_RETURN_STATE(NULL); } - if (self->AproxDistance(target) < dist && + if (self->Distance2D(target) < dist && (noz || ((self->Z() > target->Z() && self->Z() - target->Top() < dist) || (self->Z() <= target->Z() && target->Z() - self->Top() < dist)))) @@ -1094,19 +1090,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode) if (nails) { - angle_t ang; + DAngle ang; for (int i = 0; i < nails; i++) { - ang = i*(ANGLE_MAX/nails); + ang = i*360./nails; // Comparing the results of a test wad with Eternity, it seems A_NailBomb does not aim - P_LineAttack (self, ang, MISSILERANGE, 0, + P_LineAttack (self, ang, MISSILERANGE, 0., //P_AimLineAttack (self, ang, MISSILERANGE), naildamage, NAME_Hitscan, pufftype); } } P_RadiusAttack (self, self->target, damage, distance, self->DamageType, flags, fulldmgdistance); - P_CheckSplash(self, distance<target != NULL && self->target->player != NULL) { validcount++; @@ -1149,7 +1145,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust) } P_RadiusAttack (self, self->target, force, distance, self->DamageType, flags | RADF_NODAMAGE, fullthrustdistance); - P_CheckSplash(self, distance << FRACBITS); + P_CheckSplash(self, distance); if (sourcenothrust) { @@ -1200,11 +1196,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (ti, AActor); - PARAM_FIXED_OPT (spawnheight) { spawnheight = 32*FRACUNIT; } - PARAM_INT_OPT (spawnofs_xy) { spawnofs_xy = 0; } - PARAM_ANGLE_OPT (angle) { angle = 0; } + PARAM_FLOAT_OPT (Spawnheight) { Spawnheight = 32; } + PARAM_FLOAT_OPT (Spawnofs_xy) { Spawnofs_xy = 0; } + PARAM_ANGLE_OPT (Angle) { Angle = 0.; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_ANGLE_OPT (pitch) { pitch = 0; } + PARAM_ANGLE_OPT (Pitch) { Pitch = 0.; } PARAM_INT_OPT (ptr) { ptr = AAPTR_TARGET; } AActor *ref = COPY_AAPTR(self, ptr); @@ -1218,29 +1214,29 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) { if (ti) { - angle_t ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; - fixed_t x = spawnofs_xy * finecosine[ang]; - fixed_t y = spawnofs_xy * finesine[ang]; - fixed_t z = spawnheight + self->GetBobOffset() - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0); + DAngle angle = self->Angles.Yaw - 90; + double x = Spawnofs_xy * angle.Cos(); + double y = Spawnofs_xy * angle.Sin(); + double z = Spawnheight + self->GetBobOffset() - 32 + (self->player? self->player->crouchoffset : 0.); - fixedvec3 pos = self->Pos(); + DVector3 pos = self->Pos(); switch (aimmode) { case 0: default: // same adjustment as above (in all 3 directions this time) - for better aiming! self->SetXYZ(self->Vec3Offset(x, y, z)); - missile = P_SpawnMissileXYZ(self->PosPlusZ(32*FRACUNIT), self, ref, ti, false); + missile = P_SpawnMissileXYZ(self->PosPlusZ(32.), self, ref, ti, false); self->SetXYZ(pos); break; case 1: - missile = P_SpawnMissileXYZ(self->Vec3Offset(x, y, self->GetBobOffset() + spawnheight), self, ref, ti, false); + missile = P_SpawnMissileXYZ(self->Vec3Offset(x, y, self->GetBobOffset() + Spawnheight), self, ref, ti, false); break; case 2: - self->SetXYZ(self->Vec3Offset(x, y, 0)); - missile = P_SpawnMissileAngleZSpeed(self, self->Z() + self->GetBobOffset() + spawnheight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false); + self->SetXYZ(self->Vec3Offset(x, y, 0.)); + missile = P_SpawnMissileAngleZSpeed(self, self->Z() + self->GetBobOffset() + Spawnheight, ti, self->Angles.Yaw, 0, GetDefaultByType(ti)->Speed, self, false); self->SetXYZ(pos); flags |= CMF_ABSOLUTEPITCH; @@ -1254,38 +1250,32 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) // so that this can handle missiles with a high vertical velocity // component properly. - fixed_t missilespeed; + double missilespeed; if ( (CMF_ABSOLUTEPITCH|CMF_OFFSETPITCH) & flags) { if (CMF_OFFSETPITCH & flags) { - DVector2 velocity (missile->vel.x, missile->vel.y); - pitch += R_PointToAngle2(0,0, xs_CRoundToInt(velocity.Length()), missile->vel.z); + Pitch += missile->Vel.Pitch(); } - ang = pitch >> ANGLETOFINESHIFT; - missilespeed = abs(FixedMul(finecosine[ang], missile->Speed)); - missile->vel.z = FixedMul(finesine[ang], missile->Speed); + missilespeed = fabs(Pitch.Cos() * missile->Speed); + missile->Vel.Z = Pitch.Sin() * missile->Speed; } else { - DVector2 velocity (missile->vel.x, missile->vel.y); - missilespeed = xs_CRoundToInt(velocity.Length()); + missilespeed = missile->VelXYToSpeed(); } if (CMF_SAVEPITCH & flags) { - missile->pitch = pitch; + missile->Angles.Pitch = Pitch; // In aimmode 0 and 1 without absolutepitch or offsetpitch, the pitch parameter // contains the unapplied parameter. In that case, it is set as pitch without // otherwise affecting the spawned actor. } - missile->angle = (CMF_ABSOLUTEANGLE & flags) ? angle : missile->angle + angle ; - - ang = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul(missilespeed, finecosine[ang]); - missile->vel.y = FixedMul(missilespeed, finesine[ang]); + missile->Angles.Yaw = (CMF_ABSOLUTEANGLE & flags) ? Angle : missile->Angles.Yaw + Angle; + missile->VelFromAngle(missilespeed); // handle projectile shooting projectiles - track the // links back to a real owner @@ -1354,7 +1344,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) PARAM_INT (numbullets); PARAM_INT (damageperbullet); PARAM_CLASS_OPT (pufftype, AActor) { pufftype = PClass::FindActor(NAME_BulletPuff); } - PARAM_FIXED_OPT (range) { range = MISSILERANGE; } + PARAM_FLOAT_OPT (range) { range = 0; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (ptr) { ptr = AAPTR_TARGET; } @@ -1364,8 +1354,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) range = MISSILERANGE; int i; - int bangle; - int bslope = 0; + DAngle bangle; + DAngle bslope = 0.; int laflags = (flags & CBAF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; if (ref != NULL || (flags & CBAF_AIMFACING)) @@ -1374,15 +1364,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) { A_Face(self, ref); } - bangle = self->angle; + bangle = self->Angles.Yaw; if (!(flags & CBAF_NOPITCH)) bslope = P_AimLineAttack (self, bangle, MISSILERANGE); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); for (i = 0; i < numbullets; i++) { - int angle = bangle; - int slope = bslope; + DAngle angle = bangle; + DAngle slope = bslope; if (flags & CBAF_EXPLICITANGLE) { @@ -1391,8 +1381,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) } else { - angle += pr_cwbullet.Random2() * (spread_xy / 255); - slope += pr_cwbullet.Random2() * (spread_z / 255); + angle += spread_xy * (pr_cwbullet.Random2() / 255.); + slope += spread_z * (pr_cwbullet.Random2() / 255.); } int damage = damageperbullet; @@ -1452,7 +1442,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (ti, AActor); - PARAM_FIXED (spawnheight); + PARAM_FLOAT (spawnheight); PARAM_INT (damage); PARAM_SOUND_OPT (meleesound) { meleesound = 0; } PARAM_NAME_OPT (damagetype) { damagetype = NAME_Melee; } @@ -1475,9 +1465,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack) else if (ti) { // This seemingly senseless code is needed for proper aiming. - self->AddZ(spawnheight + self->GetBobOffset() - 32*FRACUNIT); - AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32*FRACUNIT), self, self->target, ti, false); - self->AddZ(-(spawnheight + self->GetBobOffset() - 32*FRACUNIT)); + double add = spawnheight + self->GetBobOffset() - 32; + self->AddZ(add); + AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32.), self, self->target, ti, false); + self->AddZ(-add); if (missile) { @@ -1539,7 +1530,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) PARAM_INT (damageperbullet); PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; } PARAM_INT_OPT (flags) { flags = FBF_USEAMMO; } - PARAM_FIXED_OPT (range) { range = 0; } + PARAM_FLOAT_OPT (range) { range = 0; } if (!self->player) return 0; @@ -1547,8 +1538,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) AWeapon *weapon = player->ReadyWeapon; int i; - int bangle; - int bslope = 0; + DAngle bangle; + DAngle bslope = 0.; int laflags = (flags & FBF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; if ((flags & FBF_USEAMMO) && weapon && ACTION_CALL_FROM_WEAPON()) @@ -1557,16 +1548,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) return 0; // out of ammo } - if (range == 0) - range = PLAYERMISSILERANGE; + if (range == 0) range = PLAYERMISSILERANGE; if (!(flags & FBF_NOFLASH)) static_cast(self)->PlayAttacking2 (); if (!(flags & FBF_NOPITCH)) bslope = P_BulletSlope(self); - bangle = self->angle; + bangle = self->Angles.Yaw; - if (pufftype == NULL) - pufftype = PClass::FindActor(NAME_BulletPuff); + if (pufftype == NULL) pufftype = PClass::FindActor(NAME_BulletPuff); if (weapon != NULL) { @@ -1588,8 +1577,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) numbullets = 1; for (i = 0; i < numbullets; i++) { - int angle = bangle; - int slope = bslope; + DAngle angle = bangle; + DAngle slope = bslope; if (flags & FBF_EXPLICITANGLE) { @@ -1598,8 +1587,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) } else { - angle += pr_cwbullet.Random2() * (spread_xy / 255); - slope += pr_cwbullet.Random2() * (spread_z / 255); + angle += spread_xy * (pr_cwbullet.Random2() / 255.); + slope += spread_z * (pr_cwbullet.Random2() / 255.); } int damage = damageperbullet; @@ -1629,12 +1618,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (ti, AActor); - PARAM_ANGLE_OPT (angle) { angle = 0; } + PARAM_ANGLE_OPT (angle) { angle = 0.; } PARAM_BOOL_OPT (useammo) { useammo = true; } - PARAM_INT_OPT (spawnofs_xy) { spawnofs_xy = 0; } - PARAM_FIXED_OPT (spawnheight) { spawnheight = 0; } + PARAM_FLOAT_OPT (spawnofs_xy) { spawnofs_xy = 0; } + PARAM_FLOAT_OPT (spawnheight) { spawnheight = 0; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_ANGLE_OPT (pitch) { pitch = 0; } + PARAM_ANGLE_OPT (pitch) { pitch = 0.; } if (!self->player) return 0; @@ -1652,19 +1641,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) if (ti) { - angle_t ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; - fixed_t x = spawnofs_xy * finecosine[ang]; - fixed_t y = spawnofs_xy * finesine[ang]; - fixed_t z = spawnheight; - fixed_t shootangle = self->angle; + DAngle ang = self->Angles.Yaw - 90; + DVector2 ofs = ang.ToVector(spawnofs_xy); + DAngle shootangle = self->Angles.Yaw; if (flags & FPF_AIMATANGLE) shootangle += angle; // Temporarily adjusts the pitch - fixed_t saved_player_pitch = self->pitch; - self->pitch -= pitch; - AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &t, NULL, false, (flags & FPF_NOAUTOAIM) != 0); - self->pitch = saved_player_pitch; + DAngle saved_player_pitch = self->Angles.Pitch; + self->Angles.Pitch -= pitch; + AActor * misl=P_SpawnPlayerMissile (self, ofs.X, ofs.Y, spawnheight, ti, shootangle, &t, NULL, false, (flags & FPF_NOAUTOAIM) != 0); + self->Angles.Pitch = saved_player_pitch; // automatic handling of seeker missiles if (misl) @@ -1677,12 +1664,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) { // This original implementation is to aim straight ahead and then offset // the angle from the resulting direction. - DVector3 velocity(misl->vel.x, misl->vel.y, 0); - fixed_t missilespeed = xs_CRoundToInt(velocity.Length()); - misl->angle += angle; - angle_t an = misl->angle >> ANGLETOFINESHIFT; - misl->vel.x = FixedMul (missilespeed, finecosine[an]); - misl->vel.y = FixedMul (missilespeed, finesine[an]); + misl->Angles.Yaw += angle; + misl->VelFromAngle(misl->VelXYToSpeed()); } } } @@ -1715,8 +1698,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) PARAM_BOOL_OPT (norandom) { norandom = false; } PARAM_INT_OPT (flags) { flags = CPF_USEAMMO; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; } - PARAM_FIXED_OPT (range) { range = 0; } - PARAM_FIXED_OPT (lifesteal) { lifesteal = 0; } + PARAM_FLOAT_OPT (range) { range = 0; } + PARAM_FLOAT_OPT (lifesteal) { lifesteal = 0; } PARAM_INT_OPT (lifestealmax) { lifestealmax = 0; } PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; } PARAM_SOUND_OPT (MeleeSound) { MeleeSound = ""; } @@ -1729,17 +1712,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) AWeapon *weapon = player->ReadyWeapon; - angle_t angle; - int pitch; + DAngle angle; + DAngle pitch; FTranslatedLineTarget t; int actualdamage; if (!norandom) damage *= pr_cwpunch() % 8 + 1; - angle = self->angle + (pr_cwpunch.Random2() << 18); - if (range == 0) - range = MELEERANGE; + angle = self->Angles.Yaw + pr_cwpunch.Random2() * (5.625 / 256); + if (range == 0) range = MELEERANGE; pitch = P_AimLineAttack (self, angle, range, &t); // only use ammo when actually hitting something! @@ -1761,7 +1743,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) } else { - if (lifesteal && !(t.linetarget->flags5 & MF5_DONTDRAIN)) + if (lifesteal > 0 && !(t.linetarget->flags5 & MF5_DONTDRAIN)) { if (flags & CPF_STEALARMOR) { @@ -1772,8 +1754,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) if (armorbonustype != NULL) { assert(armorbonustype->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))); - ABasicArmorBonus *armorbonus = static_cast(Spawn(armorbonustype, 0,0,0, NO_REPLACE)); - armorbonus->SaveAmount *= (actualdamage * lifesteal) >> FRACBITS; + ABasicArmorBonus *armorbonus = static_cast(Spawn(armorbonustype)); + armorbonus->SaveAmount *= int(actualdamage * lifesteal); armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax; armorbonus->flags |= MF_DROPPED; armorbonus->ClearCounters(); @@ -1786,7 +1768,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) } else { - P_GiveBody (self, (actualdamage * lifesteal) >> FRACBITS, lifestealmax); + P_GiveBody (self, int(actualdamage * lifesteal), lifestealmax); } } if (weapon != NULL) @@ -1798,7 +1780,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) if (!(flags & CPF_NOTURN)) { // turn to face target - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; } if (flags & CPF_PULLIN) self->flags |= MF_JUSTATTACKED; @@ -1824,17 +1806,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RailAttack) PARAM_INT_OPT (flags) { flags = 0; } PARAM_FLOAT_OPT (maxdiff) { maxdiff = 0; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = PClass::FindActor(NAME_BulletPuff); } - PARAM_ANGLE_OPT (spread_xy) { spread_xy = 0; } - PARAM_ANGLE_OPT (spread_z) { spread_z = 0; } - PARAM_FIXED_OPT (range) { range = 0; } + PARAM_ANGLE_OPT (spread_xy) { spread_xy = 0.; } + PARAM_ANGLE_OPT (spread_z) { spread_z = 0.; } + PARAM_FLOAT_OPT (range) { range = 0; } PARAM_INT_OPT (duration) { duration = 0; } PARAM_FLOAT_OPT (sparsity) { sparsity = 1; } PARAM_FLOAT_OPT (driftspeed) { driftspeed = 1; } PARAM_CLASS_OPT (spawnclass, AActor){ spawnclass = NULL; } - PARAM_FIXED_OPT (spawnofs_z) { spawnofs_z = 0; } + PARAM_FLOAT_OPT (spawnofs_z) { spawnofs_z = 0; } PARAM_INT_OPT (SpiralOffset) { SpiralOffset = 270; } - if (range == 0) range = 8192*FRACUNIT; + if (range == 0) range = 8192; if (sparsity == 0) sparsity=1.0; if (self->player == NULL) @@ -1849,21 +1831,31 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RailAttack) return 0; // out of ammo } - angle_t angle; - angle_t slope; - - if (flags & RAF_EXPLICITANGLE) + if (!(flags & RAF_EXPLICITANGLE)) { - angle = spread_xy; - slope = spread_z; - } - else - { - angle = pr_crailgun.Random2() * (spread_xy / 255); - slope = pr_crailgun.Random2() * (spread_z / 255); + spread_xy = spread_xy * pr_crailgun.Random2() / 255; + spread_z = spread_z * pr_crailgun.Random2() / 255; } - P_RailAttack (self, damage, spawnofs_xy, spawnofs_z, color1, color2, maxdiff, flags, pufftype, angle, slope, range, duration, sparsity, driftspeed, spawnclass, SpiralOffset); + FRailParams p; + p.source = self; + p.damage = damage; + p.offset_xy = spawnofs_xy; + p.offset_z = spawnofs_z; + p.color1 = color1; + p.color2 = color2; + p.maxdiff = maxdiff; + p.flags = flags; + p.puff = pufftype; + p.angleoffset = spread_xy; + p.pitchoffset = spread_z; + p.distance = range; + p.duration = duration; + p.sparsity = sparsity; + p.drift = driftspeed; + p.spawnclass = spawnclass; + p.SpiralOffset = SpiralOffset; + P_RailAttack(&p); return 0; } @@ -1891,24 +1883,24 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) PARAM_INT_OPT (aim) { aim = CRF_DONTAIM; } PARAM_FLOAT_OPT (maxdiff) { maxdiff = 0; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = PClass::FindActor(NAME_BulletPuff); } - PARAM_ANGLE_OPT (spread_xy) { spread_xy = 0; } - PARAM_ANGLE_OPT (spread_z) { spread_z = 0; } - PARAM_FIXED_OPT (range) { range = 0; } + PARAM_ANGLE_OPT (spread_xy) { spread_xy = 0.; } + PARAM_ANGLE_OPT (spread_z) { spread_z = 0.; } + PARAM_FLOAT_OPT (range) { range = 0; } PARAM_INT_OPT (duration) { duration = 0; } PARAM_FLOAT_OPT (sparsity) { sparsity = 1; } PARAM_FLOAT_OPT (driftspeed) { driftspeed = 1; } PARAM_CLASS_OPT (spawnclass, AActor){ spawnclass = NULL; } - PARAM_FIXED_OPT (spawnofs_z) { spawnofs_z = 0; } + PARAM_FLOAT_OPT (spawnofs_z) { spawnofs_z = 0; } PARAM_INT_OPT (SpiralOffset) { SpiralOffset = 270; } - if (range == 0) range = 8192*FRACUNIT; + if (range == 0) range = 8192.; if (sparsity == 0) sparsity = 1; FTranslatedLineTarget t; - fixedvec3 savedpos = self->Pos(); - angle_t saved_angle = self->angle; - fixed_t saved_pitch = self->pitch; + DVector3 savedpos = self->Pos(); + DAngle saved_angle = self->Angles.Yaw; + DAngle saved_pitch = self->Angles.Pitch; if (aim && self->target == NULL) { @@ -1925,63 +1917,68 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) if (aim) { - self->angle = self->AngleTo(self->target); + self->Angles.Yaw = self->AngleTo(self->target); } - self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &t, ANGLE_1*60, 0, aim ? self->target : NULL); + self->Angles.Pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE, &t, 60., 0, aim ? self->target : NULL); if (t.linetarget == NULL && aim) { // We probably won't hit the target, but aim at it anyway so we don't look stupid. - fixedvec2 pos = self->Vec2To(self->target); - DVector2 xydiff(pos.x, pos.y); - double zdiff = (self->target->Z() + (self->target->height>>1)) - - (self->Z() + (self->height>>1) - self->floorclip); - self->pitch = int(atan2(zdiff, xydiff.Length()) * ANGLE_180 / -M_PI); + DVector2 xydiff = self->Vec2To(self->target); + double zdiff = self->target->Center() - self->Center() - self->Floorclip; + self->Angles.Pitch = VecToAngle(xydiff.Length(), zdiff); } // Let the aim trail behind the player if (aim) { - saved_angle = self->angle = self->AngleTo(self->target, -self->target->vel.x * 3, -self->target->vel.y * 3); + saved_angle = self->Angles.Yaw = self->AngleTo(self->target, -self->target->Vel.X * 3, -self->target->Vel.Y * 3); if (aim == CRF_AIMDIRECT) { // Tricky: We must offset to the angle of the current position // but then change the angle again to ensure proper aim. self->SetXY(self->Vec2Offset( - spawnofs_xy * finecosine[self->angle], - spawnofs_xy * finesine[self->angle])); + spawnofs_xy * self->Angles.Yaw.Cos(), + spawnofs_xy * self->Angles.Yaw.Sin())); spawnofs_xy = 0; - self->angle = self->AngleTo(self->target,- self->target->vel.x * 3, -self->target->vel.y * 3); + self->Angles.Yaw = self->AngleTo(self->target,- self->target->Vel.X * 3, -self->target->Vel.Y * 3); } if (self->target->flags & MF_SHADOW) { - angle_t rnd = pr_crailgun.Random2() << 21; - self->angle += rnd; - saved_angle = rnd; + DAngle rnd = pr_crailgun.Random2() * (45. / 256.); + self->Angles.Yaw += rnd; } } - angle_t angle = (self->angle - ANG90) >> ANGLETOFINESHIFT; - - angle_t angleoffset; - angle_t slopeoffset; - - if (flags & CRF_EXPLICITANGLE) + if (!(flags & CRF_EXPLICITANGLE)) { - angleoffset = spread_xy; - slopeoffset = spread_z; - } - else - { - angleoffset = pr_crailgun.Random2() * (spread_xy / 255); - slopeoffset = pr_crailgun.Random2() * (spread_z / 255); + spread_xy = spread_xy * pr_crailgun.Random2() / 255; + spread_z = spread_z * pr_crailgun.Random2() / 255; } - P_RailAttack (self, damage, spawnofs_xy, spawnofs_z, color1, color2, maxdiff, flags, pufftype, angleoffset, slopeoffset, range, duration, sparsity, driftspeed, spawnclass,SpiralOffset); + FRailParams p; + p.source = self; + p.damage = damage; + p.offset_xy = spawnofs_xy; + p.offset_z = spawnofs_z; + p.color1 = color1; + p.color2 = color2; + p.maxdiff = maxdiff; + p.flags = flags; + p.puff = pufftype; + p.angleoffset = spread_xy; + p.pitchoffset = spread_z; + p.distance = range; + p.duration = duration; + p.sparsity = sparsity; + p.drift = driftspeed; + p.spawnclass = spawnclass; + p.SpiralOffset = SpiralOffset; + P_RailAttack(&p); self->SetXYZ(savedpos); - self->angle = saved_angle; - self->pitch = saved_pitch; + self->Angles.Yaw = saved_angle; + self->Angles.Pitch = saved_pitch; return 0; } @@ -2013,7 +2010,7 @@ static bool DoGiveInventory(AActor *receiver, bool orresult, VM_ARGS) } if (mi) { - AInventory *item = static_cast(Spawn(mi, 0, 0, 0, NO_REPLACE)); + AInventory *item = static_cast(Spawn(mi)); if (item == NULL) { return false; @@ -2243,10 +2240,10 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) mo->tracer = self->tracer; } - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; if (flags & SIXF_TRANSFERPITCH) { - mo->pitch = self->pitch; + mo->Angles.Pitch = self->Angles.Pitch; } if (!(flags & SIXF_ORIGINATOR)) { @@ -2324,8 +2321,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) } if (flags & SIXF_TRANSFERSCALE) { - mo->scaleX = self->scaleX; - mo->scaleY = self->scaleY; + mo->Scale = self->Scale; } if (flags & SIXF_TRANSFERAMBUSHFLAG) { @@ -2352,7 +2348,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) } if (flags & SIXF_TRANSFERALPHA) { - mo->alpha = self->alpha; + mo->Alpha = self->Alpha; } if (flags & SIXF_TRANSFERRENDERSTYLE) { @@ -2367,7 +2363,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) if (flags & SIXF_TRANSFERROLL) { - mo->roll = self->roll; + mo->Angles.Roll = self->Angles.Roll; } if (flags & SIXF_ISTARGET) @@ -2397,8 +2393,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem) { PARAM_ACTION_PROLOGUE; PARAM_CLASS_OPT (missile, AActor) { missile = PClass::FindActor("Unknown"); } - PARAM_FIXED_OPT (distance) { distance = 0; } - PARAM_FIXED_OPT (zheight) { zheight = 0; } + PARAM_FLOAT_OPT (distance) { distance = 0; } + PARAM_FLOAT_OPT (zheight) { zheight = 0; } PARAM_BOOL_OPT (useammo) { useammo = true; } PARAM_BOOL_OPT (transfer_translation) { transfer_translation = false; } @@ -2416,7 +2412,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem) if (distance == 0) { // use the minimum distance that does not result in an overlap - distance = (self->radius + GetDefaultByType(missile)->radius) >> FRACBITS; + distance = (self->radius + GetDefaultByType(missile)->radius); } if (ACTION_CALL_FROM_WEAPON()) @@ -2434,7 +2430,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem) } } - AActor *mo = Spawn( missile, self->Vec3Angle(distance, self->angle, -self->floorclip + self->GetBobOffset() + zheight), ALLOW_REPLACE); + AActor *mo = Spawn( missile, self->Vec3Angle(distance, self->Angles.Yaw, -self->Floorclip + self->GetBobOffset() + zheight), ALLOW_REPLACE); int flags = (transfer_translation ? SIXF_TRANSFERTRANSLATION : 0) + (useammo ? SIXF_SETMASTER : 0); ACTION_RETURN_BOOL(InitSpawnedItem(self, mo, flags)); // for an inventory item's use state @@ -2451,13 +2447,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (missile, AActor); - PARAM_FIXED_OPT (xofs) { xofs = 0; } - PARAM_FIXED_OPT (yofs) { yofs = 0; } - PARAM_FIXED_OPT (zofs) { zofs = 0; } - PARAM_FIXED_OPT (xvel) { xvel = 0; } - PARAM_FIXED_OPT (yvel) { yvel = 0; } - PARAM_FIXED_OPT (zvel) { zvel = 0; } - PARAM_ANGLE_OPT (angle) { angle = 0; } + PARAM_FLOAT_OPT (xofs) { xofs = 0; } + PARAM_FLOAT_OPT (yofs) { yofs = 0; } + PARAM_FLOAT_OPT (zofs) { zofs = 0; } + PARAM_FLOAT_OPT (xvel) { xvel = 0; } + PARAM_FLOAT_OPT (yvel) { yvel = 0; } + PARAM_FLOAT_OPT (zvel) { zvel = 0; } + PARAM_ANGLE_OPT (angle) { angle = 0.; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (chance) { chance = 0; } PARAM_INT_OPT (tid) { tid = 0; } @@ -2476,14 +2472,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) ACTION_RETURN_BOOL(true); } - fixedvec2 pos; + DVector2 pos; if (!(flags & SIXF_ABSOLUTEANGLE)) { - angle += self->angle; + angle += self->Angles.Yaw; } - - angle_t ang = angle >> ANGLETOFINESHIFT; + double s = angle.Sin(); + double c = angle.Cos(); if (flags & SIXF_ABSOLUTEPOSITION) { @@ -2493,20 +2489,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) { // in relative mode negative y values mean 'left' and positive ones mean 'right' // This is the inverse orientation of the absolute mode! - pos = self->Vec2Offset( - FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]), - FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang])); + pos = self->Vec2Offset(xofs * c + yofs * s, xofs * s - yofs*c); } if (!(flags & SIXF_ABSOLUTEVELOCITY)) { // Same orientation issue here! - fixed_t newxvel = FixedMul(xvel, finecosine[ang]) + FixedMul(yvel, finesine[ang]); - yvel = FixedMul(xvel, finesine[ang]) - FixedMul(yvel, finecosine[ang]); + double newxvel = xvel * c + yvel * s; + yvel = xvel * s - yvel * c; xvel = newxvel; } - AActor *mo = Spawn(missile, pos.x, pos.y, self->Z() - self->floorclip + self->GetBobOffset() + zofs, ALLOW_REPLACE); + AActor *mo = Spawn(missile, DVector3(pos, self->Z() - self->Floorclip + self->GetBobOffset() + zofs), ALLOW_REPLACE); bool res = InitSpawnedItem(self, mo, flags); if (res) { @@ -2516,19 +2510,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) mo->tid = tid; mo->AddToHash(); } + mo->Vel = {xvel, yvel, zvel}; if (flags & SIXF_MULTIPLYSPEED) { - mo->vel.x = FixedMul(xvel, mo->Speed); - mo->vel.y = FixedMul(yvel, mo->Speed); - mo->vel.z = FixedMul(zvel, mo->Speed); + mo->Vel *= mo->Speed; } - else - { - mo->vel.x = xvel; - mo->vel.y = yvel; - mo->vel.z = zvel; - } - mo->angle = angle; + mo->Angles.Yaw = angle; } ACTION_RETURN_BOOL(res); // for an inventory item's use state } @@ -2544,9 +2531,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (missile, AActor); - PARAM_FIXED_OPT (zheight) { zheight = 0; } - PARAM_FIXED_OPT (xyvel) { xyvel = 0; } - PARAM_FIXED_OPT (zvel) { zvel = 0; } + PARAM_FLOAT_OPT (zheight) { zheight = 0; } + PARAM_FLOAT_OPT (xyvel) { xyvel = 0; } + PARAM_FLOAT_OPT (zvel) { zvel = 0; } PARAM_BOOL_OPT (useammo) { useammo = true; } if (missile == NULL) @@ -2571,36 +2558,36 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade) AActor *bo; bo = Spawn(missile, - self->PosPlusZ(-self->floorclip + self->GetBobOffset() + zheight + 35*FRACUNIT + (self->player? self->player->crouchoffset : 0)), + self->PosPlusZ(-self->Floorclip + self->GetBobOffset() + zheight + 35 + (self->player? self->player->crouchoffset : 0.)), ALLOW_REPLACE); if (bo) { P_PlaySpawnSound(bo, self); if (xyvel != 0) bo->Speed = xyvel; - bo->angle = self->angle + (((pr_grenade()&7) - 4) << 24); + bo->Angles.Yaw = self->Angles.Yaw + (((pr_grenade()&7) - 4) * (360./256.)); - angle_t pitch = angle_t(-self->pitch) >> ANGLETOFINESHIFT; - angle_t angle = bo->angle >> ANGLETOFINESHIFT; + DAngle pitch = -self->Angles.Pitch; + DAngle angle = bo->Angles.Yaw; // There are two vectors we are concerned about here: xy and z. We rotate // them separately according to the shooter's pitch and then sum them to // get the final velocity vector to shoot with. - fixed_t xy_xyscale = FixedMul(bo->Speed, finecosine[pitch]); - fixed_t xy_velz = FixedMul(bo->Speed, finesine[pitch]); - fixed_t xy_velx = FixedMul(xy_xyscale, finecosine[angle]); - fixed_t xy_vely = FixedMul(xy_xyscale, finesine[angle]); + double xy_xyscale = bo->Speed * pitch.Cos(); + double xy_velz = bo->Speed * pitch.Sin(); + double xy_velx = xy_xyscale * angle.Cos(); + double xy_vely = xy_xyscale * angle.Sin(); - pitch = angle_t(self->pitch) >> ANGLETOFINESHIFT; - fixed_t z_xyscale = FixedMul(zvel, finesine[pitch]); - fixed_t z_velz = FixedMul(zvel, finecosine[pitch]); - fixed_t z_velx = FixedMul(z_xyscale, finecosine[angle]); - fixed_t z_vely = FixedMul(z_xyscale, finesine[angle]); + pitch = self->Angles.Pitch; + double z_xyscale = zvel * pitch.Sin(); + double z_velz = zvel * pitch.Cos(); + double z_velx = z_xyscale * angle.Cos(); + double z_vely = z_xyscale * angle.Sin(); - bo->vel.x = xy_velx + z_velx + (self->vel.x >> 1); - bo->vel.y = xy_vely + z_vely + (self->vel.y >> 1); - bo->vel.z = xy_velz + z_velz; + bo->Vel.X = xy_velx + z_velx + self->Vel.X / 2; + bo->Vel.Y = xy_vely + z_vely + self->Vel.Y / 2; + bo->Vel.Z = xy_velz + z_velz; bo->target = self; P_CheckMissileSpawn (bo, self->radius); @@ -2621,12 +2608,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Recoil) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(xyvel); + PARAM_FLOAT(xyvel); - angle_t angle = self->angle + ANG180; - angle >>= ANGLETOFINESHIFT; - self->vel.x += FixedMul(xyvel, finecosine[angle]); - self->vel.y += FixedMul(xyvel, finesine[angle]); + self->Thrust(self->Angles.Yaw + 180., xyvel); return 0; } @@ -2785,13 +2769,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LogFloat) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTranslucent) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED (alpha); + PARAM_FLOAT (alpha); PARAM_INT_OPT (mode) { mode = 0; } mode = mode == 0 ? STYLE_Translucent : mode == 2 ? STYLE_Fuzzy : STYLE_Add; self->RenderStyle.Flags &= ~STYLEF_Alpha1; - self->alpha = clamp(alpha, 0, FRACUNIT); + self->Alpha = clamp(alpha, 0., 1.); self->RenderStyle = ERenderStyle(mode); return 0; } @@ -2813,21 +2797,21 @@ enum FadeFlags DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeIn) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED_OPT(reduce) { reduce = FRACUNIT/10; } + PARAM_FLOAT_OPT(reduce) { reduce = 0.1; } PARAM_INT_OPT(flags) { flags = 0; } if (reduce == 0) { - reduce = FRACUNIT / 10; + reduce = 0.1; } self->RenderStyle.Flags &= ~STYLEF_Alpha1; - self->alpha += reduce; + self->Alpha += reduce; - if (self->alpha >= FRACUNIT) + if (self->Alpha >= 1.) { if (flags & FTF_CLAMP) { - self->alpha = FRACUNIT; + self->Alpha = 1.; } if (flags & FTF_REMOVE) { @@ -2847,20 +2831,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeIn) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeOut) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED_OPT(reduce) { reduce = FRACUNIT/10; } + PARAM_FLOAT_OPT(reduce) { reduce = 0.1; } PARAM_INT_OPT(flags) { flags = FTF_REMOVE; } if (reduce == 0) { - reduce = FRACUNIT/10; + reduce = 0.1; } self->RenderStyle.Flags &= ~STYLEF_Alpha1; - self->alpha -= reduce; - if (self->alpha <= 0) + self->Alpha -= reduce; + if (self->Alpha <= 0) { if (flags & FTF_CLAMP) { - self->alpha = 0; + self->Alpha = 0; } if (flags & FTF_REMOVE) { @@ -2881,35 +2865,35 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeOut) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeTo) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED (target); - PARAM_FIXED_OPT (amount) { amount = fixed_t(0.1*FRACUNIT); } + PARAM_FLOAT (target); + PARAM_FLOAT_OPT (amount) { amount = 0.1; } PARAM_INT_OPT (flags) { flags = 0; } self->RenderStyle.Flags &= ~STYLEF_Alpha1; - if (self->alpha > target) + if (self->Alpha > target) { - self->alpha -= amount; + self->Alpha -= amount; - if (self->alpha < target) + if (self->Alpha < target) { - self->alpha = target; + self->Alpha = target; } } - else if (self->alpha < target) + else if (self->Alpha < target) { - self->alpha += amount; + self->Alpha += amount; - if (self->alpha > target) + if (self->Alpha > target) { - self->alpha = target; + self->Alpha = target; } } if (flags & FTF_CLAMP) { - self->alpha = clamp(self->alpha, 0, FRACUNIT); + self->Alpha = clamp(self->Alpha, 0., 1.); } - if (self->alpha == target && (flags & FTF_REMOVE)) + if (self->Alpha == target && (flags & FTF_REMOVE)) { P_RemoveThing(self); } @@ -2926,8 +2910,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeTo) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetScale) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED (scalex); - PARAM_FIXED_OPT (scaley) { scaley = scalex; } + PARAM_FLOAT (scalex); + PARAM_FLOAT_OPT (scaley) { scaley = scalex; } PARAM_INT_OPT (ptr) { ptr = AAPTR_DEFAULT; } PARAM_BOOL_OPT (usezero) { usezero = false; } @@ -2939,8 +2923,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetScale) { scaley = scalex; } - ref->scaleX = scalex; - ref->scaleY = scaley; + ref->Scale = { scalex, scaley }; } return 0; } @@ -2971,8 +2954,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris) PARAM_ACTION_PROLOGUE; PARAM_CLASS (debris, AActor); PARAM_BOOL_OPT (transfer_translation) { transfer_translation = false; } - PARAM_FIXED_OPT (mult_h) { mult_h = FRACUNIT; } - PARAM_FIXED_OPT (mult_v) { mult_v = FRACUNIT; } + PARAM_FLOAT_OPT (mult_h) { mult_h = 1; } + PARAM_FLOAT_OPT (mult_v) { mult_v = 1; } int i; AActor *mo; @@ -2980,16 +2963,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris) return 0; // only positive values make sense here - if (mult_v <= 0) - mult_v = FRACUNIT; - if (mult_h <= 0) - mult_h = FRACUNIT; + if (mult_v <= 0) mult_v = 1; + if (mult_h <= 0) mult_h = 1; for (i = 0; i < GetDefaultByType(debris)->health; i++) { - fixed_t xo = ((pr_spawndebris() - 128) << 12); - fixed_t yo = ((pr_spawndebris() - 128) << 12); - fixed_t zo = (pr_spawndebris()*self->height / 256 + self->GetBobOffset()); + double xo = (pr_spawndebris() - 128) / 16.; + double yo = (pr_spawndebris() - 128) / 16.; + double zo = pr_spawndebris()*self->Height / 256 + self->GetBobOffset(); mo = Spawn(debris, self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { @@ -3001,9 +2982,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris) { mo->SetState (mo->GetClass()->OwnedStates + i); } - mo->vel.z = FixedMul(mult_v, ((pr_spawndebris()&7)+5)*FRACUNIT); - mo->vel.x = FixedMul(mult_h, pr_spawndebris.Random2()<<(FRACBITS-6)); - mo->vel.y = FixedMul(mult_h, pr_spawndebris.Random2()<<(FRACBITS-6)); + mo->Vel.X = mult_h * pr_spawndebris.Random2() / 64.; + mo->Vel.Y = mult_h * pr_spawndebris.Random2() / 64.; + mo->Vel.Z = mult_v * ((pr_spawndebris() & 7) + 5); } } return 0; @@ -3030,51 +3011,50 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnParticle) PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (lifetime) { lifetime = 35; } PARAM_INT_OPT (size) { size = 1; } - PARAM_ANGLE_OPT (angle) { angle = 0; } - PARAM_FIXED_OPT (xoff) { xoff = 0; } - PARAM_FIXED_OPT (yoff) { yoff = 0; } - PARAM_FIXED_OPT (zoff) { zoff = 0; } - PARAM_FIXED_OPT (xvel) { xvel = 0; } - PARAM_FIXED_OPT (yvel) { yvel = 0; } - PARAM_FIXED_OPT (zvel) { zvel = 0; } - PARAM_FIXED_OPT (accelx) { accelx = 0; } - PARAM_FIXED_OPT (accely) { accely = 0; } - PARAM_FIXED_OPT (accelz) { accelz = 0; } - PARAM_FIXED_OPT (startalphaf) { startalphaf = FRACUNIT; } - PARAM_FIXED_OPT (fadestepf) { fadestepf = -FRACUNIT; } + PARAM_ANGLE_OPT (angle) { angle = 0.; } + PARAM_FLOAT_OPT (xoff) { xoff = 0; } + PARAM_FLOAT_OPT (yoff) { yoff = 0; } + PARAM_FLOAT_OPT (zoff) { zoff = 0; } + PARAM_FLOAT_OPT (xvel) { xvel = 0; } + PARAM_FLOAT_OPT (yvel) { yvel = 0; } + PARAM_FLOAT_OPT (zvel) { zvel = 0; } + PARAM_FLOAT_OPT (accelx) { accelx = 0; } + PARAM_FLOAT_OPT (accely) { accely = 0; } + PARAM_FLOAT_OPT (accelz) { accelz = 0; } + PARAM_FLOAT_OPT (startalpha) { startalpha = 1.; } + PARAM_FLOAT_OPT (fadestep) { fadestep = -1.; } - BYTE startalpha = (BYTE)(clamp(startalphaf, 0, FRACUNIT) * 255 / FRACUNIT); - int fadestep = fadestepf < 0 ? -1 : clamp(fadestepf, 0, FRACUNIT) * 255 / FRACUNIT; - lifetime = clamp(lifetime, 0, 255); // Clamp to byte + startalpha = clamp(startalpha, 0., 1.); + if (fadestep > 0) fadestep = clamp(fadestep, 0., 1.); size = clamp(size, 0, 65535); // Clamp to word if (lifetime != 0) { - const angle_t ang = (angle + ((flags & SPF_RELANG) ? self->angle : 0)) >> ANGLETOFINESHIFT; - fixedvec3 pos; + if (flags & SPF_RELANG) angle += self->Angles.Yaw; + double s = angle.Sin(); + double c = angle.Cos(); + DVector3 pos(xoff, yoff, zoff); + DVector3 vel(xvel, yvel, zvel); + DVector3 acc(accelx, accely, accelz); //[MC] Code ripped right out of A_SpawnItemEx. if (flags & SPF_RELPOS) { // in relative mode negative y values mean 'left' and positive ones mean 'right' // This is the inverse orientation of the absolute mode! - const fixed_t xof1 = xoff; - xoff = FixedMul(xof1, finecosine[ang]) + FixedMul(yoff, finesine[ang]); - yoff = FixedMul(xof1, finesine[ang]) - FixedMul(yoff, finecosine[ang]); + pos.X = xoff * c + yoff * s; + pos.Y = xoff * s - yoff * c; } if (flags & SPF_RELVEL) { - const fixed_t newxvel = FixedMul(xvel, finecosine[ang]) + FixedMul(yvel, finesine[ang]); - yvel = FixedMul(xvel, finesine[ang]) - FixedMul(yvel, finecosine[ang]); - xvel = newxvel; + vel.X = xvel * c + yvel * s; + vel.Y = xvel * s - yvel * c; } if (flags & SPF_RELACCEL) { - fixed_t newaccelx = FixedMul(accelx, finecosine[ang]) + FixedMul(accely, finesine[ang]); - accely = FixedMul(accelx, finesine[ang]) - FixedMul(accely, finecosine[ang]); - accelx = newaccelx; + acc.X = accelx * c + accely * s; + acc.Y = accelx * s - accely * c; } - pos = self->Vec3Offset(xoff, yoff, zoff); - P_SpawnParticle(pos.x, pos.y, pos.z, xvel, yvel, zvel, color, !!(flags & SPF_FULLBRIGHT), startalpha, lifetime, size, fadestep, accelx, accely, accelz); + P_SpawnParticle(self->Vec3Offset(pos), vel, acc, color, !!(flags & SPF_FULLBRIGHT), startalpha, lifetime, size, fadestep); } return 0; } @@ -3117,16 +3097,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight) // Useful for maps with many multi-actor special effects. // //=========================================================================== -static bool DoCheckSightOrRange(AActor *self, AActor *camera, double range, bool twodi) +static bool DoCheckSightOrRange(AActor *self, AActor *camera, double range, bool twodi, bool checksight) { if (camera == NULL) { return false; } // Check distance first, since it's cheaper than checking sight. - fixedvec2 pos = camera->Vec2To(self); - fixed_t dz; - fixed_t eyez = (camera->Top() - (camera->height>>2)); // same eye height as P_CheckSight + DVector2 pos = camera->Vec2To(self); + double dz; + double eyez = camera->Center(); if (eyez > self->Top()) { dz = self->Top() - eyez; @@ -3139,14 +3119,15 @@ static bool DoCheckSightOrRange(AActor *self, AActor *camera, double range, bool { dz = 0; } - double distance = ((double)pos.x * pos.x) + ((double)pos.y * pos.y) + (twodi == 0? ((double)dz * dz) : 0); - if (distance <= range){ + double distance = DVector3(pos, twodi? 0. : dz).LengthSquared(); + if (distance <= range*range) + { // Within range return true; } // Now check LOS. - if (P_CheckSight(camera, self, SF_IGNOREVISIBILITY)) + if (checksight && P_CheckSight(camera, self, SF_IGNOREVISIBILITY)) { // Visible return true; } @@ -3160,19 +3141,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange) PARAM_STATE(jump); PARAM_BOOL_OPT(twodi) { twodi = false; } - range = range * range * (double(FRACUNIT) * FRACUNIT); // no need for square roots + range *= range; for (int i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i]) { // Always check from each player. - if (DoCheckSightOrRange(self, players[i].mo, range, twodi)) + if (DoCheckSightOrRange(self, players[i].mo, range, twodi, true)) { ACTION_RETURN_STATE(NULL); } // If a player is viewing from a non-player, check that too. if (players[i].camera != NULL && players[i].camera->player == NULL && - DoCheckSightOrRange(self, players[i].camera, range, twodi)) + DoCheckSightOrRange(self, players[i].camera, range, twodi, true)) { ACTION_RETURN_STATE(NULL); } @@ -3181,42 +3162,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange) ACTION_RETURN_STATE(jump); } -//=========================================================================== -// -// A_CheckRange -// Jumps if this actor is out of range of all players. -// -//=========================================================================== -static bool DoCheckRange(AActor *self, AActor *camera, double range, bool twodi) -{ - if (camera == NULL) - { - return false; - } - // Check distance first, since it's cheaper than checking sight. - fixedvec2 pos = camera->Vec2To(self); - fixed_t dz; - fixed_t eyez = (camera->Top() - (camera->height>>2)); // same eye height as P_CheckSight - if (eyez > self->Top()) - { - dz = self->Top() - eyez; - } - else if (eyez < self->Z()) - { - dz = self->Z() - eyez; - } - else - { - dz = 0; - } - double distance = ((double)pos.x * pos.x) + ((double)pos.y * pos.y) + (twodi == 0? ((double)dz * dz) : 0); - - if (distance <= range){ - // Within range - return true; - } - return false; -} DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckRange) { @@ -3225,19 +3170,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckRange) PARAM_STATE(jump); PARAM_BOOL_OPT(twodi) { twodi = false; } - range = range * range * (double(FRACUNIT) * FRACUNIT); // no need for square roots + range *= range; for (int i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i]) { // Always check from each player. - if (DoCheckRange(self, players[i].mo, range, twodi)) + if (DoCheckSightOrRange(self, players[i].mo, range, twodi, false)) { ACTION_RETURN_STATE(NULL); } // If a player is viewing from a non-player, check that too. if (players[i].camera != NULL && players[i].camera->player == NULL && - DoCheckRange(self, players[i].camera, range, twodi)) + DoCheckSightOrRange(self, players[i].camera, range, twodi, false)) { ACTION_RETURN_STATE(NULL); } @@ -3360,30 +3305,30 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Burst) return 0; } - self->vel.x = self->vel.y = self->vel.z = 0; - self->height = self->GetDefault()->height; + self->Vel.Zero(); + self->Height = self->GetDefault()->Height; // [RH] In Hexen, this creates a random number of shards (range [24,56]) // with no relation to the size of the self shattering. I think it should // base the number of shards on the size of the dead thing, so bigger // things break up into more shards than smaller things. // An self with radius 20 and height 64 creates ~40 chunks. - numChunks = MAX (4, (self->radius>>FRACBITS)*(self->height>>FRACBITS)/32); + numChunks = MAX (4, int(self->radius * self->Height)/32); i = (pr_burst.Random2()) % (numChunks/4); for (i = MAX (24, numChunks + i); i >= 0; i--) { - fixed_t xo = (((pr_burst() - 128)*self->radius) >> 7); - fixed_t yo = (((pr_burst() - 128)*self->radius) >> 7); - fixed_t zo = (pr_burst()*self->height / 255 + self->GetBobOffset()); + double xo = (pr_burst() - 128) * self->radius / 128; + double yo = (pr_burst() - 128) * self->radius / 128; + double zo = (pr_burst() * self->Height / 255); mo = Spawn(chunk, self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { - mo->vel.z = FixedDiv(mo->Z() - self->Z(), self->height)<<2; - mo->vel.x = pr_burst.Random2 () << (FRACBITS-7); - mo->vel.y = pr_burst.Random2 () << (FRACBITS-7); + mo->Vel.Z = 4 * (mo->Z() - self->Z()) * self->Height; + mo->Vel.X = pr_burst.Random2() / 128.; + mo->Vel.Y = pr_burst.Random2() / 128.; mo->RenderStyle = self->RenderStyle; - mo->alpha = self->alpha; + mo->Alpha = self->Alpha; mo->CopyFriendliness(self, true); } } @@ -3445,11 +3390,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckCeiling) DEFINE_ACTION_FUNCTION(AActor, A_Stop) { PARAM_ACTION_PROLOGUE; - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); if (self->player && self->player->mo == self && !(self->player->cheats & CF_PREDICTING)) { self->player->mo->PlayIdle(); - self->player->vel.x = self->player->vel.y = 0; + self->player->Vel.Zero(); } return 0; } @@ -3458,11 +3403,10 @@ static void CheckStopped(AActor *self) { if (self->player != NULL && self->player->mo == self && - !(self->player->cheats & CF_PREDICTING) && - !(self->vel.x | self->vel.y | self->vel.z)) + !(self->player->cheats & CF_PREDICTING) && !self->Vel.isZero()) { self->player->mo->PlayIdle(); - self->player->vel.x = self->player->vel.y = 0; + self->player->Vel.Zero(); } } @@ -3487,10 +3431,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn) PARAM_INT_OPT(flags) { flags = RSF_FOG; } bool oktorespawn = false; - fixedvec3 pos = self->Pos(); + DVector3 pos = self->Pos(); self->flags |= MF_SOLID; - self->height = self->GetDefault()->height; + self->Height = self->GetDefault()->Height; self->radius = self->GetDefault()->radius; CALL_ACTION(A_RestoreSpecialPosition, self); @@ -3501,7 +3445,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn) } else { - oktorespawn = P_CheckPosition(self, self->X(), self->Y(), true); + oktorespawn = P_CheckPosition(self, self->Pos(), true); } if (oktorespawn) @@ -3581,9 +3525,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlayerSkinCheck) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetGravity) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(gravity); + PARAM_FLOAT(gravity); - self->gravity = clamp(gravity, 0, FRACUNIT*10); + self->Gravity = clamp(gravity, 0., 10.); return 0; } @@ -3742,142 +3686,132 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) */ AActor *target; - fixedvec3 pos; - fixed_t vx, vy, vz; + DVector3 pos; + DVector3 vel; PARAM_ACTION_PROLOGUE; PARAM_STATE (jump); PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (range) { range = 0; } - PARAM_FIXED_OPT (minrange) { minrange = 0; } + PARAM_FLOAT_OPT (range) { range = 0; } + PARAM_FLOAT_OPT (minrange) { minrange = 0; } + PARAM_ANGLE_OPT (angle) { angle = 0.; } + PARAM_ANGLE_OPT (pitch) { pitch = 0.; } + PARAM_FLOAT_OPT (offsetheight) { offsetheight = 0; } + PARAM_FLOAT_OPT (offsetwidth) { offsetwidth = 0; } + PARAM_INT_OPT (ptr_target) { ptr_target = AAPTR_DEFAULT; } + PARAM_FLOAT_OPT (offsetforward) { offsetforward = 0; } + + DAngle ang; + + target = COPY_AAPTR(self, ptr_target == AAPTR_DEFAULT ? AAPTR_TARGET|AAPTR_PLAYER_GETTARGET|AAPTR_NULL : ptr_target); // no player-support by default + + if (flags & CLOFF_MUL_HEIGHT) { - PARAM_ANGLE_OPT (angle) { angle = 0; } - PARAM_ANGLE_OPT (pitch) { pitch = 0; } - PARAM_FIXED_OPT (offsetheight) { offsetheight = 0; } - PARAM_FIXED_OPT (offsetwidth) { offsetwidth = 0; } - PARAM_INT_OPT (ptr_target) { ptr_target = AAPTR_DEFAULT; } - PARAM_FIXED_OPT (offsetforward) { offsetforward = 0; } - - target = COPY_AAPTR(self, ptr_target == AAPTR_DEFAULT ? AAPTR_TARGET|AAPTR_PLAYER_GETTARGET|AAPTR_NULL : ptr_target); // no player-support by default - - if (flags & CLOFF_MUL_HEIGHT) + if (self->player != NULL) { - if (self->player != NULL) - { - // Synced with hitscan: self->player->mo->height is strangely conscientious about getting the right actor for player - offsetheight = FixedMul(offsetheight, FixedMul (self->player->mo->height, self->player->crouchfactor)); - } - else - { - offsetheight = FixedMul(offsetheight, self->height); - } + // Synced with hitscan: self->player->mo->height is strangely conscientious about getting the right actor for player + offsetheight *= self->player->mo->Height * self->player->crouchfactor; } - if (flags & CLOFF_MUL_WIDTH) + else { - offsetforward = FixedMul(self->radius, offsetforward); - offsetwidth = FixedMul(self->radius, offsetwidth); + offsetheight *= self->Height; } + } + if (flags & CLOFF_MUL_WIDTH) + { + offsetforward *= self->radius; + offsetwidth *= self->radius; +} - pos = self->PosPlusZ(offsetheight - self->floorclip); + pos = self->PosPlusZ(offsetheight - self->Floorclip); if (!(flags & CLOFF_FROMBASE)) { // default to hitscan origin - // Synced with hitscan: self->height is strangely NON-conscientious about getting the right actor for player - pos.z += (self->height >> 1); + // Synced with hitscan: self->Height is strangely NON-conscientious about getting the right actor for player + pos.Z += self->Height *0.5; if (self->player != NULL) { - pos.z += FixedMul (self->player->mo->AttackZOffset, self->player->crouchfactor); + pos.Z += self->player->mo->AttackZOffset * self->player->crouchfactor; } else { - pos.z += 8*FRACUNIT; + pos.Z += 8; } } if (target) { - fixed_t xydist = self->Distance2D(target); - fixed_t distance = P_AproxDistance(xydist, target->Z() - pos.z); - - if (range && !(flags & CLOFF_CHECKPARTIAL)) + if (range > 0 && !(flags & CLOFF_CHECKPARTIAL)) { + double distance = self->Distance3D(target); if (distance > range) { ACTION_RETURN_STATE(NULL); } } + if (flags & CLOFF_NOAIM_HORZ) { - angle_t ang; - - if (flags & CLOFF_NOAIM_HORZ) - { - ang = self->angle; - } - else ang = self->AngleTo (target); - - angle += ang; - - ang >>= ANGLETOFINESHIFT; - - fixedvec2 xy = self->Vec2Offset( - FixedMul(offsetforward, finecosine[ang]) + FixedMul(offsetwidth, finesine[ang]), - FixedMul(offsetforward, finesine[ang]) - FixedMul(offsetwidth, finecosine[ang])); - - pos.x = xy.x; - pos.y = xy.y; + ang = self->Angles.Yaw; } + else ang = self->AngleTo (target); + + angle += ang; + double s = ang.Sin(); + double c = ang.Cos(); + + DVector2 xy = self->Vec2Offset(offsetforward * c + offsetwidth * s, offsetforward * s - offsetwidth * c); + + pos.X = xy.X; + pos.Y = xy.Y; + + double xydist = self->Distance2D(target); if (flags & CLOFF_NOAIM_VERT) { - pitch += self->pitch; + pitch += self->Angles.Pitch; } else if (flags & CLOFF_AIM_VERT_NOOFFSET) { - pitch -= R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + offsetheight + target->height / 2); + pitch -= VecToAngle(xydist, target->Center() - pos.Z + offsetheight); } else { - pitch -= R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + target->height / 2); + pitch -= VecToAngle(xydist, target->Center() - pos.Z); } } else if (flags & CLOFF_ALLOWNULL) { - angle += self->angle; - pitch += self->pitch; + angle += self->Angles.Yaw; + pitch += self->Angles.Pitch; - angle_t ang = self->angle >> ANGLETOFINESHIFT; + double s = angle.Sin(); + double c = angle.Cos(); - fixedvec2 xy = self->Vec2Offset( - FixedMul(offsetforward, finecosine[ang]) + FixedMul(offsetwidth, finesine[ang]), - FixedMul(offsetforward, finesine[ang]) - FixedMul(offsetwidth, finecosine[ang])); + DVector2 xy = self->Vec2Offset(offsetforward * c + offsetwidth * s, offsetforward * s - offsetwidth * c); - pos.x = xy.x; - pos.y = xy.y; + pos.X = xy.X; + pos.Y = xy.Y; } else { ACTION_RETURN_STATE(NULL); } - angle >>= ANGLETOFINESHIFT; - pitch >>= ANGLETOFINESHIFT; + double cp = pitch.Cos(); - vx = FixedMul (finecosine[pitch], finecosine[angle]); - vy = FixedMul (finecosine[pitch], finesine[angle]); - vz = -finesine[pitch]; - } + vel = { cp * angle.Cos(), cp * angle.Sin(), -pitch.Sin() }; /* Variable set: jump, flags, target - x1,y1,z1 (trace point of origin) - vx,vy,vz (trace unit vector) + pos (trace point of origin) + vel (trace unit vector) range */ - sector_t *sec = P_PointInSector(pos.x, pos.y); + sector_t *sec = P_PointInSector(pos); if (range == 0) { @@ -3892,7 +3826,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) lof_data.Flags = flags; lof_data.BadActor = false; - Trace(pos.x, pos.y, pos.z, sec, vx, vy, vz, range, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, TRACE_PortalRestrict, + Trace(pos, sec, vel, range, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, TRACE_PortalRestrict, CheckLOFTraceFunc, &lof_data); if (trace.HitType == TRACE_HitActor || @@ -3949,12 +3883,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) { PARAM_ACTION_PROLOGUE; PARAM_STATE (jump); - PARAM_ANGLE_OPT (fov) { fov = 0; } + PARAM_ANGLE_OPT (fov) { fov = 0.; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (dist_max) { dist_max = 0; } - PARAM_FIXED_OPT (dist_close) { dist_close = 0; } + PARAM_FLOAT_OPT (dist_max) { dist_max = 0; } + PARAM_FLOAT_OPT (dist_close) { dist_close = 0; } - angle_t an; AActor *target, *viewport; FTranslatedLineTarget t; @@ -3992,7 +3925,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) else { // Does the player aim at something that can be shot? - P_AimLineAttack(self, self->angle, MISSILERANGE, &t, (flags & JLOSF_NOAUTOAIM) ? ANGLE_1/2 : 0, ALF_PORTALRESTRICT); + P_AimLineAttack(self, self->Angles.Yaw, MISSILERANGE, &t, (flags & JLOSF_NOAUTOAIM) ? 0.5 : 0., ALF_PORTALRESTRICT); if (!t.linetarget) { @@ -4004,14 +3937,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) { case JLOSF_TARGETLOS|JLOSF_FLIPFOV: // target makes sight check, player makes fov check; player has verified fov - fov = 0; + fov = 0.; // fall-through case JLOSF_TARGETLOS: doCheckSight = !(flags & JLOSF_NOSIGHT); // The target is responsible for sight check and fov break; default: // player has verified sight and fov - fov = 0; + fov = 0.; // fall-through case JLOSF_FLIPFOV: // Player has verified sight, but target must verify fov doCheckSight = false; @@ -4029,7 +3962,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) { ACTION_RETURN_STATE(NULL); } - fixed_t distance = self->AproxDistance3D(target); + double distance = self->Distance3D(target); if (dist_max && (distance > dist_max)) { @@ -4042,7 +3975,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) ACTION_RETURN_STATE(NULL); } if (flags & JLOSF_CLOSENOFOV) - fov = 0; + fov = 0.; if (flags & JLOSF_CLOSENOSIGHT) doCheckSight = false; @@ -4062,11 +3995,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) else { target = viewport; viewport = self; } } - if (fov && (fov < ANGLE_MAX)) + if (fov > 0 && (fov < 360.)) { - an = viewport->AngleTo(target) - viewport->angle; + DAngle an = absangle(viewport->AngleTo(target), viewport->Angles.Yaw); - if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) + if (an > (fov / 2)) { ACTION_RETURN_STATE(NULL); // [KS] Outside of FOV - return } @@ -4086,12 +4019,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS) { PARAM_ACTION_PROLOGUE; PARAM_STATE (jump); - PARAM_ANGLE_OPT (fov) { fov = 0; } + PARAM_ANGLE_OPT (fov) { fov = 0.; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (dist_max) { dist_max = 0; } - PARAM_FIXED_OPT (dist_close) { dist_close = 0; } + PARAM_FLOAT_OPT (dist_max) { dist_max = 0; } + PARAM_FLOAT_OPT (dist_close) { dist_close = 0; } - angle_t an; AActor *target; if (flags & JLOSF_CHECKMASTER) @@ -4120,7 +4052,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS) ACTION_RETURN_STATE(NULL); } - fixed_t distance = self->AproxDistance3D(target); + double distance = self->Distance3D(target); if (dist_max && (distance > dist_max)) { @@ -4136,17 +4068,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS) ACTION_RETURN_STATE(NULL); } if (flags & JLOSF_CLOSENOFOV) - fov = 0; + fov = 0.; if (flags & JLOSF_CLOSENOSIGHT) doCheckSight = false; } - if (fov && (fov < ANGLE_MAX)) + if (fov > 0 && (fov < 360.)) { - an = target->AngleTo(self) - target->angle; + DAngle an = absangle(target->AngleTo(self), target->Angles.Yaw); - if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) + if (an > (fov / 2)) { ACTION_RETURN_STATE(NULL); // [KS] Outside of FOV - return } @@ -4427,8 +4359,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_RaiseSiblings) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_FaceConsolePlayer) { - PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(max_turn_angle) { max_turn_angle = 0; } // NOTE: It does nothing for zdoom. return 0; } @@ -4479,7 +4409,7 @@ enum DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetAngle) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(angle) { angle = 0; } + PARAM_FLOAT_OPT(angle) { angle = 0; } PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } @@ -4502,7 +4432,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetAngle) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE(pitch); + PARAM_FLOAT(pitch); PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } @@ -4513,23 +4443,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) return 0; } - if (ref->player != NULL || (flags & SPF_FORCECLAMP)) - { // clamp the pitch we set - int min, max; - - if (ref->player != NULL) - { - min = ref->player->MinPitch; - max = ref->player->MaxPitch; - } - else - { - min = -ANGLE_90 + (1 << ANGLETOFINESHIFT); - max = ANGLE_90 - (1 << ANGLETOFINESHIFT); - } - pitch = clamp(pitch, min, max); - } - ref->SetPitch(pitch, !!(flags & SPF_INTERPOLATE), !!(flags & SPF_FORCECLAMP)); return 0; } @@ -4545,7 +4458,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRoll) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE (roll); + PARAM_FLOAT (roll); PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -4568,7 +4481,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRoll) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ScaleVelocity) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(scale); + PARAM_FLOAT(scale); PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -4578,11 +4491,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ScaleVelocity) return 0; } - INTBOOL was_moving = ref->vel.x | ref->vel.y | ref->vel.z; + bool was_moving = !ref->Vel.isZero(); - ref->vel.x = FixedMul(ref->vel.x, scale); - ref->vel.y = FixedMul(ref->vel.y, scale); - ref->vel.z = FixedMul(ref->vel.z, scale); + ref->Vel *= scale; // If the actor was previously moving but now is not, and is a player, // update its player variables. (See A_Stop.) @@ -4602,9 +4513,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ScaleVelocity) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeVelocity) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED_OPT (x) { x = 0; } - PARAM_FIXED_OPT (y) { y = 0; } - PARAM_FIXED_OPT (z) { z = 0; } + PARAM_FLOAT_OPT (x) { x = 0; } + PARAM_FLOAT_OPT (y) { y = 0; } + PARAM_FLOAT_OPT (z) { z = 0; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (ptr) { ptr = AAPTR_DEFAULT; } @@ -4615,28 +4526,24 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeVelocity) return 0; } - INTBOOL was_moving = ref->vel.x | ref->vel.y | ref->vel.z; + INTBOOL was_moving = !ref->Vel.isZero(); - fixed_t vx = x, vy = y, vz = z; - fixed_t sina = finesine[ref->angle >> ANGLETOFINESHIFT]; - fixed_t cosa = finecosine[ref->angle >> ANGLETOFINESHIFT]; + DVector3 vel(x, y, z); + double sina = ref->Angles.Yaw.Sin(); + double cosa = ref->Angles.Yaw.Cos(); if (flags & 1) // relative axes - make x, y relative to actor's current angle { - vx = DMulScale16(x, cosa, -y, sina); - vy = DMulScale16(x, sina, y, cosa); + vel.X = x*cosa - y*sina; + vel.Y = x*sina + y*cosa; } if (flags & 2) // discard old velocity - replace old velocity with new velocity { - ref->vel.x = vx; - ref->vel.y = vy; - ref->vel.z = vz; + ref->Vel = vel; } else // add new velocity to old velocity { - ref->vel.x += vx; - ref->vel.y += vy; - ref->vel.z += vz; + ref->Vel += vel; } if (was_moving) @@ -4835,8 +4742,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) PARAM_CLASS_OPT (target_type, ASpecialSpot) { target_type = PClass::FindActor("BossSpot"); } PARAM_CLASS_OPT (fog_type, AActor) { fog_type = PClass::FindActor("TeleportFog"); } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (mindist) { mindist = 128 << FRACBITS; } - PARAM_FIXED_OPT (maxdist) { maxdist = 128 << FRACBITS; } + PARAM_FLOAT_OPT (mindist) { mindist = 128; } + PARAM_FLOAT_OPT (maxdist) { maxdist = 0; } PARAM_INT_OPT (ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -4907,28 +4814,30 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) // of the spot. if (flags & TF_SENSITIVEZ) { - fixed_t posz = (flags & TF_USESPOTZ) ? spot->Z() : spot->floorz; - if ((posz + ref->height > spot->ceilingz) || (posz < spot->floorz)) + double posz = (flags & TF_USESPOTZ) ? spot->Z() : spot->floorz; + if ((posz + ref->Height > spot->ceilingz) || (posz < spot->floorz)) { return numret; } } - fixedvec3 prev = ref->Pos(); - fixed_t aboveFloor = spot->Z() - spot->floorz; - fixed_t finalz = spot->floorz + aboveFloor; + DVector3 prev = ref->Pos(); + double aboveFloor = spot->Z() - spot->floorz; + double finalz = spot->floorz + aboveFloor; - if (spot->Z() + ref->height > spot->ceilingz) - finalz = spot->ceilingz - ref->height; + if (spot->Top() > spot->ceilingz) + finalz = spot->ceilingz - ref->Height; else if (spot->Z() < spot->floorz) finalz = spot->floorz; + DVector3 tpos = spot->PosAtZ(finalz); + //Take precedence and cooperate with telefragging first. - bool tele_result = P_TeleportMove(ref, spot->X(), spot->Y(), finalz, !!(flags & TF_TELEFRAG)); + bool tele_result = P_TeleportMove(ref, tpos, !!(flags & TF_TELEFRAG)); if (!tele_result && (flags & TF_FORCED)) { //If for some reason the original move didn't work, regardless of telefrag, force it to move. - ref->SetOrigin(spot->X(), spot->Y(), finalz, false); + ref->SetOrigin(tpos, false); tele_result = true; } @@ -4966,10 +4875,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) ref->SetZ((flags & TF_USESPOTZ) ? spot->Z() : ref->floorz, false); if (!(flags & TF_KEEPANGLE)) - ref->angle = spot->angle; + ref->Angles.Yaw = spot->Angles.Yaw; - if (!(flags & TF_KEEPVELOCITY)) - ref->vel.x = ref->vel.y = ref->vel.z = 0; + if (!(flags & TF_KEEPVELOCITY)) ref->Vel.Zero(); if (!(flags & TF_NOJUMP)) //The state jump should only happen with the calling actor. { @@ -5006,8 +4914,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Turn) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(angle) { angle = 0; } - self->angle += angle; + PARAM_FLOAT_OPT(angle) { angle = 0; } + self->Angles.Yaw += angle; return 0; } @@ -5064,47 +4972,44 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_QuakeEx) // //=========================================================================== -void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdist) +void A_Weave(AActor *self, int xyspeed, int zspeed, double xydist, double zdist) { - fixed_t newX, newY; + DVector2 newpos; int weaveXY, weaveZ; - int angle; - fixed_t dist; + DAngle angle; + double dist; weaveXY = self->WeaveIndexXY & 63; weaveZ = self->WeaveIndexZ & 63; - angle = (self->angle + ANG90) >> ANGLETOFINESHIFT; + angle = self->Angles.Yaw + 90; if (xydist != 0 && xyspeed != 0) { - dist = MulScale13(finesine[weaveXY << BOBTOFINESHIFT], xydist); - newX = self->X() - FixedMul (finecosine[angle], dist); - newY = self->Y() - FixedMul (finesine[angle], dist); + dist = BobSin(weaveXY) * xydist; + newpos = self->Pos().XY() - angle.ToVector(dist); weaveXY = (weaveXY + xyspeed) & 63; - dist = MulScale13(finesine[weaveXY << BOBTOFINESHIFT], xydist); - newX += FixedMul (finecosine[angle], dist); - newY += FixedMul (finesine[angle], dist); + dist = BobSin(weaveXY) * xydist; + newpos += angle.ToVector(dist); if (!(self->flags5 & MF5_NOINTERACTION)) { - P_TryMove (self, newX, newY, true); + P_TryMove (self, newpos, true); } else { self->UnlinkFromWorld (); self->flags |= MF_NOBLOCKMAP; // We need to do portal offsetting here explicitly, because SetXY cannot do that. - newX -= self->X(); - newY -= self->Y(); - self->SetXY(self->Vec2Offset(newX, newY)); + newpos -= self->Pos().XY(); + self->SetXY(self->Vec2Offset(newpos.X, newpos.Y)); self->LinkToWorld (); } self->WeaveIndexXY = weaveXY; } if (zdist != 0 && zspeed != 0) { - self->AddZ(-MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist)); + self->AddZ(-BobSin(weaveZ) * zdist); weaveZ = (weaveZ + zspeed) & 63; - self->AddZ(MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist)); + self->AddZ(BobSin(weaveZ) * zdist); self->WeaveIndexZ = weaveZ; } } @@ -5114,8 +5019,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Weave) PARAM_ACTION_PROLOGUE; PARAM_INT (xspeed); PARAM_INT (yspeed); - PARAM_FIXED (xdist); - PARAM_FIXED (ydist); + PARAM_FLOAT (xdist); + PARAM_FLOAT (ydist); A_Weave(self, xspeed, yspeed, xdist, ydist); return 0; } @@ -5171,12 +5076,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) PARAM_ACTION_PROLOGUE; PARAM_INT_OPT (flags) { flags = 0; } PARAM_SOUND_OPT (sound) { sound = "weapons/pistol"; } - PARAM_FIXED_OPT (snipe) { snipe = FRACUNIT; } + PARAM_FLOAT_OPT (snipe) { snipe = 1.; } PARAM_INT_OPT (maxdamage) { maxdamage = 64; } PARAM_INT_OPT (blocksize) { blocksize = 128; } PARAM_INT_OPT (pointblank) { pointblank = 2; } PARAM_INT_OPT (longrange) { longrange = 4; } - PARAM_FIXED_OPT (runspeed) { runspeed = 160*FRACUNIT; } + PARAM_FLOAT_OPT (runspeed) { runspeed = 160; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = PClass::FindActor(NAME_BulletPuff); } if (!self->target) @@ -5189,31 +5094,27 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) A_FaceTarget (self); // Target can dodge if it can see enemy - angle_t angle = self->target->AngleTo(self) - self->target->angle; - angle >>= 24; - bool dodge = (P_CheckSight(self->target, self) && (angle>226 || angle<30)); + DAngle angle = absangle(self->target->Angles.Yaw, self->target->AngleTo(self)); + bool dodge = (P_CheckSight(self->target, self) && angle < 30. * 256. / 360.); // 30 byteangles ~ 21° // Distance check is simplistic - fixedvec2 vec = self->Vec2To(self->target); - fixed_t dx = abs (vec.x); - fixed_t dy = abs (vec.y); - fixed_t dist = dx > dy ? dx : dy; + DVector2 vec = self->Vec2To(self->target); + double dx = fabs (vec.X); + double dy = fabs (vec.Y); + double dist = dx > dy ? dx : dy; // Some enemies are more precise - dist = FixedMul(dist, snipe); + dist *= snipe; // Convert distance into integer number of blocks - dist >>= FRACBITS; - dist /= blocksize; + int idist = int(dist / blocksize); // Now for the speed accuracy thingie - fixed_t speed = FixedMul(self->target->vel.x, self->target->vel.x) - + FixedMul(self->target->vel.y, self->target->vel.y) - + FixedMul(self->target->vel.z, self->target->vel.z); + double speed = self->target->Vel.LengthSquared(); int hitchance = speed < runspeed ? 256 : 160; // Distance accuracy (factoring dodge) - hitchance -= dist * (dodge ? 16 : 8); + hitchance -= idist * (dodge ? 16 : 8); // While we're here, we may as well do something for this: if (self->target->flags & MF_SHADOW) @@ -5225,10 +5126,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) if (pr_cabullet() < hitchance) { // Compute position for spawning blood/puff - angle = self->target->AngleTo(self); - - fixedvec3 bloodpos = self->target->Vec3Angle(self->target->radius, angle, self->target->height >> 1); - + DAngle angle = self->target->AngleTo(self); + DVector3 BloodPos = self->target->Vec3Angle(self->target->radius, angle, self->target->Height/2); int damage = flags & WAF_NORANDOM ? maxdamage : (1 + (pr_cabullet() % maxdamage)); if (dist >= pointblank) @@ -5249,7 +5148,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) if ((0 && dpuff->flags3 & MF3_PUFFONACTORS) || !spawnblood) { spawnblood = false; - P_SpawnPuff(self, pufftype, bloodpos, angle, angle, 0); + P_SpawnPuff(self, pufftype, BloodPos, angle, angle, 0); } } else if (self->target->flags3 & MF3_GHOST) @@ -5259,7 +5158,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) int newdam = P_DamageMobj(self->target, self, self, damage, mod, DMG_THRUSTLESS); if (spawnblood) { - P_SpawnBlood(bloodpos, angle, newdam > 0 ? newdam : damage, self->target); + P_SpawnBlood(BloodPos, angle, newdam > 0 ? newdam : damage, self->target); P_TraceBleed(newdam > 0 ? newdam : damage, self->target, self); } } @@ -5281,15 +5180,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) { PARAM_ACTION_PROLOGUE; PARAM_INT(destination_selector); - PARAM_FIXED_OPT(xofs) { xofs = 0; } - PARAM_FIXED_OPT(yofs) { yofs = 0; } - PARAM_FIXED_OPT(zofs) { zofs = 0; } - PARAM_ANGLE_OPT(angle) { angle = 0; } + PARAM_FLOAT_OPT(xofs) { xofs = 0; } + PARAM_FLOAT_OPT(yofs) { yofs = 0; } + PARAM_FLOAT_OPT(zofs) { zofs = 0; } + PARAM_ANGLE_OPT(angle) { angle = 0.; } PARAM_INT_OPT(flags) { flags = 0; } PARAM_STATE_OPT(success_state) { success_state = NULL; } - PARAM_FIXED_OPT(heightoffset) { heightoffset = 0; } - PARAM_FIXED_OPT(radiusoffset) { radiusoffset = 0; } - PARAM_ANGLE_OPT(pitch) { pitch = 0; } + PARAM_FLOAT_OPT(heightoffset) { heightoffset = 0; } + PARAM_FLOAT_OPT(radiusoffset) { radiusoffset = 0; } + PARAM_ANGLE_OPT(pitch) { pitch = 0.; } AActor *reference; @@ -5490,7 +5389,7 @@ enum RadiusGiveFlags RGF_CORPSES | RGF_MISSILES, }; -static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amount, fixed_t distance, int flags, PClassActor *filter, FName species, fixed_t mindist) +static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amount, double distance, int flags, PClassActor *filter, FName species, double mindist) { // [MC] We only want to make an exception for missiles here. Nothing else. bool missilePass = !!((flags & RGF_MISSILES) && thing->flags & MF_MISSILE); @@ -5564,26 +5463,22 @@ static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amo if (selfPass || monsterPass || corpsePass || killedPass || itemPass || objectPass || missilePass || playerPass || voodooPass) { - fixedvec3 diff = self->Vec3To(thing); - diff.z += (thing->height - self->height) / 2; + DVector3 diff = self->Vec3To(thing); + diff.Z += thing->Height *0.5; if (flags & RGF_CUBE) { // check if inside a cube - double dx = fabs((double)(diff.x)); - double dy = fabs((double)(diff.y)); - double dz = fabs((double)(diff.z)); - double dist = (double)distance; - double min = (double)mindist; - if ((dx > dist || dy > dist || dz > dist) || (min && (dx < min && dy < min && dz < min))) + double dx = fabs(diff.X); + double dy = fabs(diff.Y); + double dz = fabs(diff.Z); + if ((dx > distance || dy > distance || dz > distance) || (mindist && (dx < mindist && dy < mindist && dz < mindist))) { return false; } } else { // check if inside a sphere - double distsquared = double(distance) * double(distance); - double minsquared = double(mindist) * double(mindist); - double lengthsquared = DVector3(diff.x, diff.y, diff.z).LengthSquared(); - if (lengthsquared > distsquared || (minsquared && (lengthsquared < minsquared))) + double lengthsquared = diff.LengthSquared(); + if (lengthsquared > distance*distance || (mindist && (lengthsquared < mindist*mindist))) { return false; } @@ -5591,7 +5486,7 @@ static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amo if ((flags & RGF_NOSIGHT) || P_CheckSight(thing, self, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) { // OK to give; target is in direct path, or the monster doesn't care about it being in line of sight. - AInventory *gift = static_cast(Spawn(item, 0, 0, 0, NO_REPLACE)); + AInventory *gift = static_cast(Spawn(item)); if (gift->IsKindOf(RUNTIME_CLASS(AHealth))) { gift->Amount *= amount; @@ -5620,12 +5515,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (item, AInventory); - PARAM_FIXED (distance); + PARAM_FLOAT (distance); PARAM_INT (flags); PARAM_INT_OPT (amount) { amount = 0; } PARAM_CLASS_OPT (filter, AActor) { filter = NULL; } PARAM_NAME_OPT (species) { species = NAME_None; } - PARAM_FIXED_OPT (mindist) { mindist = 0; } + PARAM_FLOAT_OPT (mindist) { mindist = 0; } // We need a valid item, valid targets, and a valid range if (item == NULL || (flags & RGF_MASK) == 0 || !flags || distance <= 0 || mindist >= distance) @@ -5650,7 +5545,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) else { FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); - fixed_t mid = self->Z() + self->height / 2; + double mid = self->Center(); FMultiBlockThingsIterator it(check, self->X(), self->Y(), mid-distance, mid+distance, distance, false, self->Sector); FMultiBlockThingsIterator::CheckResult cres; @@ -5750,7 +5645,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropItem) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(speed); + PARAM_FLOAT(speed); PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -5770,7 +5665,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetFloatSpeed) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(speed); + PARAM_FLOAT(speed); PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -6472,8 +6367,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower) PARAM_ACTION_PROLOGUE; PARAM_STATE(high); PARAM_STATE(low); - PARAM_FIXED_OPT(offsethigh) { offsethigh = 0; } - PARAM_FIXED_OPT(offsetlow) { offsetlow = 0; } + PARAM_FLOAT_OPT(offsethigh) { offsethigh = 0; } + PARAM_FLOAT_OPT(offsetlow) { offsetlow = 0; } PARAM_BOOL_OPT(includeHeight) { includeHeight = true; } PARAM_INT_OPT(ptr) { ptr = AAPTR_TARGET; } @@ -6482,11 +6377,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower) if (mobj != NULL && mobj != self) //AAPTR_DEFAULT is completely useless in this regard. { - if ((high) && (mobj->Z() > ((includeHeight ? self->height : 0) + self->Z() + offsethigh))) + if ((high) && (mobj->Z() > ((includeHeight ? self->Height : 0) + self->Z() + offsethigh))) { ACTION_RETURN_STATE(high); } - else if ((low) && (mobj->Z() + (includeHeight ? mobj->height : 0)) < (self->Z() + offsetlow)) + else if ((low) && (mobj->Z() + (includeHeight ? mobj->Height : 0)) < (self->Z() + offsetlow)) { ACTION_RETURN_STATE(low); } @@ -6613,7 +6508,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) PARAM_ACTION_PROLOGUE; PARAM_STATE(jump); PARAM_CLASS(classname, AActor); - PARAM_FIXED(distance); + PARAM_FLOAT(distance); PARAM_INT_OPT(count) { count = 1; } PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } @@ -6634,7 +6529,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) } int counter = 0; bool result = false; - fixed_t closer = distance, farther = 0, current = distance; + double closer = distance, farther = 0, current = distance; const bool ptrWillChange = !!(flags & (CPXF_SETTARGET | CPXF_SETMASTER | CPXF_SETTRACER)); const bool ptrDistPref = !!(flags & (CPXF_CLOSEST | CPXF_FARTHEST)); @@ -6665,7 +6560,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) //[MC]Make sure it's in range and respect the desire for Z or not. The function forces it to use //Z later for ensuring CLOSEST and FARTHEST flags are respected perfectly. //Ripped from sphere checking in A_RadiusGive (along with a number of things). - if ((ref->AproxDistance(mo) < distance && + if ((ref->Distance2D(mo) < distance && ((flags & CPXF_NOZ) || ((ref->Z() > mo->Z() && ref->Z() - mo->Top() < distance) || (ref->Z() <= mo->Z() && mo->Z() - ref->Top() < distance))))) @@ -6675,7 +6570,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) if (ptrWillChange) { - current = ref->AproxDistance(mo); + current = ref->Distance2D(mo); if ((flags & CPXF_CLOSEST) && (current < closer)) { @@ -6770,12 +6665,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) { PARAM_ACTION_PROLOGUE; PARAM_STATE(block) - PARAM_INT_OPT(flags) { flags = 0; } + PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } - PARAM_FIXED_OPT(xofs) { xofs = 0; } - PARAM_FIXED_OPT(yofs) { yofs = 0; } - PARAM_FIXED_OPT(zofs) { zofs = 0; } - PARAM_ANGLE_OPT(angle) { angle = 0; } + PARAM_FLOAT_OPT(xofs) { xofs = 0; } + PARAM_FLOAT_OPT(yofs) { yofs = 0; } + PARAM_FLOAT_OPT(zofs) { zofs = 0; } + PARAM_ANGLE_OPT(angle) { angle = 0.; } AActor *mobj = COPY_AAPTR(self, ptr); @@ -6787,25 +6682,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) if (!(flags & CBF_ABSOLUTEANGLE)) { - angle += self->angle; + angle += self->Angles.Yaw; } - angle_t ang = angle >> ANGLETOFINESHIFT; - fixedvec3 oldpos = mobj->Pos(); - fixedvec3 pos; + DVector3 oldpos = mobj->Pos(); + DVector3 pos; if (flags & CBF_ABSOLUTEPOS) { - pos.x = xofs; - pos.y = yofs; - pos.z = zofs; + pos = { xofs, yofs, zofs }; } else { - pos = mobj->Vec3Offset( - FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]), - FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang]), - mobj->Z() + zofs); + double s = angle.Sin(); + double c = angle.Cos(); + pos = mobj->Vec3Offset(xofs * c + yofs * s, xofs * s - yofs * c, zofs); } // Next, try checking the position based on the sensitivity desired. @@ -6815,9 +6706,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) bool checker = false; if (flags & CBF_DROPOFF) { - mobj->SetZ(pos.z); - checker = P_CheckMove(mobj, pos.x, pos.y); - mobj->SetZ(oldpos.z); + mobj->SetZ(pos.Z); + checker = P_CheckMove(mobj, pos); + mobj->SetZ(oldpos.Z); } else { @@ -6826,7 +6717,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) mobj->SetOrigin(oldpos, true); } - //Nothing to block it so skip the rest. if (checker) { ACTION_RETURN_STATE(NULL); @@ -6875,9 +6765,9 @@ enum FMDFlags DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(offset) { offset = 0; } - PARAM_ANGLE_OPT(anglelimit) { anglelimit = 0; } - PARAM_ANGLE_OPT(pitchlimit) { pitchlimit = 0; } + PARAM_ANGLE_OPT(offset) { offset = 0.; } + PARAM_ANGLE_OPT(anglelimit) { anglelimit = 0.; } + PARAM_ANGLE_OPT(pitchlimit) { pitchlimit = 0.; } PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } @@ -6890,36 +6780,32 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) } //Don't bother calculating this if we don't have any horizontal movement. - if (!(flags & FMDF_NOANGLE) && (mobj->vel.x != 0 || mobj->vel.y != 0)) + if (!(flags & FMDF_NOANGLE) && (mobj->Vel.X != 0 || mobj->Vel.Y != 0)) { - angle_t current = mobj->angle; - const angle_t angle = R_PointToAngle2(0, 0, mobj->vel.x, mobj->vel.y); + DAngle current = mobj->Angles.Yaw; + DAngle angle = mobj->Vel.Angle(); //Done because using anglelimit directly causes a signed/unsigned mismatch. - const angle_t limit = anglelimit; //Code borrowed from A_Face*. - if (limit > 0 && (absangle(current - angle) > limit)) + if (anglelimit > 0) { - if (current < angle) + DAngle delta = -deltaangle(current, angle); + if (fabs(delta) > anglelimit) { - // [MC] This may appear backwards, but I assure any who - // reads this, it works. - if (current - angle > ANGLE_180) - current += limit + offset; - else - current -= limit + offset; + if (delta < 0) + { + current += anglelimit + offset; + } + else if (delta > 0) + { + current -= anglelimit + offset; + } + else // huh??? + { + current = angle + 180. + offset; + } mobj->SetAngle(current, !!(flags & FMDF_INTERPOLATE)); } - else if (current > angle) - { - if (angle - current > ANGLE_180) - current -= limit + offset; - else - current += limit + offset; - mobj->SetAngle(current, !!(flags & FMDF_INTERPOLATE)); - } - else - mobj->SetAngle(angle + ANGLE_180 + offset, !!(flags & FMDF_INTERPOLATE)); } else mobj->SetAngle(angle + offset, !!(flags & FMDF_INTERPOLATE)); @@ -6927,31 +6813,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) if (!(flags & FMDF_NOPITCH)) { - fixed_t current = mobj->pitch; - const DVector2 velocity(mobj->vel.x, mobj->vel.y); - const fixed_t pitch = R_PointToAngle2(0, 0, xs_CRoundToInt(velocity.Length()), -mobj->vel.z); + DAngle current = mobj->Angles.Pitch; + const DVector2 velocity = mobj->Vel.XY(); + DAngle pitch = VecToAngle(velocity.Length(), -mobj->Vel.Z); if (pitchlimit > 0) { - // [MC] angle_t for pitchlimit was required because otherwise - // we would wind up with less than desirable turn rates that didn't - // match that of A_SetPitch. We want consistency. Also, I didn't know - // of a better way to convert from angle_t to fixed_t properly so I - // used this instead. - fixed_t plimit = fixed_t(pitchlimit); + DAngle pdelta = deltaangle(current, pitch); - if (abs(current - pitch) > plimit) + if (fabs(pdelta) > pitchlimit) { - fixed_t max = 0; - - if (current > pitch) + if (pdelta > 0) { - max = MIN(plimit, (current - pitch)); - current -= max; + current -= MIN(pitchlimit, pdelta); } - else //if (current > pitch) + else //if (pdelta < 0) { - max = MIN(plimit, (pitch - current)); - current += max; + current += MIN(pitchlimit, -pdelta); } mobj->SetPitch(current, !!(flags & FMDF_INTERPOLATE)); } diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 132440a73..16fcc9a55 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -619,38 +619,38 @@ void InitThingdef() // Define some member variables we feel like exposing to the user PSymbolTable &symt = RUNTIME_CLASS(AActor)->Symbols; PType *array5 = NewArray(TypeSInt32, 5); - symt.AddSymbol(new PField(NAME_Alpha, TypeFixed, VARF_Native, myoffsetof(AActor,alpha))); - symt.AddSymbol(new PField(NAME_Angle, TypeAngle, VARF_Native, myoffsetof(AActor,angle))); - symt.AddSymbol(new PField(NAME_Args, array5, VARF_Native, myoffsetof(AActor,args))); - symt.AddSymbol(new PField(NAME_CeilingZ, TypeFixed, VARF_Native, myoffsetof(AActor,ceilingz))); - symt.AddSymbol(new PField(NAME_FloorZ, TypeFixed, VARF_Native, myoffsetof(AActor,floorz))); - symt.AddSymbol(new PField(NAME_Health, TypeSInt32, VARF_Native, myoffsetof(AActor,health))); - symt.AddSymbol(new PField(NAME_Mass, TypeSInt32, VARF_Native, myoffsetof(AActor,Mass))); - symt.AddSymbol(new PField(NAME_Pitch, TypeAngle, VARF_Native, myoffsetof(AActor,pitch))); - symt.AddSymbol(new PField(NAME_Roll, TypeAngle, VARF_Native, myoffsetof(AActor,roll))); - symt.AddSymbol(new PField(NAME_Special, TypeSInt32, VARF_Native, myoffsetof(AActor,special))); - symt.AddSymbol(new PField(NAME_TID, TypeSInt32, VARF_Native, myoffsetof(AActor,tid))); - symt.AddSymbol(new PField(NAME_TIDtoHate, TypeSInt32, VARF_Native, myoffsetof(AActor,TIDtoHate))); - symt.AddSymbol(new PField(NAME_WaterLevel, TypeSInt32, VARF_Native, myoffsetof(AActor,waterlevel))); - symt.AddSymbol(new PField(NAME_X, TypeFixed, VARF_Native, myoffsetof(AActor,__pos.x))); // must remain read-only! - symt.AddSymbol(new PField(NAME_Y, TypeFixed, VARF_Native, myoffsetof(AActor,__pos.y))); // must remain read-only! - symt.AddSymbol(new PField(NAME_Z, TypeFixed, VARF_Native, myoffsetof(AActor,__pos.z))); // must remain read-only! - symt.AddSymbol(new PField(NAME_VelX, TypeFixed, VARF_Native, myoffsetof(AActor,vel.x))); - symt.AddSymbol(new PField(NAME_VelY, TypeFixed, VARF_Native, myoffsetof(AActor,vel.y))); - symt.AddSymbol(new PField(NAME_VelZ, TypeFixed, VARF_Native, myoffsetof(AActor,vel.z))); - symt.AddSymbol(new PField(NAME_MomX, TypeFixed, VARF_Native, myoffsetof(AActor,vel.x))); - symt.AddSymbol(new PField(NAME_MomY, TypeFixed, VARF_Native, myoffsetof(AActor,vel.y))); - symt.AddSymbol(new PField(NAME_MomZ, TypeFixed, VARF_Native, myoffsetof(AActor,vel.z))); - symt.AddSymbol(new PField(NAME_ScaleX, TypeFixed, VARF_Native, myoffsetof(AActor,scaleX))); - symt.AddSymbol(new PField(NAME_ScaleY, TypeFixed, VARF_Native, myoffsetof(AActor,scaleY))); - symt.AddSymbol(new PField(NAME_Score, TypeSInt32, VARF_Native, myoffsetof(AActor,Score))); - symt.AddSymbol(new PField(NAME_Accuracy, TypeSInt32, VARF_Native, myoffsetof(AActor,accuracy))); - symt.AddSymbol(new PField(NAME_Stamina, TypeSInt32, VARF_Native, myoffsetof(AActor,stamina))); - symt.AddSymbol(new PField(NAME_Height, TypeFixed, VARF_Native, myoffsetof(AActor,height))); - symt.AddSymbol(new PField(NAME_Radius, TypeFixed, VARF_Native, myoffsetof(AActor,radius))); - symt.AddSymbol(new PField(NAME_ReactionTime,TypeSInt32, VARF_Native, myoffsetof(AActor,reactiontime))); - symt.AddSymbol(new PField(NAME_MeleeRange, TypeFixed, VARF_Native, myoffsetof(AActor,meleerange))); - symt.AddSymbol(new PField(NAME_Speed, TypeFixed, VARF_Native, myoffsetof(AActor,Speed))); - symt.AddSymbol(new PField(NAME_Threshold, TypeSInt32, VARF_Native, myoffsetof(AActor,threshold))); - symt.AddSymbol(new PField(NAME_DefThreshold,TypeSInt32, VARF_Native, myoffsetof(AActor,DefThreshold))); + symt.AddSymbol(new PField(NAME_Alpha, TypeFloat64, VARF_Native, myoffsetof(AActor,Alpha))); + symt.AddSymbol(new PField(NAME_Angle, TypeFloat64, VARF_Native, myoffsetof(AActor,Angles.Yaw))); + symt.AddSymbol(new PField(NAME_Args, array5, VARF_Native, myoffsetof(AActor,args))); + symt.AddSymbol(new PField(NAME_CeilingZ, TypeFloat64, VARF_Native, myoffsetof(AActor,ceilingz))); + symt.AddSymbol(new PField(NAME_FloorZ, TypeFloat64, VARF_Native, myoffsetof(AActor,floorz))); + symt.AddSymbol(new PField(NAME_Health, TypeSInt32, VARF_Native, myoffsetof(AActor,health))); + symt.AddSymbol(new PField(NAME_Mass, TypeSInt32, VARF_Native, myoffsetof(AActor,Mass))); + symt.AddSymbol(new PField(NAME_Pitch, TypeFloat64, VARF_Native, myoffsetof(AActor,Angles.Pitch))); + symt.AddSymbol(new PField(NAME_Roll, TypeFloat64, VARF_Native, myoffsetof(AActor,Angles.Roll))); + symt.AddSymbol(new PField(NAME_Special, TypeSInt32, VARF_Native, myoffsetof(AActor,special))); + symt.AddSymbol(new PField(NAME_TID, TypeSInt32, VARF_Native, myoffsetof(AActor,tid))); + symt.AddSymbol(new PField(NAME_TIDtoHate, TypeSInt32, VARF_Native, myoffsetof(AActor,TIDtoHate))); + symt.AddSymbol(new PField(NAME_WaterLevel, TypeSInt32, VARF_Native, myoffsetof(AActor,waterlevel))); + symt.AddSymbol(new PField(NAME_X, TypeFloat64, VARF_Native, myoffsetof(AActor,__Pos.X))); // must remain read-only! + symt.AddSymbol(new PField(NAME_Y, TypeFloat64, VARF_Native, myoffsetof(AActor,__Pos.Y))); // must remain read-only! + symt.AddSymbol(new PField(NAME_Z, TypeFloat64, VARF_Native, myoffsetof(AActor,__Pos.Z))); // must remain read-only! + symt.AddSymbol(new PField(NAME_VelX, TypeFloat64, VARF_Native, myoffsetof(AActor,Vel.X))); + symt.AddSymbol(new PField(NAME_VelY, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.Y))); + symt.AddSymbol(new PField(NAME_VelZ, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.Z))); + symt.AddSymbol(new PField(NAME_MomX, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.X))); + symt.AddSymbol(new PField(NAME_MomY, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.Y))); + symt.AddSymbol(new PField(NAME_MomZ, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.Z))); + symt.AddSymbol(new PField(NAME_ScaleX, TypeFloat64, VARF_Native, myoffsetof(AActor, Scale.X))); + symt.AddSymbol(new PField(NAME_ScaleY, TypeFloat64, VARF_Native, myoffsetof(AActor, Scale.Y))); + symt.AddSymbol(new PField(NAME_Score, TypeSInt32, VARF_Native, myoffsetof(AActor,Score))); + symt.AddSymbol(new PField(NAME_Accuracy, TypeSInt32, VARF_Native, myoffsetof(AActor,accuracy))); + symt.AddSymbol(new PField(NAME_Stamina, TypeSInt32, VARF_Native, myoffsetof(AActor,stamina))); + symt.AddSymbol(new PField(NAME_Height, TypeFloat64, VARF_Native, myoffsetof(AActor,Height))); + symt.AddSymbol(new PField(NAME_Radius, TypeFloat64, VARF_Native, myoffsetof(AActor,radius))); + symt.AddSymbol(new PField(NAME_ReactionTime,TypeSInt32, VARF_Native, myoffsetof(AActor,reactiontime))); + symt.AddSymbol(new PField(NAME_MeleeRange, TypeFloat64, VARF_Native, myoffsetof(AActor,meleerange))); + symt.AddSymbol(new PField(NAME_Speed, TypeFloat64, VARF_Native, myoffsetof(AActor,Speed))); + symt.AddSymbol(new PField(NAME_Threshold, TypeSInt32, VARF_Native, myoffsetof(AActor,threshold))); + symt.AddSymbol(new PField(NAME_DefThreshold,TypeSInt32, VARF_Native, myoffsetof(AActor,DefThreshold))); } diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index e1a9e653e..1b570c62e 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -53,6 +53,7 @@ #include "m_fixed.h" #include "vmbuilder.h" #include "v_text.h" +#include "math/cmath.h" struct FLOP { @@ -65,23 +66,23 @@ struct FLOP // degrees to radians for those that work with angles. static const FLOP FxFlops[] = { - { NAME_Exp, FLOP_EXP, [](double v) { return exp(v); } }, - { NAME_Log, FLOP_LOG, [](double v) { return log(v); } }, - { NAME_Log10, FLOP_LOG10, [](double v) { return log10(v); } }, - { NAME_Sqrt, FLOP_SQRT, [](double v) { return sqrt(v); } }, + { NAME_Exp, FLOP_EXP, [](double v) { return g_exp(v); } }, + { NAME_Log, FLOP_LOG, [](double v) { return g_log(v); } }, + { NAME_Log10, FLOP_LOG10, [](double v) { return g_log10(v); } }, + { NAME_Sqrt, FLOP_SQRT, [](double v) { return g_sqrt(v); } }, { NAME_Ceil, FLOP_CEIL, [](double v) { return ceil(v); } }, { NAME_Floor, FLOP_FLOOR, [](double v) { return floor(v); } }, - { NAME_ACos, FLOP_ACOS_DEG, [](double v) { return acos(v) * (180.0 / M_PI); } }, - { NAME_ASin, FLOP_ASIN_DEG, [](double v) { return asin(v) * (180.0 / M_PI); } }, - { NAME_ATan, FLOP_ATAN_DEG, [](double v) { return atan(v) * (180.0 / M_PI); } }, - { NAME_Cos, FLOP_COS_DEG, [](double v) { return cos(v * (M_PI / 180.0)); } }, - { NAME_Sin, FLOP_SIN_DEG, [](double v) { return sin(v * (M_PI / 180.0)); } }, - { NAME_Tan, FLOP_TAN_DEG, [](double v) { return tan(v * (M_PI / 180.0)); } }, + { NAME_ACos, FLOP_ACOS_DEG, [](double v) { return g_acos(v) * (180.0 / M_PI); } }, + { NAME_ASin, FLOP_ASIN_DEG, [](double v) { return g_asin(v) * (180.0 / M_PI); } }, + { NAME_ATan, FLOP_ATAN_DEG, [](double v) { return g_atan(v) * (180.0 / M_PI); } }, + { NAME_Cos, FLOP_COS_DEG, [](double v) { return g_cosdeg(v); } }, + { NAME_Sin, FLOP_SIN_DEG, [](double v) { return g_sindeg(v); } }, + { NAME_Tan, FLOP_TAN_DEG, [](double v) { return g_tan(v * (M_PI / 180.0)); } }, - { NAME_CosH, FLOP_COSH, [](double v) { return cosh(v); } }, - { NAME_SinH, FLOP_SINH, [](double v) { return sinh(v); } }, - { NAME_TanH, FLOP_TANH, [](double v) { return tanh(v); } }, + { NAME_CosH, FLOP_COSH, [](double v) { return g_cosh(v); } }, + { NAME_SinH, FLOP_SINH, [](double v) { return g_sinh(v); } }, + { NAME_TanH, FLOP_TANH, [](double v) { return g_tanh(v); } }, }; ExpEmit::ExpEmit(VMFunctionBuilder *build, int type) diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index 0eeddd85c..a86be2bc9 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -486,14 +486,6 @@ static void ParseNativeFunction(FScanner &sc, PClassActor *cls) rets.Push(TypeFloat64); break; - case TK_Angle_t: - rets.Push(TypeAngle); - break; - - case TK_Fixed_t: - rets.Push(TypeFixed); - break; - case TK_State: rets.Push(TypeState); break; @@ -1282,8 +1274,8 @@ static void ParseDamageDefinition(FScanner &sc) if (sc.Compare("FACTOR")) { sc.MustGetFloat(); - dtd.DefaultFactor = FLOAT2FIXED(sc.Float); - if (!dtd.DefaultFactor) dtd.ReplaceFactor = true; // Multiply by 0 yields 0: FixedMul(damage, FixedMul(factor, 0)) is more wasteful than FixedMul(factor, 0) + dtd.DefaultFactor = sc.Float; + if (dtd.DefaultFactor == 0) dtd.ReplaceFactor = true; } else if (sc.Compare("REPLACEFACTOR")) { diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 489a1ada4..c435cd575 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1,7 +1,7 @@ /* ** thingdef-properties.cpp ** -** Actor definitions - properties and flags handling +** Actor denitions - properties and flags handling ** **--------------------------------------------------------------------------- ** Copyright 2002-2007 Christoph Oelckers @@ -242,19 +242,19 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in defaults->DamageType = set? NAME_Ice : NAME_None; break; case DEPF_LOWGRAVITY: - defaults->gravity = set? FRACUNIT/8 : FRACUNIT; + defaults->Gravity = set ? 1. / 8 : 1.; break; case DEPF_SHORTMISSILERANGE: - defaults->maxtargetrange = set? 896*FRACUNIT : 0; + defaults->maxtargetrange = set? 896. : 0.; break; case DEPF_LONGMELEERANGE: - defaults->meleethreshold = set? 196*FRACUNIT : 0; + defaults->meleethreshold = set? 196. : 0.; break; case DEPF_QUARTERGRAVITY: - defaults->gravity = set? FRACUNIT/4 : FRACUNIT; + defaults->Gravity = set ? 1. / 4 : 1.; break; case DEPF_FIRERESIST: - info->SetDamageFactor(NAME_Fire, set? FRACUNIT/2 : FRACUNIT); + info->SetDamageFactor(NAME_Fire, set ? 0.5 : 1.); break; // the bounce flags will set the compatibility bounce modes to remain compatible case DEPF_HERETICBOUNCE: @@ -312,18 +312,18 @@ bool CheckDeprecatedFlags(const AActor *actor, PClassActor *info, int index) case DEPF_ICEDAMAGE: return actor->DamageType == NAME_Ice; case DEPF_LOWGRAVITY: - return actor->gravity == FRACUNIT/8; + return actor->Gravity == 1./8; case DEPF_SHORTMISSILERANGE: - return actor->maxtargetrange == 896*FRACUNIT; + return actor->maxtargetrange == 896.; case DEPF_LONGMELEERANGE: - return actor->meleethreshold == 196*FRACUNIT; + return actor->meleethreshold == 196.; case DEPF_QUARTERGRAVITY: - return actor->gravity == FRACUNIT/4; + return actor->Gravity == 1./4; case DEPF_FIRERESIST: if (info->DamageFactors) { - fixed_t *df = info->DamageFactors->CheckKey(NAME_Fire); - return df && (*df) == FRACUNIT / 2; + double *df = info->DamageFactors->CheckKey(NAME_Fire); + return df && (*df) == 0.5; } return false; @@ -606,7 +606,7 @@ DEFINE_PROPERTY(projectilekickback, I, Actor) //========================================================================== DEFINE_PROPERTY(speed, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); defaults->Speed = id; } @@ -615,8 +615,8 @@ DEFINE_PROPERTY(speed, F, Actor) //========================================================================== DEFINE_PROPERTY(floatspeed, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->FloatSpeed=id; + PROP_DOUBLE_PARM(id, 0); + defaults->FloatSpeed = id; } //========================================================================== @@ -624,8 +624,8 @@ DEFINE_PROPERTY(floatspeed, F, Actor) //========================================================================== DEFINE_PROPERTY(radius, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->radius=id; + PROP_DOUBLE_PARM(id, 0); + defaults->radius = id; } //========================================================================== @@ -633,8 +633,8 @@ DEFINE_PROPERTY(radius, F, Actor) //========================================================================== DEFINE_PROPERTY(height, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->height=id; + PROP_DOUBLE_PARM(id, 0); + defaults->Height=id; } //========================================================================== @@ -642,7 +642,7 @@ DEFINE_PROPERTY(height, F, Actor) //========================================================================== DEFINE_PROPERTY(projectilepassheight, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); defaults->projectilepassheight=id; } @@ -660,8 +660,8 @@ DEFINE_PROPERTY(mass, I, Actor) //========================================================================== DEFINE_PROPERTY(xscale, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->scaleX = id; + PROP_DOUBLE_PARM(id, 0); + defaults->Scale.X = id; } //========================================================================== @@ -669,8 +669,8 @@ DEFINE_PROPERTY(xscale, F, Actor) //========================================================================== DEFINE_PROPERTY(yscale, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->scaleY = id; + PROP_DOUBLE_PARM(id, 0); + defaults->Scale.Y = id; } //========================================================================== @@ -678,8 +678,8 @@ DEFINE_PROPERTY(yscale, F, Actor) //========================================================================== DEFINE_PROPERTY(scale, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->scaleX = defaults->scaleY = id; + PROP_DOUBLE_PARM(id, 0); + defaults->Scale.X = defaults->Scale.Y = id; } //========================================================================== @@ -850,7 +850,7 @@ DEFINE_PROPERTY(renderstyle, S, Actor) //========================================================================== DEFINE_PROPERTY(defaultalpha, 0, Actor) { - defaults->alpha = gameinfo.gametype == GAME_Heretic ? HR_SHADOW : HX_SHADOW; + defaults->Alpha = gameinfo.gametype == GAME_Heretic ? HR_SHADOW : HX_SHADOW; } //========================================================================== @@ -858,8 +858,8 @@ DEFINE_PROPERTY(defaultalpha, 0, Actor) //========================================================================== DEFINE_PROPERTY(alpha, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->alpha = id; + PROP_DOUBLE_PARM(id, 0); + defaults->Alpha = id; } //========================================================================== @@ -916,9 +916,9 @@ DEFINE_PROPERTY(explosiondamage, I, Actor) //========================================================================== DEFINE_PROPERTY(deathheight, F, Actor) { - PROP_FIXED_PARM(h, 0); + PROP_DOUBLE_PARM(h, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); - static_cast(info)->DeathHeight = MAX(0, h); + static_cast(info)->DeathHeight = MAX(0., h); } //========================================================================== @@ -926,9 +926,9 @@ DEFINE_PROPERTY(deathheight, F, Actor) //========================================================================== DEFINE_PROPERTY(burnheight, F, Actor) { - PROP_FIXED_PARM(h, 0); + PROP_DOUBLE_PARM(h, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); - static_cast(info)->BurnHeight = MAX(0, h); + static_cast(info)->BurnHeight = MAX(0., h); } //========================================================================== @@ -936,7 +936,7 @@ DEFINE_PROPERTY(burnheight, F, Actor) //========================================================================== DEFINE_PROPERTY(maxtargetrange, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); defaults->maxtargetrange = id; } @@ -945,7 +945,7 @@ DEFINE_PROPERTY(maxtargetrange, F, Actor) //========================================================================== DEFINE_PROPERTY(meleethreshold, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); defaults->meleethreshold = id; } @@ -964,7 +964,7 @@ DEFINE_PROPERTY(meleedamage, I, Actor) //========================================================================== DEFINE_PROPERTY(meleerange, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); defaults->meleerange = id; } @@ -993,7 +993,7 @@ DEFINE_PROPERTY(missiletype, S, Actor) //========================================================================== DEFINE_PROPERTY(missileheight, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); static_cast(info)->MissileHeight = id; } @@ -1003,7 +1003,7 @@ DEFINE_PROPERTY(missileheight, F, Actor) //========================================================================== DEFINE_PROPERTY(pushfactor, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); defaults->pushfactor = id; } @@ -1132,8 +1132,8 @@ DEFINE_PROPERTY(bouncetype, S, Actor) //========================================================================== DEFINE_PROPERTY(bouncefactor, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->bouncefactor = clamp(id, 0, FRACUNIT); + PROP_DOUBLE_PARM(id, 0); + defaults->bouncefactor = clamp(id, 0, 1); } //========================================================================== @@ -1141,8 +1141,8 @@ DEFINE_PROPERTY(bouncefactor, F, Actor) //========================================================================== DEFINE_PROPERTY(wallbouncefactor, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->wallbouncefactor = clamp(id, 0, FRACUNIT); + PROP_DOUBLE_PARM(id, 0); + defaults->wallbouncefactor = clamp(id, 0, 1); } //========================================================================== @@ -1217,7 +1217,7 @@ DEFINE_PROPERTY(deathtype, S, Actor) DEFINE_PROPERTY(damagefactor, ZF, Actor) { PROP_STRING_PARM(str, 0); - PROP_FIXED_PARM(id, 1); + PROP_DOUBLE_PARM(id, 1); if (str == NULL) { @@ -1247,7 +1247,7 @@ DEFINE_PROPERTY(decal, S, Actor) //========================================================================== DEFINE_PROPERTY(maxstepheight, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); defaults->MaxStepHeight = i; } @@ -1256,7 +1256,7 @@ DEFINE_PROPERTY(maxstepheight, F, Actor) //========================================================================== DEFINE_PROPERTY(maxdropoffheight, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); defaults->MaxDropOffHeight = i; } @@ -1300,7 +1300,7 @@ DEFINE_PROPERTY(poisondamagetype, S, Actor) //========================================================================== DEFINE_PROPERTY(fastspeed, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); static_cast(info)->FastSpeed = i; } @@ -1310,7 +1310,7 @@ DEFINE_PROPERTY(fastspeed, F, Actor) //========================================================================== DEFINE_PROPERTY(radiusdamagefactor, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); static_cast(info)->RDFactor = i; } @@ -1320,7 +1320,7 @@ DEFINE_PROPERTY(radiusdamagefactor, F, Actor) //========================================================================== DEFINE_PROPERTY(cameraheight, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); static_cast(info)->CameraHeight = i; } @@ -1330,8 +1330,8 @@ DEFINE_PROPERTY(cameraheight, F, Actor) //========================================================================== DEFINE_PROPERTY(vspeed, F, Actor) { - PROP_FIXED_PARM(i, 0); - defaults->vel.z = i; + PROP_DOUBLE_PARM(i, 0); + defaults->Vel.Z = i; } //========================================================================== @@ -1339,10 +1339,10 @@ DEFINE_PROPERTY(vspeed, F, Actor) //========================================================================== DEFINE_PROPERTY(gravity, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); if (i < 0) I_Error ("Gravity must not be negative."); - defaults->gravity = i; + defaults->Gravity = i; } //========================================================================== @@ -1350,7 +1350,7 @@ DEFINE_PROPERTY(gravity, F, Actor) //========================================================================== DEFINE_PROPERTY(friction, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); if (i < 0) I_Error ("Friction must not be negative."); defaults->Friction = i; @@ -1639,9 +1639,9 @@ DEFINE_CLASS_PROPERTY(saveamount, I, Armor) //========================================================================== DEFINE_CLASS_PROPERTY(savepercent, F, Armor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); - i = clamp(i, 0, 100*FRACUNIT)/100; + i = clamp(i, 0., 100.)/100.; // Special case here because this property has to work for 2 unrelated classes if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup))) { @@ -2028,7 +2028,7 @@ DEFINE_CLASS_PROPERTY(upsound, S, Weapon) //========================================================================== DEFINE_CLASS_PROPERTY(yadjust, F, Weapon) { - PROP_FIXED_PARM(i, 0); + PROP_FLOAT_PARM(i, 0); defaults->YAdjust = i; } @@ -2056,7 +2056,7 @@ DEFINE_CLASS_PROPERTY(bobstyle, S, Weapon) //========================================================================== DEFINE_CLASS_PROPERTY(bobspeed, F, Weapon) { - PROP_FIXED_PARM(i, 0); + PROP_FLOAT_PARM(i, 0); defaults->BobSpeed = i; } @@ -2065,7 +2065,7 @@ DEFINE_CLASS_PROPERTY(bobspeed, F, Weapon) //========================================================================== DEFINE_CLASS_PROPERTY(bobrangex, F, Weapon) { - PROP_FIXED_PARM(i, 0); + PROP_FLOAT_PARM(i, 0); defaults->BobRangeX = i; } @@ -2074,7 +2074,7 @@ DEFINE_CLASS_PROPERTY(bobrangex, F, Weapon) //========================================================================== DEFINE_CLASS_PROPERTY(bobrangey, F, Weapon) { - PROP_FIXED_PARM(i, 0); + PROP_FLOAT_PARM(i, 0); defaults->BobRangeY = i; } @@ -2093,9 +2093,9 @@ DEFINE_CLASS_PROPERTY(slotnumber, I, Weapon) //========================================================================== DEFINE_CLASS_PROPERTY(slotpriority, F, Weapon) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassWeapon))); - static_cast(info)->SlotPriority = i; + static_cast(info)->SlotPriority = int(i*65536); } //========================================================================== @@ -2258,7 +2258,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, duration, I, Inventory) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(powerup, strength, F, Inventory) { - fixed_t *pStrength; + double *pStrength; if (info->IsDescendantOf(RUNTIME_CLASS(APowerup))) { @@ -2273,7 +2273,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, strength, F, Inventory) I_Error("\"powerup.strength\" requires an actor of type \"Powerup\"\n"); return; } - PROP_FIXED_PARM(f, 0); + PROP_DOUBLE_PARM(f, 0); *pStrength = f; } @@ -2497,7 +2497,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, clearcolorset, I, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, attackzoffset, F, PlayerPawn) { - PROP_FIXED_PARM(z, 0); + PROP_DOUBLE_PARM(z, 0); defaults->AttackZOffset = z; } @@ -2506,7 +2506,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, attackzoffset, F, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, jumpz, F, PlayerPawn) { - PROP_FIXED_PARM(z, 0); + PROP_DOUBLE_PARM(z, 0); defaults->JumpZ = z; } @@ -2515,7 +2515,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, jumpz, F, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, GruntSpeed, F, PlayerPawn) { - PROP_FIXED_PARM(z, 0); + PROP_DOUBLE_PARM(z, 0); defaults->GruntSpeed = z; } @@ -2524,8 +2524,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, GruntSpeed, F, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, FallingScreamSpeed, FF, PlayerPawn) { - PROP_FIXED_PARM(minz, 0); - PROP_FIXED_PARM(maxz, 1); + PROP_DOUBLE_PARM(minz, 0); + PROP_DOUBLE_PARM(maxz, 1); defaults->FallingScreamMinSpeed = minz; defaults->FallingScreamMaxSpeed = maxz; } @@ -2566,7 +2566,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, spawnclass, L, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, viewheight, F, PlayerPawn) { - PROP_FIXED_PARM(z, 0); + PROP_DOUBLE_PARM(z, 0); defaults->ViewHeight = z; } @@ -2575,7 +2575,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, viewheight, F, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, userange, F, PlayerPawn) { - PROP_FIXED_PARM(z, 0); + PROP_DOUBLE_PARM(z, 0); defaults->UseRange = z; } @@ -2584,7 +2584,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, userange, F, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, aircapacity, F, PlayerPawn) { - PROP_FIXED_PARM(z, 0); + PROP_DOUBLE_PARM(z, 0); defaults->AirCapacity = z; } @@ -2593,11 +2593,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, aircapacity, F, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, forwardmove, F_f, PlayerPawn) { - PROP_FIXED_PARM(m, 0); + PROP_DOUBLE_PARM(m, 0); defaults->ForwardMove1 = defaults->ForwardMove2 = m; if (PROP_PARM_COUNT > 1) { - PROP_FIXED_PARM(m2, 1); + PROP_DOUBLE_PARM(m2, 1); defaults->ForwardMove2 = m2; } } @@ -2607,11 +2607,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, forwardmove, F_f, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, sidemove, F_f, PlayerPawn) { - PROP_FIXED_PARM(m, 0); + PROP_DOUBLE_PARM(m, 0); defaults->SideMove1 = defaults->SideMove2 = m; if (PROP_PARM_COUNT > 1) { - PROP_FIXED_PARM(m2, 1); + PROP_DOUBLE_PARM(m2, 1); defaults->SideMove2 = m2; } } @@ -2786,7 +2786,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, hexenarmor, FFFFF, PlayerPawn) assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); for (int i = 0; i < 5; i++) { - PROP_FIXED_PARM(val, i); + PROP_DOUBLE_PARM(val, i); static_cast(info)->HexenArmor[i] = val; } } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 1ccf04044..55ea7b871 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -167,7 +167,7 @@ void STACK_ARGS DCanvas::DrawTextureV(FTexture *img, double x, double y, uint32 } fixedcolormap = dc_colormap; - ESPSResult mode = R_SetPatchStyle (parms.style, parms.alpha, 0, parms.fillcolor); + ESPSResult mode = R_SetPatchStyle (parms.style, parms.Alpha, 0, parms.fillcolor); BYTE *destorgsave = dc_destorg; dc_destorg = screen->GetBuffer(); @@ -363,7 +363,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag parms->destheight = parms->texheight; parms->top = img->GetScaledTopOffset(); parms->left = img->GetScaledLeftOffset(); - parms->alpha = FRACUNIT; + parms->Alpha = 1.f; parms->fillcolor = -1; parms->remap = NULL; parms->translation = NULL; @@ -531,7 +531,11 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_Alpha: - parms->alpha = MIN(FRACUNIT, va_arg (tags, fixed_t)); + parms->Alpha = FIXED2FLOAT(MIN(OPAQUE, va_arg (tags, fixed_t))); + break; + + case DTA_AlphaF: + parms->Alpha = (float)(MIN(1., va_arg(tags, double))); break; case DTA_AlphaChannel: @@ -640,7 +644,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag break; case DTA_ShadowAlpha: - parms->shadowAlpha = MIN(FRACUNIT, va_arg (tags, fixed_t)); + parms->shadowAlpha = MIN(OPAQUE, va_arg (tags, fixed_t)); break; case DTA_ShadowColor: @@ -719,7 +723,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag { parms->style = STYLE_Shaded; } - else if (parms->alpha < FRACUNIT) + else if (parms->Alpha < 1.f) { parms->style = STYLE_TranslucentStencil; } @@ -728,7 +732,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag parms->style = STYLE_Stencil; } } - else if (parms->alpha < FRACUNIT) + else if (parms->Alpha < 1.f) { parms->style = STYLE_Translucent; } @@ -1148,7 +1152,7 @@ void DCanvas::Clear (int left, int top, int right, int bottom, int palcolor, uin //========================================================================== void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, angle_t rotation, + double originx, double originy, double scalex, double scaley, DAngle rotation, FDynamicColormap *colormap, int lightlevel) { #ifndef NO_SWRENDER @@ -1159,8 +1163,7 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, int i; int y1, y2, y; fixed_t x; - double rot = rotation * M_PI / double(1u << 31); - bool dorotate = rot != 0; + bool dorotate = rotation != 0.; double cosrot, sinrot; if (--npoints < 2 || Buffer == NULL) @@ -1198,11 +1201,12 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, return; } - scalex /= FIXED2DBL(tex->xScale); - scaley /= FIXED2DBL(tex->yScale); + scalex /= tex->Scale.X; + scaley /= tex->Scale.Y; - cosrot = cos(rot); - sinrot = sin(rot); + // Use the CRT's functions here. + cosrot = cos(rotation.Radians()); + sinrot = sin(rotation.Radians()); // Setup constant texture mapping parameters. R_SetupSpanBits(tex); diff --git a/src/v_video.h b/src/v_video.h index 7e0b09258..533adb52e 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -35,6 +35,7 @@ #define __V_VIDEO_H__ #include "doomtype.h" +#include "vectors.h" #include "doomdef.h" #include "dobject.h" @@ -74,6 +75,7 @@ enum DTA_DestWidth, // width of area to draw to DTA_DestHeight, // height of area to draw to DTA_Alpha, // alpha value for translucency + DTA_AlphaF, // alpha value for translucency DTA_FillColor, // color to stencil onto the destination (RGB is the color for truecolor drawers, A is the palette index for paletted drawers) DTA_Translation, // translation table to recolor the source DTA_AlphaChannel, // bool: the source is an alpha channel; used with DTA_FillColor @@ -178,7 +180,7 @@ public: // Fill a simple polygon with a texture virtual void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, angle_t rotation, + double originx, double originy, double scalex, double scaley, DAngle rotation, struct FDynamicColormap *colormap, int lightlevel); // Set an area to a specified color @@ -238,7 +240,7 @@ public: int rclip; double top; double left; - fixed_t alpha; + float Alpha; uint32 fillcolor; FRemapTable *remap; const BYTE *translation; diff --git a/src/vectors.h b/src/vectors.h index 87db3461e..91cf1e962 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -42,16 +42,19 @@ #include #include - -#ifndef PI -#define PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -#define EQUAL_EPSILON (1/65536.f) +#include "xs_Float.h" +#include "math/cmath.h" + + +#define EQUAL_EPSILON (1/65536.) + +// make this a local inline function to avoid any dependencies on other headers and not pollute the global namespace +namespace pi +{ + inline double pi() { return 3.14159265358979323846; } +} -#define DEG2RAD(d) ((d)*PI/180.f) -#define RAD2DEG(r) ((r)*180.f/PI) template struct TVector3; template struct TRotator; @@ -66,8 +69,8 @@ struct TVector2 { } - TVector2 (double a, double b) - : X(vec_t(a)), Y(vec_t(b)) + TVector2 (vec_t a, vec_t b) + : X(a), Y(b) { } @@ -86,6 +89,11 @@ struct TVector2 Y = X = 0; } + bool isZero() const + { + return X == 0 && Y == 0; + } + TVector2 &operator= (const TVector2 &other) { // This might seem backwards, but this helps produce smaller code when a newly @@ -102,12 +110,12 @@ struct TVector2 // Access X and Y as an array vec_t &operator[] (int index) { - return *(&X + index); + return index == 0 ? X : Y; } const vec_t &operator[] (int index) const { - return *(&X + index); + return index == 0 ? X : Y; } // Test for equality @@ -147,53 +155,53 @@ struct TVector2 return *this; } - friend TVector2 operator+ (const TVector2 &v, double scalar) + friend TVector2 operator+ (const TVector2 &v, vec_t scalar) { return TVector2(v.X + scalar, v.Y + scalar); } - friend TVector2 operator+ (double scalar, const TVector2 &v) + friend TVector2 operator+ (vec_t scalar, const TVector2 &v) { return TVector2(v.X + scalar, v.Y + scalar); } // Scalar subtraction - TVector2 &operator-= (double scalar) + TVector2 &operator-= (vec_t scalar) { X -= scalar, Y -= scalar; return *this; } - TVector2 operator- (double scalar) const + TVector2 operator- (vec_t scalar) const { return TVector2(X - scalar, Y - scalar); } // Scalar multiplication - TVector2 &operator*= (double scalar) + TVector2 &operator*= (vec_t scalar) { X *= scalar, Y *= scalar; return *this; } - friend TVector2 operator* (const TVector2 &v, double scalar) + friend TVector2 operator* (const TVector2 &v, vec_t scalar) { return TVector2(v.X * scalar, v.Y * scalar); } - friend TVector2 operator* (double scalar, const TVector2 &v) + friend TVector2 operator* (vec_t scalar, const TVector2 &v) { return TVector2(v.X * scalar, v.Y * scalar); } // Scalar division - TVector2 &operator/= (double scalar) + TVector2 &operator/= (vec_t scalar) { scalar = 1 / scalar, X *= scalar, Y *= scalar; return *this; } - TVector2 operator/ (double scalar) const + TVector2 operator/ (vec_t scalar) const { scalar = 1 / scalar; return TVector2(X * scalar, Y * scalar); @@ -224,12 +232,12 @@ struct TVector2 } // Vector length - double Length() const + vec_t Length() const { - return sqrt (X*X + Y*Y); + return (vec_t)g_sqrt (X*X + Y*Y); } - double LengthSquared() const + vec_t LengthSquared() const { return X*X + Y*Y; } @@ -237,15 +245,15 @@ struct TVector2 // Return a unit vector facing the same direction as this one TVector2 Unit() const { - double len = Length(); + vec_t len = Length(); if (len != 0) len = 1 / len; return *this * len; } // Scales this vector into a unit vector. Returns the old length - double MakeUnit() + vec_t MakeUnit() { - double len, ilen; + vec_t len, ilen; len = ilen = Length(); if (ilen != 0) ilen = 1 / ilen; *this *= ilen; @@ -258,17 +266,23 @@ struct TVector2 return X*other.X + Y*other.Y; } - // Returns the angle (in radians) that the ray (0,0)-(X,Y) faces - double Angle() const - { - return atan2 (X, Y); - } + // Returns the angle that the ray (0,0)-(X,Y) faces + TAngle Angle() const; - // Returns a rotated vector. TAngle is in radians. + // Returns a rotated vector. angle is in degrees. TVector2 Rotated (double angle) { - double cosval = cos (angle); - double sinval = sin (angle); + double cosval = g_cosdeg (angle); + double sinval = g_sindeg (angle); + return TVector2(X*cosval - Y*sinval, Y*cosval + X*sinval); + } + + // Returns a rotated vector. angle is in degrees. + template + TVector2 Rotated(TAngle angle) + { + double cosval = angle.Cos(); + double sinval = angle.Sin(); return TVector2(X*cosval - Y*sinval, Y*cosval + X*sinval); } @@ -296,8 +310,8 @@ struct TVector3 { } - TVector3 (double a, double b, double c) - : X(vec_t(a)), Y(vec_t(b)), Z(vec_t(c)) + TVector3 (vec_t a, vec_t b, vec_t c) + : X(a), Y(b), Z(c) { } @@ -306,7 +320,7 @@ struct TVector3 { } - TVector3 (const Vector2 &xy, double z) + TVector3 (const Vector2 &xy, vec_t z) : X(xy.X), Y(xy.Y), Z(z) { } @@ -318,6 +332,11 @@ struct TVector3 Z = Y = X = 0; } + bool isZero() const + { + return X == 0 && Y == 0 && Z == 0; + } + TVector3 &operator= (const TVector3 &other) { Z = other.Z, Y = other.Y, X = other.X; @@ -327,12 +346,12 @@ struct TVector3 // Access X and Y and Z as an array vec_t &operator[] (int index) { - return *(&X + index); + return index == 0 ? X : index == 1 ? Y : Z; } const vec_t &operator[] (int index) const { - return *(&X + index); + return index == 0 ? X : index == 1 ? Y : Z; } // Test for equality @@ -366,59 +385,59 @@ struct TVector3 } // Scalar addition - TVector3 &operator+= (double scalar) + TVector3 &operator+= (vec_t scalar) { X += scalar, Y += scalar, Z += scalar; return *this; } - friend TVector3 operator+ (const TVector3 &v, double scalar) + friend TVector3 operator+ (const TVector3 &v, vec_t scalar) { return TVector3(v.X + scalar, v.Y + scalar, v.Z + scalar); } - friend TVector3 operator+ (double scalar, const TVector3 &v) + friend TVector3 operator+ (vec_t scalar, const TVector3 &v) { return TVector3(v.X + scalar, v.Y + scalar, v.Z + scalar); } // Scalar subtraction - TVector3 &operator-= (double scalar) + TVector3 &operator-= (vec_t scalar) { X -= scalar, Y -= scalar, Z -= scalar; return *this; } - TVector3 operator- (double scalar) const + TVector3 operator- (vec_t scalar) const { return TVector3(X - scalar, Y - scalar, Z - scalar); } // Scalar multiplication - TVector3 &operator*= (double scalar) + TVector3 &operator*= (vec_t scalar) { X = vec_t(X *scalar), Y = vec_t(Y * scalar), Z = vec_t(Z * scalar); return *this; } - friend TVector3 operator* (const TVector3 &v, double scalar) + friend TVector3 operator* (const TVector3 &v, vec_t scalar) { return TVector3(v.X * scalar, v.Y * scalar, v.Z * scalar); } - friend TVector3 operator* (double scalar, const TVector3 &v) + friend TVector3 operator* (vec_t scalar, const TVector3 &v) { return TVector3(v.X * scalar, v.Y * scalar, v.Z * scalar); } // Scalar division - TVector3 &operator/= (double scalar) + TVector3 &operator/= (vec_t scalar) { scalar = 1 / scalar, X = vec_t(X * scalar), Y = vec_t(Y * scalar), Z = vec_t(Z * scalar); return *this; } - TVector3 operator/ (double scalar) const + TVector3 operator/ (vec_t scalar) const { scalar = 1 / scalar; return TVector3(X * scalar, Y * scalar, Z * scalar); @@ -462,11 +481,21 @@ struct TVector3 return *this; } - // Add a 3D vector and a 2D vector. - // Discards the Z component of the 3D vector and returns a 2D vector. - friend Vector2 operator+ (const TVector3 &v3, const Vector2 &v2) + // returns the XY fields as a 2D-vector. + Vector2 XY() const { - return Vector2(v3.X + v2.X, v3.Y + v2.Y); + return{ X, Y }; + } + + // Add a 3D vector and a 2D vector. + friend TVector3 operator+ (const TVector3 &v3, const Vector2 &v2) + { + 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) @@ -476,20 +505,21 @@ struct TVector3 // Subtract a 3D vector and a 2D vector. // Discards the Z component of the 3D vector and returns a 2D vector. - friend Vector2 operator- (const TVector3 &v3, const Vector2 &v2) - { - return Vector2(v3.X - v2.X, v3.Y - v2.Y); - } - friend Vector2 operator- (const TVector2 &v2, const TVector3 &v3) { return Vector2(v2.X - v3.X, v2.Y - v3.Y); } + + + // Returns the angle (in radians) that the ray (0,0)-(X,Y) faces + TAngle Angle() const; + TAngle Pitch() const; + // Vector length double Length() const { - return sqrt (X*X + Y*Y + Z*Z); + return g_sqrt (X*X + Y*Y + Z*Z); } double LengthSquared() const @@ -514,15 +544,21 @@ struct TVector3 } // Resizes this vector to be the specified length (if it is not 0) - TVector3 &Resize(double len) + TVector3 &MakeResize(double len) { - double nowlen = Length(); - X = vec_t(X * (len /= nowlen)); - Y = vec_t(Y * len); - Z = vec_t(Z * len); + double scale = len / Length(); + X = vec_t(X * scale); + Y = vec_t(Y * scale); + Z = vec_t(Z * scale); return *this; } + TVector3 Resized(double len) + { + double scale = len / Length(); + return{ vec_t(X * scale), vec_t(Y * scale), vec_t(Z * scale) }; + } + // Dot product double operator | (const TVector3 &other) const { @@ -572,7 +608,7 @@ struct TMatrix3x3 // (The axis vector must be normalized.) TMatrix3x3(const Vector3 &axis, double radians) { - double c = cos(radians), s = sin(radians), t = 1 - c; + double c = g_cos(radians), s = g_sin(radians), t = 1 - c; /* In comments: A more readable version of the matrix setup. This was found in Diana Gruber's article "The Mathematics of the 3D Rotation Matrix" at and is @@ -750,24 +786,36 @@ struct TAngle { vec_t Degrees; +private: + const double BAM_FACTOR = (90. / 0x40000000); +public: + + + // This is to catch any accidental attempt to assign an angle_t to this type. Any explicit exception will require a type cast. + TAngle(int) = delete; + TAngle(unsigned int) = delete; + TAngle(long) = delete; + TAngle(unsigned long) = delete; + TAngle &operator= (int other) = delete; + TAngle &operator= (unsigned other) = delete; + TAngle &operator= (long other) = delete; + TAngle &operator= (unsigned long other) = delete; + TAngle () { } - TAngle (float amt) + TAngle (vec_t amt) : Degrees(amt) { } - TAngle (double amt) - : Degrees(vec_t(amt)) - { - } - + /* TAngle (int amt) : Degrees(vec_t(amt)) { } + */ TAngle (const TAngle &other) : Degrees(other.Degrees) @@ -786,8 +834,8 @@ struct TAngle return *this; } - operator float() const { return Degrees; } - operator double() const { return Degrees; } + // intentionally disabled so that common math functions cannot be accidentally called with a TAngle. + //operator vec_t() const { return Degrees; } TAngle operator- () const { @@ -838,53 +886,53 @@ struct TAngle return Degrees / other.Degrees; } - TAngle &operator+= (double other) + TAngle &operator+= (vec_t other) { - Degrees = vec_t(Degrees + other); + Degrees = Degrees + other; return *this; } - TAngle &operator-= (double other) + TAngle &operator-= (vec_t other) { - Degrees = vec_t(Degrees - other); + Degrees = Degrees - other; return *this; } - TAngle &operator*= (double other) + TAngle &operator*= (vec_t other) { - Degrees = vec_t(Degrees * other); + Degrees = Degrees * other; return *this; } - TAngle &operator/= (double other) + TAngle &operator/= (vec_t other) { - Degrees = vec_t(Degrees / other); + Degrees = Degrees / other; return *this; } - TAngle operator+ (double other) const + TAngle operator+ (vec_t other) const { return Degrees + other; } - TAngle operator- (double other) const + TAngle operator- (vec_t other) const { return Degrees - other; } - friend TAngle operator- (double o1, TAngle o2) + friend TAngle operator- (vec_t o1, TAngle o2) { return TAngle(o1 - o2.Degrees); } - TAngle operator* (double other) const + TAngle operator* (vec_t other) const { - return Degrees * vec_t(other); + return Degrees * other; } - TAngle operator/ (double other) const + TAngle operator/ (vec_t other) const { - return Degrees / vec_t(other); + return Degrees / other; } // Should the comparisons consider an epsilon value? @@ -918,100 +966,97 @@ struct TAngle return Degrees != other.Degrees; } - bool operator< (double other) const + bool operator< (vec_t other) const { return Degrees < other; } - bool operator> (double other) const + bool operator> (vec_t other) const { return Degrees > other; } - bool operator<= (double other) const + bool operator<= (vec_t other) const { return Degrees <= other; } - bool operator>= (double other) const + bool operator>= (vec_t other) const { return Degrees >= other; } - bool operator== (double other) const + bool operator== (vec_t other) const { return Degrees == other; } - bool operator!= (double other) const + bool operator!= (vec_t other) const { return Degrees != other; } // Ensure the angle is between [0.0,360.0) degrees - TAngle &Normalize360() + TAngle Normalized360() const { - // Normalizing the angle converts it to a BAM, masks it, and converts it back to a float. - - // This could have been kept entirely in floating point using fmod(), but the MSVCRT has lots - // of overhead for that function, despite the x87 offering the FPREM instruction which does - // exactly what fmod() is supposed to do. So fmod ends up being an order of magnitude slower - // than casting to and from an int. - - // Casting Degrees to a volatile ensures that the compiler will not try to evaluate an expression - // such as "TAngle a(360*100+24); a.Normalize360();" at compile time. Normally, it would see that - // this expression is constant and attempt to remove the Normalize360() call entirely and store - // the result of the function in the TAngle directly. Unfortunately, it does not do the casting - // properly and will overflow, producing an incorrect result. So we need to make sure it always - // evaluates Normalize360 at run time and never at compile time. (This applies to VC++. I don't - // know if other compilers suffer similarly). - Degrees = vec_t((int(*(volatile vec_t *)&Degrees * ((1<<30)/360.0)) & ((1<<30)-1)) * (360.f/(1<<30))); - return *this; + // Normalizing the angle converts it to a BAM, which masks it, and converts it back to a float. + // Note: We MUST use xs_Float here because it is the only method that guarantees reliable wraparound. + return (vec_t)(BAM_FACTOR * BAMs()); } // Ensures the angle is between (-180.0,180.0] degrees - TAngle &Normalize180() + TAngle Normalized180() const { - Degrees = vec_t((((int(*(volatile vec_t *)&Degrees * ((1<<30)/360.0))+(1<<29)-1) & ((1<<30)-1)) - (1<<29)+1) * (360.f/(1<<30))); - return *this; + return (vec_t)(BAM_FACTOR * (signed int)BAMs()); } - // Like Normalize360(), except the integer value is not converted back to a float. - // The steps parameter must be a power of 2. - int Quantize(int steps) + vec_t Radians() const { - return int(*(volatile vec_t *)&Degrees * (steps/360.0)) & (steps-1); + return Degrees * (pi::pi() / 180.0); } + + unsigned BAMs() const + { + return xs_CRoundToInt(Degrees * (0x40000000 / 90.)); + } + + TVector2 ToVector(vec_t length = 1) const + { + return TVector2(length * Cos(), length * Sin()); + } + + vec_t Cos() const + { + return vec_t(g_cosdeg(Degrees)); + } + + vec_t Sin() const + { + return vec_t(g_sindeg(Degrees)); + } + + double Tan() const + { + return g_tan(Degrees * (pi::pi() / 180.)); + } + + // This is for calculating vertical velocity. For high pitches the tangent will become too large to be useful. + double TanClamped(double max = 5.) const + { + return clamp(Tan(), -max, max); + } + + static inline TAngle ToDegrees(double rad) + { + return TAngle(double(rad * (180.0 / pi::pi()))); + } + }; -template -inline double ToRadians (const TAngle °) +// Emulates the old floatbob offset table with direct calls to trig functions. +inline double BobSin(double fb) { - return double(deg.Degrees * (PI / 180.0)); -} - -template -inline TAngle ToDegrees (double rad) -{ - return TAngle (double(rad * (180.0 / PI))); -} - -template -inline double cos (const TAngle °) -{ - return cos(ToRadians(deg)); -} - -template -inline double sin (const TAngle °) -{ - return sin(ToRadians(deg)); -} - -template -inline double tan (const TAngle °) -{ - return tan(ToRadians(deg)); + return TAngle(double(fb * (180.0 / 32))).Sin() * 8; } template @@ -1021,15 +1066,68 @@ inline TAngle fabs (const TAngle °) } template -inline TAngle vectoyaw (const TVector2 &vec) +inline TAngle deltaangle(const TAngle &a1, const TAngle &a2) { - return atan2(vec.Y, vec.X) * (180.0 / PI); + return (a2 - a1).Normalized180(); } template -inline TAngle vectoyaw (const TVector3 &vec) +inline TAngle deltaangle(const TAngle &a1, double a2) { - return atan2(vec.Y, vec.X) * (180.0 / PI); + return (a2 - a1).Normalized180(); +} + +template +inline TAngle deltaangle(double a1, const TAngle &a2) +{ + return (a2 - a1).Normalized180(); +} + +template +inline TAngle absangle(const TAngle &a1, const TAngle &a2) +{ + return fabs((a1 - a2).Normalized180()); +} + +template +inline TAngle absangle(const TAngle &a1, double a2) +{ + return fabs((a1 - a2).Normalized180()); +} + +inline TAngle VecToAngle(double x, double y) +{ + return g_atan2(y, x) * (180.0 / pi::pi()); +} + +template +inline TAngle VecToAngle (const TVector2 &vec) +{ + return (T)g_atan2(vec.Y, vec.X) * (180.0 / pi::pi()); +} + +template +inline TAngle VecToAngle (const TVector3 &vec) +{ + return (T)g_atan2(vec.Y, vec.X) * (180.0 / pi::pi()); +} + +template +TAngle TVector2::Angle() const +{ + return VecToAngle(X, Y); +} + +template +TAngle TVector3::Angle() const +{ + return VecToAngle(X, Y); +} + +template +TAngle TVector3::Pitch() const +{ + return VecToAngle(TVector2(X, Y).Length(), Z); } // Much of this is copied from TVector3. Is all that functionality really appropriate? @@ -1174,39 +1272,23 @@ struct TRotator { return TRotator(Pitch - other.Pitch, Yaw - other.Yaw, Roll - other.Roll); } - - // Normalize each component - TRotator &Normalize180 () - { - for (int i = -3; i; ++i) - { - (*this)[i+3].Normalize180(); - } - return *this; - } - - TRotator &Normalize360 () - { - for (int i = -3; i; ++i) - { - (*this)[i+3].Normalize360(); - } - return *this; - } }; // Create a forward vector from a rotation (ignoring roll) template inline TVector3::TVector3 (const TRotator &rot) -: X(cos(rot.Pitch)*cos(rot.Yaw)), Y(cos(rot.Pitch)*sin(rot.Yaw)), Z(-sin(rot.Pitch)) { + double pcos = rot.Pitch.Cos(); + X = pcos * rot.Yaw.Cos(); + Y = pcos * rot.Yaw.Sin(); + Z = rot.Pitch.Sin(); } template inline TMatrix3x3::TMatrix3x3(const TVector3 &axis, TAngle degrees) { - double c = cos(degrees), s = sin(degrees), t = 1 - c; + double c = degrees.Cos(), s = degrees.Sin(), t = 1 - c; double sx = s*axis.X, sy = s*axis.Y, sz = s*axis.Z; double tx, ty, txx, tyy, u, v; @@ -1230,11 +1312,12 @@ typedef TVector2 FVector2; typedef TVector3 FVector3; typedef TRotator FRotator; typedef TMatrix3x3 FMatrix3x3; -//typedef TAngle FAngle; +typedef TAngle FAngle; typedef TVector2 DVector2; typedef TVector3 DVector3; typedef TRotator DRotator; typedef TMatrix3x3 DMatrix3x3; +typedef TAngle DAngle; #endif diff --git a/src/version.h b/src/version.h index 17e4fa3f1..3a79f24c7 100644 --- a/src/version.h +++ b/src/version.h @@ -72,11 +72,11 @@ const char *GetVersionString(); // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 3100 +#define MINSAVEVER 4536 // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4535 +#define SAVEVER 4536 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index e95e6c594..108edff3b 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -722,7 +722,7 @@ static int WI_DrawCharPatch (FFont *font, int charcode, int x, int y, EColorRang int width; screen->DrawTexture(font->GetChar(charcode, &width), x, y, nomove ? DTA_CleanNoMove : DTA_Clean, true, - DTA_ShadowAlpha, (gameinfo.gametype & GAME_DoomChex) ? 0 : FRACUNIT/2, + DTA_ShadowAlpha, (gameinfo.gametype & GAME_DoomChex) ? 0 : OPAQUE/2, DTA_Translation, font->GetColorTranslation(translation), TAG_DONE); return x - width; @@ -759,7 +759,7 @@ int CheckRealHeight(FTexture *tex) } } // Scale maxy before returning it - maxy = (maxy << 17) / tex->yScale; + maxy = int((maxy *2) / tex->Scale.Y); maxy = (maxy >> 1) + (maxy & 1); return maxy; } diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index ec8684ad9..7ec394d52 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -3071,10 +3071,11 @@ void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bo void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - angle_t rotation, FDynamicColormap *colormap, int lightlevel) + DAngle rotation, FDynamicColormap *colormap, int lightlevel) { // Use an equation similar to player sprites to determine shade - fixed_t shade = LIGHT2SHADE(lightlevel) - 12*FRACUNIT; + double fadelevel = clamp((LIGHT2SHADE(lightlevel)/65536. - 12) / NUMCOLORMAPS, 0.0, 1.0); + BufferedTris *quad; FBVERTEX *verts; D3DTex *tex; @@ -3083,8 +3084,7 @@ void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, D3DCOLOR color0, color1; float ox, oy; float cosrot, sinrot; - float rot = float(rotation * M_PI / float(1u << 31)); - bool dorotate = rot != 0; + bool dorotate = rotation != 0; if (npoints < 3) { // This is no polygon. @@ -3105,8 +3105,8 @@ void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, return; } - cosrot = cos(rot); - sinrot = sin(rot); + cosrot = (float)cos(rotation.Radians()); + sinrot = (float)sin(rotation.Radians()); CheckQuadBatch(npoints - 2, npoints); quad = &QuadExtra[QuadBatchPos]; @@ -3129,7 +3129,6 @@ void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, quad->ShaderNum = BQS_InGameColormap; quad->Desat = colormap->Desaturate; color0 = D3DCOLOR_ARGB(255, colormap->Color.r, colormap->Color.g, colormap->Color.b); - double fadelevel = clamp(shade / (NUMCOLORMAPS * 65536.0), 0.0, 1.0); color1 = D3DCOLOR_ARGB(DWORD((1 - fadelevel) * 255), DWORD(colormap->Fade.r * fadelevel), DWORD(colormap->Fade.g * fadelevel), @@ -3535,7 +3534,7 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & } else { - alpha = clamp (parms.alpha, 0, FRACUNIT) / 65536.f; + alpha = clamp(parms.Alpha, 0.f, 1.f); } style.CheckFuzz(); diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 4e6868a7b..241e9dae2 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -1080,10 +1080,10 @@ void DoomSpecificInfo (char *buffer, size_t bufflen) } else { - buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nviewx = %d", viewx); - buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewy = %d", viewy); - buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewz = %d", viewz); - buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewangle = %x", viewangle); + buffer += mysnprintf (buffer, buffend - buffer, "\r\n\r\nviewx = %f", ViewPos.X); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewy = %f", ViewPos.Y); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewz = %f", ViewPos.Z); + buffer += mysnprintf (buffer, buffend - buffer, "\r\nviewangle = %f", ViewAngle); } } *buffer++ = '\r'; diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index f33532e29..ebf90e476 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -468,7 +468,7 @@ static void CALLBACK TimerTicked(UINT id, UINT msg, DWORD_PTR user, DWORD_PTR dw // //========================================================================== -fixed_t I_GetTimeFrac(uint32 *ms) +double I_GetTimeFrac(uint32 *ms) { DWORD now = timeGetTime(); if (ms != NULL) @@ -478,12 +478,11 @@ fixed_t I_GetTimeFrac(uint32 *ms) DWORD step = TicNext - TicStart; if (step == 0) { - return FRACUNIT; + return 1.; } else { - fixed_t frac = clamp ((now - TicStart)*FRACUNIT/step, 0, FRACUNIT); - return frac; + return clamp(double(now - TicStart) / step, 0, 1); } } @@ -727,7 +726,7 @@ void CalculateCPUSpeed() PerfToMillisec = PerfToSec * 1000.0; } - if (!batchrun) Printf ("CPU Speed: %.0f MHz\n", 0.001 / PerfToMillisec); + if (!batchrun) Printf ("CPU speed: %.0f MHz\n", 0.001 / PerfToMillisec); } //========================================================================== diff --git a/src/win32/i_system.h b/src/win32/i_system.h index 179af4804..8e75b22a3 100644 --- a/src/win32/i_system.h +++ b/src/win32/i_system.h @@ -90,7 +90,7 @@ extern int (*I_WaitForTic) (int); // tic will never arrive (unless it's the current one). extern void (*I_FreezeTime) (bool frozen); -fixed_t I_GetTimeFrac (uint32 *ms); +double I_GetTimeFrac (uint32 *ms); // Return a seed value for the RNG. unsigned int I_MakeRNGSeed(); diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 00a34578a..f8fcd1fba 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -265,7 +265,7 @@ public: void DrawPixel(int x, int y, int palcolor, uint32 rgbcolor); void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - angle_t rotation, FDynamicColormap *colormap, int lightlevel); + DAngle rotation, FDynamicColormap *colormap, int lightlevel); bool WipeStartScreen(int type); void WipeEndScreen(); bool WipeDo(int ticks); diff --git a/src/xlat/xlat_parser.y b/src/xlat/xlat_parser.y index 9bafb9fb8..e6afc1307 100644 --- a/src/xlat/xlat_parser.y +++ b/src/xlat/xlat_parser.y @@ -30,18 +30,18 @@ external_declaration ::= NOP. %left MULTIPLY DIVIDE MODULUS. %left NEG. -%type exp {int} -exp(A) ::= NUM(B). { A = B.val; } -exp(A) ::= exp(B) PLUS exp(C). { A = B + C; } -exp(A) ::= exp(B) MINUS exp(C). { A = B - C; } -exp(A) ::= exp(B) MULTIPLY exp(C). { A = B * C; } -exp(A) ::= exp(B) DIVIDE exp(C). { if (C != 0) A = B / C; else context->PrintError("Division by zero"); } -exp(A) ::= exp(B) MODULUS exp(C). { if (C != 0) A = B % C; else context->PrintError("Division by zero"); } -exp(A) ::= exp(B) OR exp(C). { A = B | C; } -exp(A) ::= exp(B) AND exp(C). { A = B & C; } -exp(A) ::= exp(B) XOR exp(C). { A = B ^ C; } -exp(A) ::= MINUS exp(B). [NEG] { A = -B; } -exp(A) ::= LPAREN exp(B) RPAREN. { A = B; } +%type expr {int} +expr(A) ::= NUM(B). { A = B.val; } +expr(A) ::= expr(B) PLUS expr(C). { A = B + C; } +expr(A) ::= expr(B) MINUS expr(C). { A = B - C; } +expr(A) ::= expr(B) MULTIPLY expr(C). { A = B * C; } +expr(A) ::= expr(B) DIVIDE expr(C). { if (C != 0) A = B / C; else context->PrintError("Division by zero"); } +expr(A) ::= expr(B) MODULUS expr(C). { if (C != 0) A = B % C; else context->PrintError("Division by zero"); } +expr(A) ::= expr(B) OR expr(C). { A = B | C; } +expr(A) ::= expr(B) AND expr(C). { A = B & C; } +expr(A) ::= expr(B) XOR expr(C). { A = B ^ C; } +expr(A) ::= MINUS expr(B). [NEG] { A = -B; } +expr(A) ::= LPAREN expr(B) RPAREN. { A = B; } //========================================================================== @@ -50,7 +50,7 @@ exp(A) ::= LPAREN exp(B) RPAREN. { A = B; } // //========================================================================== -define_statement ::= DEFINE SYM(A) LPAREN exp(B) RPAREN. +define_statement ::= DEFINE SYM(A) LPAREN expr(B) RPAREN. { context->AddSym (A.sym, B); } @@ -77,7 +77,7 @@ single_enum ::= SYM(A). context->AddSym (A.sym, context->EnumVal++); } -single_enum ::= SYM(A) EQUALS exp(B). +single_enum ::= SYM(A) EQUALS expr(B). { context->AddSym (A.sym, B); context->EnumVal = B+1; @@ -90,19 +90,19 @@ single_enum ::= SYM(A) EQUALS exp(B). //========================================================================== %type linetype_exp {int} -linetype_exp(Z) ::= exp(A). +linetype_exp(Z) ::= expr(A). { Z = static_cast(context)->DefiningLineType = A; } -linetype_declaration ::= linetype_exp(linetype) EQUALS exp(flags) COMMA exp(special) LPAREN special_args(arg) RPAREN. +linetype_declaration ::= linetype_exp(linetype) EQUALS expr(flags) COMMA expr(special) LPAREN special_args(arg) RPAREN. { SimpleLineTranslations.SetVal(linetype, FLineTrans(special&0xffff, flags+arg.addflags, arg.args[0], arg.args[1], arg.args[2], arg.args[3], arg.args[4])); static_cast(context)->DefiningLineType = -1; } -linetype_declaration ::= linetype_exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN. +linetype_declaration ::= linetype_exp EQUALS expr COMMA SYM(S) LPAREN special_args RPAREN. { Printf ("%s, line %d: %s is undefined\n", context->SourceFile, context->SourceLine, S.sym); static_cast(context)->DefiningLineType = -1; @@ -219,7 +219,7 @@ special_args(Z) ::= multi_special_arg(Z). %type boom_body {MoreLines *} -boom_declaration ::= LBRACKET exp(special) RBRACKET LPAREN exp(firsttype) COMMA exp(lasttype) RPAREN LBRACE boom_body(stores) RBRACE. +boom_declaration ::= LBRACKET expr(special) RBRACKET LPAREN expr(firsttype) COMMA expr(lasttype) RPAREN LBRACE boom_body(stores) RBRACE. { int i; MoreLines *probe; @@ -305,12 +305,12 @@ boom_selector(A) ::= ARG5. { A = 3; } boom_op(A) ::= EQUALS. { A = '='; } boom_op(A) ::= OR_EQUAL. { A = OR_EQUAL; } -boom_args(A) ::= exp(B). +boom_args(A) ::= expr(B). { A.constant = B; A.filters = NULL; } -boom_args(A) ::= exp(B) LBRACKET arg_list(C) RBRACKET. +boom_args(A) ::= expr(B) LBRACKET arg_list(C) RBRACKET. { A.mask = B; A.filters = C; @@ -329,7 +329,7 @@ arg_list(A) ::= list_val(B) COMMA arg_list(C). A->filter = B; } -list_val(A) ::= exp(B) COLON exp(C). +list_val(A) ::= expr(B) COLON expr(C). { A.filter = B; A.value = C; @@ -341,7 +341,7 @@ list_val(A) ::= exp(B) COLON exp(C). // //========================================================================== -maxlinespecial_def ::= MAXLINESPECIAL EQUALS exp(mx) SEMICOLON. +maxlinespecial_def ::= MAXLINESPECIAL EQUALS expr(mx) SEMICOLON. { // Just kill all specials higher than the max. // If the translator wants to redefine some later, just let it. @@ -356,36 +356,36 @@ maxlinespecial_def ::= MAXLINESPECIAL EQUALS exp(mx) SEMICOLON. %type sector_op {int} -sector_declaration ::= SECTOR exp(from) EQUALS exp(to) SEMICOLON. +sector_declaration ::= SECTOR expr(from) EQUALS expr(to) SEMICOLON. { FSectorTrans tr(to, true); SectorTranslations.SetVal(from, tr); } -sector_declaration ::= SECTOR exp EQUALS SYM(sy) SEMICOLON. +sector_declaration ::= SECTOR expr EQUALS SYM(sy) SEMICOLON. { Printf("Unknown constant '%s'\n", sy.sym); } -sector_declaration ::= SECTOR exp(from) EQUALS exp(to) NOBITMASK SEMICOLON. +sector_declaration ::= SECTOR expr(from) EQUALS expr(to) NOBITMASK SEMICOLON. { FSectorTrans tr(to, false); SectorTranslations.SetVal(from, tr); } -sector_bitmask ::= SECTOR BITMASK exp(mask) sector_op(op) exp(shift) SEMICOLON. +sector_bitmask ::= SECTOR BITMASK expr(mask) sector_op(op) expr(shift) SEMICOLON. { FSectorMask sm = { mask, op, shift}; SectorMasks.Push(sm); } -sector_bitmask ::= SECTOR BITMASK exp(mask) SEMICOLON. +sector_bitmask ::= SECTOR BITMASK expr(mask) SEMICOLON. { FSectorMask sm = { mask, 0, 0}; SectorMasks.Push(sm); } -sector_bitmask ::= SECTOR BITMASK exp(mask) CLEAR SEMICOLON. +sector_bitmask ::= SECTOR BITMASK expr(mask) CLEAR SEMICOLON. { FSectorMask sm = { mask, 0, 1}; SectorMasks.Push(sm); @@ -396,7 +396,7 @@ sector_op(A) ::= RSHASSIGN. { A = -1; } %type lineflag_op {int} -lineflag_declaration ::= LINEFLAG exp(from) EQUALS exp(to) SEMICOLON. +lineflag_declaration ::= LINEFLAG expr(from) EQUALS expr(to) SEMICOLON. { if (from >= 0 && from < 16) { @@ -405,7 +405,7 @@ lineflag_declaration ::= LINEFLAG exp(from) EQUALS exp(to) SEMICOLON. } } -lineflag_declaration ::= LINEFLAG exp(from) AND exp(mask) SEMICOLON. +lineflag_declaration ::= LINEFLAG expr(from) AND expr(mask) SEMICOLON. { if (from >= 0 && from < 16) { diff --git a/src/xs_Float.h b/src/xs_Float.h index b4b5218c5..33150e4ea 100644 --- a/src/xs_Float.h +++ b/src/xs_Float.h @@ -15,6 +15,8 @@ #ifndef _xs_FLOAT_H_ #define _xs_FLOAT_H_ +#include + // ==================================================================================================================== // Defines // ==================================================================================================================== @@ -37,15 +39,18 @@ #define finline __forceinline #endif +typedef double real64; + + union _xs_doubleints { real64 val; - uint32 ival[2]; + uint32_t ival[2]; }; #if 0 -#define _xs_doublecopysgn(a,b) ((int32*)&a)[_xs_iexp_]&=~(((int32*)&b)[_xs_iexp_]&0x80000000) -#define _xs_doubleisnegative(a) ((((int32*)&a)[_xs_iexp_])|0x80000000) +#define _xs_doublecopysgn(a,b) ((int32_t*)&a)[_xs_iexp_]&=~(((int32_t*)&b)[_xs_iexp_]&0x80000000) +#define _xs_doubleisnegative(a) ((((int32_t*)&a)[_xs_iexp_])|0x80000000) #endif // ==================================================================================================================== @@ -59,37 +64,37 @@ const real64 _xs_doublemagicroundeps = (.5f-_xs_doublemagicdelta); //almos // ==================================================================================================================== // Prototypes // ==================================================================================================================== -static int32 xs_CRoundToInt (real64 val, real64 dmr = _xs_doublemagic); -static int32 xs_ToInt (real64 val, real64 dme = -_xs_doublemagicroundeps); -static int32 xs_FloorToInt (real64 val, real64 dme = _xs_doublemagicroundeps); -static int32 xs_CeilToInt (real64 val, real64 dme = _xs_doublemagicroundeps); -static int32 xs_RoundToInt (real64 val); +static int32_t xs_CRoundToInt (real64 val, real64 dmr = _xs_doublemagic); +static int32_t xs_ToInt (real64 val, real64 dme = -_xs_doublemagicroundeps); +static int32_t xs_FloorToInt (real64 val, real64 dme = _xs_doublemagicroundeps); +static int32_t xs_CeilToInt (real64 val, real64 dme = _xs_doublemagicroundeps); +static int32_t xs_RoundToInt (real64 val); -//int32 versions -finline static int32 xs_CRoundToInt (int32 val) {return val;} -finline static int32 xs_ToInt (int32 val) {return val;} +//int32_t versions +finline static int32_t xs_CRoundToInt (int32_t val) {return val;} +finline static int32_t xs_ToInt (int32_t val) {return val;} // ==================================================================================================================== // Fix Class // ==================================================================================================================== -template class xs_Fix +template class xs_Fix { public: - typedef int32 Fix; + typedef int32_t Fix; // ==================================================================================================================== // Basic Conversion from Numbers // ==================================================================================================================== - finline static Fix ToFix (int32 val) {return val<>N;} + finline static int32_t ToInt (Fix f) {return f>>N;} @@ -97,7 +102,7 @@ protected: // ==================================================================================================================== // Helper function - mainly to preserve _xs_DEFAULT_CONVERSION // ==================================================================================================================== - finline static int32 xs_ConvertToFixed (real64 val) + finline static int32_t xs_ConvertToFixed (real64 val) { #if _xs_DEFAULT_CONVERSION==0 return xs_CRoundToInt(val, _xs_doublemagic/(1<int conversion, but unfortunately, // checking for SSE support every time you need to do a // conversion completely negates its performance advantage. - return int32(val); + return int32_t(val); #else #if _xs_DEFAULT_CONVERSION==0 return (val<0) ? xs_CRoundToInt(val-dme) : xs_CRoundToInt(val+dme); #else - return int32(val); + return int32_t(val); #endif #endif } // ==================================================================================================================== -finline static int32 xs_FloorToInt(real64 val, real64 dme) +finline static int32_t xs_FloorToInt(real64 val, real64 dme) { #if _xs_DEFAULT_CONVERSION==0 return xs_CRoundToInt (val - dme); @@ -167,7 +172,7 @@ finline static int32 xs_FloorToInt(real64 val, real64 dme) // ==================================================================================================================== -finline static int32 xs_CeilToInt(real64 val, real64 dme) +finline static int32_t xs_CeilToInt(real64 val, real64 dme) { #if _xs_DEFAULT_CONVERSION==0 return xs_CRoundToInt (val + dme); @@ -178,7 +183,7 @@ finline static int32 xs_CeilToInt(real64 val, real64 dme) // ==================================================================================================================== -finline static int32 xs_RoundToInt(real64 val) +finline static int32_t xs_RoundToInt(real64 val) { #if _xs_DEFAULT_CONVERSION==0 // Yes, it is important that two fadds be generated, so you cannot override the dmr @@ -197,24 +202,24 @@ finline static int32 xs_RoundToInt(real64 val) // Unsigned variants // ==================================================================================================================== // ==================================================================================================================== -finline static uint32 xs_CRoundToUInt(real64 val) +finline static uint32_t xs_CRoundToUInt(real64 val) { - return (uint32)xs_CRoundToInt(val); + return (uint32_t)xs_CRoundToInt(val); } -finline static uint32 xs_FloorToUInt(real64 val) +finline static uint32_t xs_FloorToUInt(real64 val) { - return (uint32)xs_FloorToInt(val); + return (uint32_t)xs_FloorToInt(val); } -finline static uint32 xs_CeilToUInt(real64 val) +finline static uint32_t xs_CeilToUInt(real64 val) { - return (uint32)xs_CeilToInt(val); + return (uint32_t)xs_CeilToInt(val); } -finline static uint32 xs_RoundToUInt(real64 val) +finline static uint32_t xs_RoundToUInt(real64 val) { - return (uint32)xs_RoundToInt(val); + return (uint32_t)xs_RoundToInt(val); } diff --git a/src/zscript/vm.h b/src/zscript/vm.h index 8fb740274..317a69846 100644 --- a/src/zscript/vm.h +++ b/src/zscript/vm.h @@ -894,8 +894,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_SOUND_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); FSoundID x = param[p].i; #define PARAM_COLOR_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); PalEntry x; x.d = param[p].i; #define PARAM_FLOAT_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); double x = param[p].f; -#define PARAM_FIXED_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); fixed_t x = FLOAT2FIXED(param[p].f); -#define PARAM_ANGLE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); angle_t x = FLOAT2ANGLE(param[p].f); +#define PARAM_ANGLE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); DAngle x = param[p].f; #define PARAM_STRING_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_STRING); FString x = param[p].s(); #define PARAM_STATE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); FState *x = (FState *)param[p].a; #define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)param[p].a; @@ -912,8 +911,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_SOUND_OPT_AT(p,x) FSoundID x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x = FSoundID(param[p].i); } else #define PARAM_COLOR_OPT_AT(p,x) PalEntry x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_INT); x.d = param[p].i; } else #define PARAM_FLOAT_OPT_AT(p,x) double x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else -#define PARAM_FIXED_OPT_AT(p,x) fixed_t x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = FLOAT2FIXED(param[p].f); } else -#define PARAM_ANGLE_OPT_AT(p,x) angle_t x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = FLOAT2ANGLE(param[p].f); } else +#define PARAM_ANGLE_OPT_AT(p,x) DAngle x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else #define PARAM_STRING_OPT_AT(p,x) FString x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_STRING); x = param[p].s(); } else #define PARAM_STATE_OPT_AT(p,x) FState *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); x = (FState *)param[p].a; } else #define PARAM_POINTER_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER); x = (type *)param[p].a; } else @@ -929,7 +927,6 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_SOUND(x) ++paramnum; PARAM_SOUND_AT(paramnum,x) #define PARAM_COLOR(x) ++paramnum; PARAM_COLOR_AT(paramnum,x) #define PARAM_FLOAT(x) ++paramnum; PARAM_FLOAT_AT(paramnum,x) -#define PARAM_FIXED(x) ++paramnum; PARAM_FIXED_AT(paramnum,x) #define PARAM_ANGLE(x) ++paramnum; PARAM_ANGLE_AT(paramnum,x) #define PARAM_STRING(x) ++paramnum; PARAM_STRING_AT(paramnum,x) #define PARAM_STATE(x) ++paramnum; PARAM_STATE_AT(paramnum,x) @@ -943,7 +940,6 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_SOUND_OPT(x) ++paramnum; PARAM_SOUND_OPT_AT(paramnum,x) #define PARAM_COLOR_OPT(x) ++paramnum; PARAM_COLOR_OPT_AT(paramnum,x) #define PARAM_FLOAT_OPT(x) ++paramnum; PARAM_FLOAT_OPT_AT(paramnum,x) -#define PARAM_FIXED_OPT(x) ++paramnum; PARAM_FIXED_OPT_AT(paramnum,x) #define PARAM_ANGLE_OPT(x) ++paramnum; PARAM_ANGLE_OPT_AT(paramnum,x) #define PARAM_STRING_OPT(x) ++paramnum; PARAM_STRING_OPT_AT(paramnum,x) #define PARAM_STATE_OPT(x) ++paramnum; PARAM_STATE_OPT_AT(paramnum,x) diff --git a/src/zscript/vmexec.cpp b/src/zscript/vmexec.cpp index ebce8c5f2..070aeb30a 100644 --- a/src/zscript/vmexec.cpp +++ b/src/zscript/vmexec.cpp @@ -1,6 +1,7 @@ #include #include "vm.h" #include "xs_Float.h" +#include "math/cmath.h" #define IMPLEMENT_VMEXEC diff --git a/src/zscript/vmexec.h b/src/zscript/vmexec.h index eb54e7b76..1804d4c36 100644 --- a/src/zscript/vmexec.h +++ b/src/zscript/vmexec.h @@ -210,26 +210,6 @@ begin: reg.f[a+2] = v[2]; } NEXTOP; - OP(LX): - ASSERTF(a); ASSERTA(B); ASSERTKD(C); - GETADDR(PB,KC,X_READ_NIL); - reg.f[a] = *(VM_SWORD *)ptr / 65536.0; - NEXTOP; - OP(LX_R): - ASSERTF(a); ASSERTA(B); ASSERTD(C); - GETADDR(PB,RC,X_READ_NIL); - reg.f[a] = *(VM_SWORD *)ptr / 65536.0; - NEXTOP; - OP(LANG): - ASSERTF(a); ASSERTA(B); ASSERTKD(C); - GETADDR(PB,KC,X_READ_NIL); - reg.f[a] = (*(VM_UWORD *)ptr >> 1) * (180.0 / 0x40000000); // BAM -> deg - NEXTOP; - OP(LANG_R): - ASSERTF(a); ASSERTA(B); ASSERTD(C); - GETADDR(PB,RC,X_READ_NIL); - reg.f[a] = (*(VM_UWORD *)ptr >> 1) * (180.0 / 0x40000000); - NEXTOP; OP(LBIT): ASSERTD(a); ASSERTA(B); GETADDR(PB,0,X_READ_NIL); @@ -326,26 +306,6 @@ begin: v[2] = (float)reg.f[B+2]; } NEXTOP; - OP(SX): - ASSERTA(a); ASSERTF(B); ASSERTKD(C); - GETADDR(PA,KC,X_WRITE_NIL); - *(VM_SWORD *)ptr = (VM_SWORD)(reg.f[B] * 65536.0); - NEXTOP; - OP(SX_R): - ASSERTA(a); ASSERTF(B); ASSERTD(C); - GETADDR(PA,RC,X_WRITE_NIL); - *(VM_SWORD *)ptr = (VM_SWORD)(reg.f[B] * 65536.0); - NEXTOP; - OP(SANG): - ASSERTA(a); ASSERTF(B); ASSERTKD(C); - GETADDR(PA,KC,X_WRITE_NIL); - *(VM_UWORD *)ptr = (VM_UWORD)(xs_CRoundToInt((reg.f[B]) * (0x40000000/90.))); // deg -> BAM - NEXTOP; - OP(SANG_R): - ASSERTA(a); ASSERTF(B); ASSERTD(C); - GETADDR(PA,RC,X_WRITE_NIL); - *(VM_UWORD *)ptr = (VM_UWORD)(xs_CRoundToInt((reg.f[B]) * (0x40000000/90.))); - NEXTOP; OP(SBIT): ASSERTA(a); ASSERTD(B); GETADDR(PA,0,X_WRITE_NIL); @@ -1269,7 +1229,7 @@ begin: OP(LENV): ASSERTF(a); ASSERTF(B+2); - reg.f[a] = sqrt(reg.f[B] * reg.f[B] + reg.f[B+1] * reg.f[B+1] + reg.f[B+2] * reg.f[B+2]); + reg.f[a] = g_sqrt(reg.f[B] * reg.f[B] + reg.f[B+1] * reg.f[B+1] + reg.f[B+2] * reg.f[B+2]); NEXTOP; OP(EQV_R): @@ -1392,30 +1352,30 @@ static double DoFLOP(int flop, double v) { case FLOP_ABS: return fabs(v); case FLOP_NEG: return -v; - case FLOP_EXP: return exp(v); - case FLOP_LOG: return log(v); - case FLOP_LOG10: return log10(v); - case FLOP_SQRT: return sqrt(v); + case FLOP_EXP: return g_exp(v); + case FLOP_LOG: return g_log(v); + case FLOP_LOG10: return g_log10(v); + case FLOP_SQRT: return g_sqrt(v); case FLOP_CEIL: return ceil(v); case FLOP_FLOOR: return floor(v); - case FLOP_ACOS: return acos(v); - case FLOP_ASIN: return asin(v); - case FLOP_ATAN: return atan(v); - case FLOP_COS: return cos(v); - case FLOP_SIN: return sin(v); - case FLOP_TAN: return tan(v); + case FLOP_ACOS: return g_acos(v); + case FLOP_ASIN: return g_asin(v); + case FLOP_ATAN: return g_atan(v); + case FLOP_COS: return g_cos(v); + case FLOP_SIN: return g_sin(v); + case FLOP_TAN: return g_tan(v); - case FLOP_ACOS_DEG: return acos(v) * (180 / M_PI); - case FLOP_ASIN_DEG: return asin(v) * (180 / M_PI); - case FLOP_ATAN_DEG: return atan(v) * (180 / M_PI); - case FLOP_COS_DEG: return cos(v * (M_PI / 180)); - case FLOP_SIN_DEG: return sin(v * (M_PI / 180)); - case FLOP_TAN_DEG: return tan(v * (M_PI / 180)); + case FLOP_ACOS_DEG: return g_acos(v) * (180 / M_PI); + case FLOP_ASIN_DEG: return g_asin(v) * (180 / M_PI); + case FLOP_ATAN_DEG: return g_atan(v) * (180 / M_PI); + case FLOP_COS_DEG: return g_cosdeg(v); + case FLOP_SIN_DEG: return g_sindeg(v); + case FLOP_TAN_DEG: return g_tan(v * (M_PI / 180)); - case FLOP_COSH: return cosh(v); - case FLOP_SINH: return sinh(v); - case FLOP_TANH: return tanh(v); + case FLOP_COSH: return g_cosh(v); + case FLOP_SINH: return g_sinh(v); + case FLOP_TANH: return g_tanh(v); } assert(0); return 0; diff --git a/src/zscript/vmops.h b/src/zscript/vmops.h index 36924d6bb..bb4c034c7 100644 --- a/src/zscript/vmops.h +++ b/src/zscript/vmops.h @@ -35,10 +35,6 @@ xx(LP, lp, RPRPKI), // load pointer xx(LP_R, lp, RPRPRI), xx(LV, lv, RVRPKI), // load vector xx(LV_R, lv, RVRPRI), -xx(LX, lx, RFRPKI), // load fixed point -xx(LX_R, lx, RFRPRI), -xx(LANG, lang, RFRPKI), // load angle -xx(LANG_R, lang, RFRPRI), xx(LBIT, lbit, RIRPI8), // rA = !!(*rB & C) -- *rB is a byte @@ -59,10 +55,6 @@ xx(SP, sp, RPRPKI), // store pointer xx(SP_R, sp, RPRPRI), xx(SV, sv, RPRVKI), // store vector xx(SV_R, sv, RPRVRI), -xx(SX, sx, RPRFKI), // store fixed point -xx(SX_R, sx, RPRFRI), -xx(SANG, sang, RPRFKI), // store angle -xx(SANG_R, sang, RPRFRI), xx(SBIT, sbit, RPRII8), // *rA |= C if rB is true, *rA &= ~C otherwise diff --git a/src/zscript/zcc_expr.cpp b/src/zscript/zcc_expr.cpp index 644a122a5..0cd399d64 100644 --- a/src/zscript/zcc_expr.cpp +++ b/src/zscript/zcc_expr.cpp @@ -1,3 +1,4 @@ +#include #include "dobject.h" #include "sc_man.h" #include "c_console.h" diff --git a/src/zstrformat.cpp b/src/zstrformat.cpp index 63c179ca6..65ed889ae 100644 --- a/src/zstrformat.cpp +++ b/src/zstrformat.cpp @@ -92,12 +92,8 @@ #include "zstring.h" #include "gdtoa.h" -#ifndef _MSC_VER #include -#else -typedef unsigned __int64 uint64_t; -typedef signed __int64 int64_t; -#endif + /* * MAXEXPDIG is the maximum number of decimal digits needed to store a diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index aa751e332..2aecefafa 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -184,7 +184,7 @@ ACTOR Actor native //: Thinker action native A_StopSoundEx(coerce name slot); action native A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10); action native state A_Jump(int chance = 256, state label, ...); - action native A_CustomMissile(class missiletype, float spawnheight = 32, int spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET); + action native A_CustomMissile(class missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET); action native A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET); action native A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270); action native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT); diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 98a195f01..cf01cd54c 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -10,7 +10,7 @@ ACTOR Inventory native action native state A_JumpIfNoAmmo(state label); action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = ""); action native A_FireBullets(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", int flags = 1, float range = 0); - action native A_FireCustomMissile(class missiletype, float angle = 0, bool useammo = true, int spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0); + action native A_FireCustomMissile(class missiletype, float angle = 0, bool useammo = true, float spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0); action native A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270); action native A_Light(int extralight); action native A_Light0(); @@ -105,7 +105,7 @@ ACTOR BasicArmorBonus : Armor native +Inventory.AUTOACTIVATE +Inventory.ALWAYSPICKUP Inventory.MaxAmount 0 - Armor.SavePercent 0.333333 + Armor.SavePercent 33.335 } diff --git a/wadsrc/static/actors/strife/strifeweapons.txt b/wadsrc/static/actors/strife/strifeweapons.txt index 4e4990e98..b807f110a 100644 --- a/wadsrc/static/actors/strife/strifeweapons.txt +++ b/wadsrc/static/actors/strife/strifeweapons.txt @@ -740,7 +740,7 @@ ACTOR StrifeGrenadeLauncher : StrifeWeapon Tag "$TAG_GLAUNCHER1" Inventory.PickupMessage "$TXT_GLAUNCHER" - action native A_FireGrenade (class grenadetype, int angleofs, state flash); + action native A_FireGrenade (class grenadetype, float angleofs, state flash); States {