Revert "- xs_Float.h: Make all inlines return an unsigned value, and change previous unsigned inlines to signed."

Revert "- `xs_Float.h`: Add `getint()` getter to `_xs_doubleints` struct."
Revert "- SW: When adjusting horizon in `DoPlayerDeathHoriz()`, just use integer horizon values and not Q16.16."
Revert "- Duke (RR): Clean up some unnecessary `FixedToFloat()` usage with the `fixedhoriz` `asbuildf()` method."
Revert "- `binaryangle.h`: Use `constexpr` on inline functions where it was previously not possible to do so."
Revert "- `m_fixed.h`: Use `constexpr` on inline functions where it was previously not possible to do so."
Revert "- `xs_Float.h`: Convert header to `constexpr`."

This does nor work as it violates the constexpr rules for unions. The code will error out on compilation for accessing an inactive member of a union.
This commit is contained in:
Christoph Oelckers 2021-11-01 20:25:38 +01:00
parent d9bbe1fa61
commit 86166f5e67
5 changed files with 116 additions and 100 deletions

View file

@ -42,16 +42,10 @@
typedef double real64;
struct _xs_doubleints
union _xs_doubleints
{
union
{
real64 val;
uint32_t ival[2];
};
constexpr _xs_doubleints(real64 v) : val(v) {}
constexpr uint32_t getint() const { return ival[_xs_iman_]; }
real64 val;
uint32_t ival[2];
};
#if 0
@ -62,9 +56,73 @@ struct _xs_doubleints
// ====================================================================================================================
// Constants
// ====================================================================================================================
constexpr real64 _xs_doublemagic = real64 (6755399441055744.0); //2^52 * 1.5, uses limited precisicion to floor
constexpr real64 _xs_doublemagicdelta = (1.5e-8); //almost .5f = .5f + 1e^(number of exp bit)
constexpr real64 _xs_doublemagicroundeps = (.5f-_xs_doublemagicdelta); //almost .5f = .5f - 1e^(number of exp bit)
const real64 _xs_doublemagic = real64 (6755399441055744.0); //2^52 * 1.5, uses limited precisicion to floor
const real64 _xs_doublemagicdelta = (1.5e-8); //almost .5f = .5f + 1e^(number of exp bit)
const real64 _xs_doublemagicroundeps = (.5f-_xs_doublemagicdelta); //almost .5f = .5f - 1e^(number of exp bit)
// ====================================================================================================================
// Prototypes
// ====================================================================================================================
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_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 <int32_t N> class xs_Fix
{
public:
typedef int32_t Fix;
// ====================================================================================================================
// Basic Conversion from Numbers
// ====================================================================================================================
finline static Fix ToFix (int32_t val) {return val<<N;}
finline static Fix ToFix (real64 val) {return xs_ConvertToFixed(val);}
// ====================================================================================================================
// Basic Conversion to Numbers
// ====================================================================================================================
finline static real64 ToReal (Fix f) {return real64(f)/real64(1<<N);}
finline static int32_t ToInt (Fix f) {return f>>N;}
protected:
// ====================================================================================================================
// Helper function - mainly to preserve _xs_DEFAULT_CONVERSION
// ====================================================================================================================
finline static int32_t xs_ConvertToFixed (real64 val)
{
#if _xs_DEFAULT_CONVERSION==0
return xs_CRoundToInt(val, _xs_doublemagic/(1<<N));
#else
return (long)((val)*(1<<N));
#endif
}
};
finline static int32_t xs_ToFixed(int32_t n, real64 val)
{
#if _xs_DEFAULT_CONVERSION==0
return xs_CRoundToInt(val, _xs_doublemagic/(1<<n));
#else
return (long)((val)*(1<<N));
#endif
}
// ====================================================================================================================
@ -72,22 +130,20 @@ constexpr real64 _xs_doublemagicroundeps = (.5f-_xs_doublemagicdelta);
// Inline implementation
// ====================================================================================================================
// ====================================================================================================================
finline constexpr uint32_t xs_CRoundToUInt(real64 val, real64 dmr = _xs_doublemagic)
finline static int32_t xs_CRoundToInt(real64 val, real64 dmr)
{
#if _xs_DEFAULT_CONVERSION==0
return _xs_doubleints(val + dmr).getint();
_xs_doubleints uval;
uval.val = val + dmr;
return uval.ival[_xs_iman_];
#else
return uint32_t(floor(val+.5));
return int32_t(floor(val+.5));
#endif
}
finline constexpr int32_t xs_CRoundToInt(real64 val)
{
return (int32_t)xs_CRoundToUInt(val);
}
// ====================================================================================================================
finline constexpr int32_t xs_ToInt(real64 val, real64 dme = -_xs_doublemagicroundeps)
finline static int32_t xs_ToInt(real64 val, real64 dme)
{
/* unused - something else I tried...
_xs_doublecopysgn(dme,val);
@ -114,107 +170,67 @@ finline constexpr int32_t xs_ToInt(real64 val, real64 dme = -_xs_doublemagicroun
// ====================================================================================================================
finline constexpr uint32_t xs_FloorToUInt(real64 val, real64 dme = _xs_doublemagicroundeps)
finline static int32_t xs_FloorToInt(real64 val, real64 dme)
{
#if _xs_DEFAULT_CONVERSION==0
return xs_CRoundToUInt (val - dme);
return xs_CRoundToInt (val - dme);
#else
return floor(val);
#endif
}
finline constexpr int32_t xs_FloorToInt(real64 val)
{
return (int32_t)xs_FloorToUInt(val);
}
// ====================================================================================================================
finline constexpr uint32_t xs_CeilToUInt(real64 val, real64 dme = _xs_doublemagicroundeps)
finline static int32_t xs_CeilToInt(real64 val, real64 dme)
{
#if _xs_DEFAULT_CONVERSION==0
return xs_CRoundToUInt (val + dme);
return xs_CRoundToInt (val + dme);
#else
return ceil(val);
#endif
}
finline constexpr int32_t xs_CeilToInt(real64 val)
{
return (int32_t)xs_CeilToUInt(val);
}
// ====================================================================================================================
finline constexpr uint32_t xs_RoundToUInt(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
// passed to xs_CRoundToInt with _xs_doublemagic + _xs_doublemagicdelta. If you do,
// you'll end up with Banker's Rounding again.
return xs_CRoundToUInt (val + _xs_doublemagicdelta);
return xs_CRoundToInt (val + _xs_doublemagicdelta);
#else
return floor(val+.5);
#endif
}
finline constexpr int32_t xs_RoundToInt(real64 val)
// ====================================================================================================================
// ====================================================================================================================
// Unsigned variants
// ====================================================================================================================
// ====================================================================================================================
finline static uint32_t xs_CRoundToUInt(real64 val)
{
return (int32_t)xs_RoundToUInt(val);
return (uint32_t)xs_CRoundToInt(val);
}
// ====================================================================================================================
finline constexpr int32_t xs_ToFixed(int32_t n, real64 val)
finline static uint32_t xs_FloorToUInt(real64 val)
{
#if _xs_DEFAULT_CONVERSION==0
return xs_CRoundToUInt(val, _xs_doublemagic/(1<<n));
#else
return (long)((val)*(1<<N));
#endif
return (uint32_t)xs_FloorToInt(val);
}
//int32_t versions
finline constexpr int32_t xs_CRoundToInt (int32_t val) {return val;}
finline constexpr int32_t xs_ToInt (int32_t val) {return val;}
// ====================================================================================================================
// Fix Class
// ====================================================================================================================
template <int32_t N> class xs_Fix
finline static uint32_t xs_CeilToUInt(real64 val)
{
public:
typedef int32_t Fix;
return (uint32_t)xs_CeilToInt(val);
}
// ====================================================================================================================
// Basic Conversion from Numbers
// ====================================================================================================================
finline static constexpr Fix ToFix (int32_t val) {return val<<N;}
finline static constexpr Fix ToFix (real64 val) {return xs_ConvertToFixed(val);}
finline static uint32_t xs_RoundToUInt(real64 val)
{
return (uint32_t)xs_RoundToInt(val);
}
// ====================================================================================================================
// Basic Conversion to Numbers
// ====================================================================================================================
finline static constexpr real64 ToReal (Fix f) {return real64(f)/real64(1<<N);}
finline static constexpr int32_t ToInt (Fix f) {return f>>N;}
protected:
// ====================================================================================================================
// Helper function - mainly to preserve _xs_DEFAULT_CONVERSION
// ====================================================================================================================
finline static constexpr int32_t xs_ConvertToFixed (real64 val)
{
#if _xs_DEFAULT_CONVERSION==0
return xs_CRoundToUInt(val, _xs_doublemagic/(1<<N));
#else
return (long)((val)*(1<<N));
#endif
}
};
// ====================================================================================================================

View file

@ -15,7 +15,7 @@ __forceinline constexpr int64_t DivScaleL(int64_t a, int64_t b, int shift) { ret
#include "xs_Float.h"
inline constexpr fixed_t FloatToFixed(double f)
inline fixed_t FloatToFixed(double f)
{
return xs_Fix<16>::ToFix(f);
}
@ -32,10 +32,10 @@ inline constexpr double FixedToFloat(fixed_t f)
inline constexpr int32_t FixedToInt(fixed_t f)
{
return (f + (FRACUNIT >> 1)) >> FRACBITS;
return (f + FRACUNIT/2) >> FRACBITS;
}
inline constexpr unsigned FloatToAngle(double f)
inline unsigned FloatToAngle(double f)
{
return xs_CRoundToInt((f)* (0x40000000 / 90.));
}

View file

@ -118,9 +118,9 @@ class binangle
friend constexpr binangle bamang(uint32_t v);
friend constexpr binangle q16ang(uint32_t v);
friend constexpr binangle buildang(uint32_t v);
friend constexpr binangle buildfang(double v);
friend constexpr binangle radang(double v);
friend constexpr binangle degang(double v);
friend binangle buildfang(double v);
friend binangle radang(double v);
friend binangle degang(double v);
friend FSerializer &Serialize(FSerializer &arc, const char *key, binangle &obj, binangle *defval);
@ -207,9 +207,9 @@ public:
inline constexpr binangle bamang(uint32_t v) { return binangle(v); }
inline constexpr binangle q16ang(uint32_t v) { return binangle(v << 5); }
inline constexpr binangle buildang(uint32_t v) { return binangle(v << BAMBITS); }
inline constexpr binangle buildfang(double v) { return binangle(xs_CRoundToUInt(v * BAMUNIT)); }
inline constexpr binangle radang(double v) { return binangle(xs_CRoundToUInt(v * (0x80000000u / pi::pi()))); }
inline constexpr binangle degang(double v) { return binangle(FloatToAngle(v)); }
inline binangle buildfang(double v) { return binangle(xs_CRoundToUInt(v * BAMUNIT)); }
inline binangle radang(double v) { return binangle(xs_CRoundToUInt(v * (0x80000000u / pi::pi()))); }
inline binangle degang(double v) { return binangle(FloatToAngle(v)); }
inline FSerializer &Serialize(FSerializer &arc, const char *key, binangle &obj, binangle *defval)
{
@ -226,7 +226,7 @@ inline FSerializer &Serialize(FSerializer &arc, const char *key, binangle &obj,
inline double HorizToPitch(double horiz) { return atan2(horiz, 128) * (180. / pi::pi()); }
inline double HorizToPitch(fixed_t q16horiz) { return atan2(q16horiz, IntToFixed(128)) * (180. / pi::pi()); }
inline fixed_t PitchToHoriz(double pitch) { return xs_CRoundToInt(IntToFixed(128) * tan(pitch * (pi::pi() / 180.))); }
inline constexpr int32_t PitchToBAM(double pitch) { return int(clamp<double>(pitch * (1073741823.5 / 45.), -INT32_MAX, INT32_MAX)); }
inline int32_t PitchToBAM(double pitch) { return xs_CRoundToInt(clamp<double>(pitch * (1073741823.5 / 45.), -INT32_MAX, INT32_MAX)); }
inline constexpr double BAMToPitch(int32_t bam) { return bam * (45. / 1073741823.5); }
@ -244,7 +244,7 @@ class fixedhoriz
friend constexpr fixedhoriz q16horiz(fixed_t v);
friend constexpr fixedhoriz buildhoriz(int v);
friend constexpr fixedhoriz buildfhoriz(double v);
friend fixedhoriz buildfhoriz(double v);
friend fixedhoriz pitchhoriz(double v);
friend fixedhoriz bamhoriz(int32_t v);
@ -343,7 +343,7 @@ public:
inline constexpr fixedhoriz q16horiz(fixed_t v) { return fixedhoriz(v); }
inline constexpr fixedhoriz buildhoriz(int v) { return fixedhoriz(IntToFixed(v)); }
inline constexpr fixedhoriz buildfhoriz(double v) { return fixedhoriz(FloatToFixed(v)); }
inline fixedhoriz buildfhoriz(double v) { return fixedhoriz(FloatToFixed(v)); }
inline fixedhoriz pitchhoriz(double v) { return fixedhoriz(PitchToHoriz(v)); }
inline fixedhoriz bamhoriz(int32_t v) { return pitchhoriz(BAMToPitch(v)); }

View file

@ -1742,7 +1742,7 @@ static void onMotorcycle(int snum, ESyncBits &actions)
}
if (horiz != FRACUNIT)
{
p->horizon.addadjustment(horiz - p->horizon.horiz.asbuildf());
p->horizon.addadjustment(horiz - FixedToFloat(p->horizon.horiz.asq16()));
}
int currSpeed = int(p->MotoSpeed);
@ -2010,7 +2010,7 @@ static void onBoat(int snum, ESyncBits &actions)
}
if (horiz != FRACUNIT)
{
p->horizon.addadjustment(horiz - p->horizon.horiz.asbuildf());
p->horizon.addadjustment(horiz - FixedToFloat(p->horizon.horiz.asq16()));
}
if (p->MotoSpeed > 0 && p->on_ground == 1 && (p->vehTurnLeft || p->vehTurnRight))

View file

@ -6038,12 +6038,12 @@ DoPlayerBeginDie(PLAYERp pp)
void
DoPlayerDeathHoriz(PLAYERp pp, short target, short speed)
{
if ((pp->horizon.horiz.asbuild() - target) > 1)
if ((pp->horizon.horiz.asq16() - IntToFixed(target)) > FRACUNIT)
{
pp->horizon.addadjustment(-speed);
}
if ((target - pp->horizon.horiz.asbuild()) > 1)
if ((IntToFixed(target) - pp->horizon.horiz.asq16()) > FRACUNIT)
{
pp->horizon.addadjustment(speed);
}