Advertisement
Kitomas

fx16_8.hpp

Dec 1st, 2023
621
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.59 KB | None | 0 0
  1. #ifndef _UTILS_FX16_8_HPP
  2. #define _UTILS_FX16_8_HPP
  3.  
  4.  
  5. #include <stdexcept>
  6.  
  7. #include <SDL2/SDL.h>
  8.  
  9.  
  10.  
  11.  
  12. struct fx16_8; //forward declaration
  13.  
  14. extern const fx16_8 fx_epsilon; // = 1/256
  15. extern const fx16_8 fx_1third;  // = 1/3
  16. extern const fx16_8 fx_2thirds; // = 2/3
  17. extern const fx16_8 fx_half;    // = 1/2
  18.  
  19. extern const fx16_8 fx_sqrt2; // = sqrt(2)
  20.  
  21. extern const fx16_8 fx_invpi; // = 1/pi
  22. extern const fx16_8 fx_pi4;   // = pi/4
  23. extern const fx16_8 fx_pi2;   // = pi/2
  24. extern const fx16_8 fx_pi;    // = pi
  25. extern const fx16_8 fx_2pi;   // = pi*2
  26.  
  27. extern const fx16_8 fx_pi_180;    // = pi/180
  28. extern const fx16_8 fx_180_pi;    // = 180/pi
  29. extern const fx16_8 fx_invpi_180; // = 1/(pi/180)
  30. extern const fx16_8 fx_inv180_pi; // = 1/(180/pi)
  31.  
  32. extern const Sint16 _fx16_8_sin_table[1608]; //lookup table for sin, cos, tan
  33.  
  34.  
  35.  
  36.  
  37.  
  38. #define _FX_F32(_n) ( (int)(((_n)*256.0f)+0.5f) )
  39. #define _FX_F64(_n) ( (int)(((_n)*256.0)+0.5) )
  40.  
  41. struct fx16_8 { //32-bit fixed point; 16-bits of integer, 8-bits of fraction
  42.   Sint32 v = 0; //(highest 8-bits used for headroom between operations)
  43.  
  44.   int    i32() const { return v>>8;           }
  45.   float  f32() const { return (float)v/256;   }
  46.   double f64() const { return (double)v/256;  }
  47.  
  48.  
  49.   fx16_8(){}
  50.   fx16_8(const int&    n){ v = n<<8;       }
  51.   fx16_8(const float&  n){ v = _FX_F32(n); }
  52.   fx16_8(const double& n){ v = _FX_F64(n); }
  53.   fx16_8(const fx16_8& n){ v = n.v;        }
  54.  
  55.   fx16_8& operator++(){ v += 256; return *this; }
  56.   fx16_8& operator--(){ v -= 256; return *this; }
  57.  
  58.   fx16_8& operator=(const int&    n){ v = n<<8;       return *this; }
  59.   fx16_8& operator=(const float&  n){ v = _FX_F32(n); return *this; }
  60.   fx16_8& operator=(const double& n){ v = _FX_F64(n); return *this; }
  61.   fx16_8& operator=(const fx16_8& n){ v = n.v;        return *this; }
  62.  
  63.  
  64.   fx16_8& operator+=(const int&    n){ v += n<<8;       return *this; }
  65.   fx16_8& operator+=(const float&  n){ v += _FX_F32(n); return *this; }
  66.   fx16_8& operator+=(const double& n){ v += _FX_F64(n); return *this; }
  67.   fx16_8& operator+=(const fx16_8& n){ v += n.v;        return *this; }
  68.  
  69.   fx16_8& operator-=(const int&    n){ v -= n<<8;       return *this; }
  70.   fx16_8& operator-=(const float&  n){ v -= _FX_F32(n); return *this; }
  71.   fx16_8& operator-=(const double& n){ v -= _FX_F64(n); return *this; }
  72.   fx16_8& operator-=(const fx16_8& n){ v -= n.v;        return *this; }
  73.  
  74.   fx16_8& operator*=(const int&    n){ v = (v*(n<<8))>>8;     return *this; }
  75.   fx16_8& operator*=(const float&  n){ v = (v*_FX_F32(n))>>8; return *this; }
  76.   fx16_8& operator*=(const double& n){ v = (v*_FX_F64(n))>>8; return *this; }
  77.   fx16_8& operator*=(const fx16_8& n){ v = (v*n.v)>>8;        return *this; }
  78.  
  79.   fx16_8& operator/=(const int&    n){ v = (v<<8)/(n<<8);     return *this; }
  80.   fx16_8& operator/=(const float&  n){ v = (v<<8)/_FX_F32(n); return *this; }
  81.   fx16_8& operator/=(const double& n){ v = (v<<8)/_FX_F64(n); return *this; }
  82.   fx16_8& operator/=(const fx16_8& n){ v = (v<<8)/n.v;        return *this; }
  83.  
  84.   fx16_8& operator%=(const int&    n){ v = (v<<8)%(n<<8);     return *this; }
  85.   fx16_8& operator%=(const float&  n){ v = (v<<8)%_FX_F32(n); return *this; }
  86.   fx16_8& operator%=(const double& n){ v = (v<<8)%_FX_F64(n); return *this; }
  87.   fx16_8& operator%=(const fx16_8& n){ v = (v<<8)%n.v;        return *this; }
  88.  
  89.   fx16_8& operator<<=(const int& n){ v <<= n; return *this; }
  90.   fx16_8& operator>>=(const int& n){ v >>= n; return *this; }
  91.  
  92.  
  93.   fx16_8 operator+(const int&    n) const { fx16_8 o; o.v = v+(n<<8);     return o; }
  94.   fx16_8 operator+(const float&  n) const { fx16_8 o; o.v = v+_FX_F32(n); return o; }
  95.   fx16_8 operator+(const double& n) const { fx16_8 o; o.v = v+_FX_F64(n); return o; }
  96.   fx16_8 operator+(const fx16_8& n) const { fx16_8 o; o.v = v+n.v;        return o; }
  97.  
  98.   fx16_8 operator-(const int&    n) const { fx16_8 o; o.v = v-(n<<8);     return o; }
  99.   fx16_8 operator-(const float&  n) const { fx16_8 o; o.v = v-_FX_F32(n); return o; }
  100.   fx16_8 operator-(const double& n) const { fx16_8 o; o.v = v-_FX_F64(n); return o; }
  101.   fx16_8 operator-(const fx16_8& n) const { fx16_8 o; o.v = v-n.v;        return o; }
  102.  
  103.   fx16_8 operator*(const int&    n) const { fx16_8 o; o.v = (v*(n<<8))>>8;     return o; }
  104.   fx16_8 operator*(const float&  n) const { fx16_8 o; o.v = (v*_FX_F32(n))>>8; return o; }
  105.   fx16_8 operator*(const double& n) const { fx16_8 o; o.v = (v*_FX_F64(n))>>8; return o; }
  106.   fx16_8 operator*(const fx16_8& n) const { fx16_8 o; o.v = (v*n.v)>>8;        return o; }
  107.  
  108.   fx16_8 operator/(const int&    n) const { fx16_8 o; o.v = (v<<8)/(n<<8);     return o; }
  109.   fx16_8 operator/(const float&  n) const { fx16_8 o; o.v = (v<<8)/_FX_F32(n); return o; }
  110.   fx16_8 operator/(const double& n) const { fx16_8 o; o.v = (v<<8)/_FX_F64(n); return o; }
  111.   fx16_8 operator/(const fx16_8& n) const { fx16_8 o; o.v = (v<<8)/n.v;        return o; }
  112.  
  113.   fx16_8 operator%(const int&    n) const { fx16_8 o; o.v = (v<<8)%(n<<8);     return o; }
  114.   fx16_8 operator%(const float&  n) const { fx16_8 o; o.v = (v<<8)%_FX_F32(n); return o; }
  115.   fx16_8 operator%(const double& n) const { fx16_8 o; o.v = (v<<8)%_FX_F64(n); return o; }
  116.   fx16_8 operator%(const fx16_8& n) const { fx16_8 o; o.v = (v<<8)%n.v;        return o; }
  117.  
  118.   fx16_8 operator<<(const int& n) const { fx16_8 o; o.v = v<<n; return o; }
  119.   fx16_8 operator>>(const int& n) const { fx16_8 o; o.v = v>>n; return o; }
  120.  
  121.   fx16_8 operator-() const { fx16_8 o; o.v = -v; return o; }
  122.  
  123.  
  124.   bool operator==(const int&    n) const { return v == n<<8;       }
  125.   bool operator==(const float&  n) const { return v == _FX_F32(n); }
  126.   bool operator==(const double& n) const { return v == _FX_F64(n); }
  127.   bool operator==(const fx16_8& n) const { return v == n.v;        }
  128.  
  129.   bool operator!=(const int&    n) const { return v != n<<8;       }
  130.   bool operator!=(const float&  n) const { return v != _FX_F32(n); }
  131.   bool operator!=(const double& n) const { return v != _FX_F64(n); }
  132.   bool operator!=(const fx16_8& n) const { return v != n.v;        }
  133.  
  134.   bool operator<(const int&    n) const { return v < n<<8;       }
  135.   bool operator<(const float&  n) const { return v < _FX_F32(n); }
  136.   bool operator<(const double& n) const { return v < _FX_F64(n); }
  137.   bool operator<(const fx16_8& n) const { return v < n.v;        }
  138.  
  139.   bool operator>(const int&    n) const { return v > n<<8;       }
  140.   bool operator>(const float&  n) const { return v > _FX_F32(n); }
  141.   bool operator>(const double& n) const { return v > _FX_F64(n); }
  142.   bool operator>(const fx16_8& n) const { return v > n.v;        }
  143.  
  144.   bool operator<=(const int&    n) const { return v <= n<<8;       }
  145.   bool operator<=(const float&  n) const { return v <= _FX_F32(n); }
  146.   bool operator<=(const double& n) const { return v <= _FX_F64(n); }
  147.   bool operator<=(const fx16_8& n) const { return v <= n.v;        }
  148.  
  149.   bool operator>=(const int&    n) const { return v >= n<<8;       }
  150.   bool operator>=(const float&  n) const { return v >= _FX_F32(n); }
  151.   bool operator>=(const double& n) const { return v >= _FX_F64(n); }
  152.   bool operator>=(const fx16_8& n) const { return v >= n.v;        }
  153.  
  154.  
  155.   fx16_8    abs() const { fx16_8 o; o.v = std::abs(v);        return o; }
  156.   fx16_8  trunc() const { fx16_8 o; o.v = v&0xffffff00;       return o; }
  157.   fx16_8  round() const { fx16_8 o; o.v = (v+128)&0xffffff00; return o; }
  158.   int    iround() const { return (v+128)>>8; }
  159.  
  160.   fx16_8 sin() const {
  161.     fx16_8 o; o.v = _fx16_8_sin_table[std::abs(v)%fx_2pi.v];
  162.     return o;
  163.   }
  164.   fx16_8 cos() const {
  165.     fx16_8 o; o.v = _fx16_8_sin_table[(std::abs(v)+fx_pi2.v)%fx_2pi.v];
  166.     return o;
  167.   }
  168.   fx16_8 tan() const { return sin()/cos(); }
  169.  
  170.  
  171.   //i'll come up with a more pure implementation of the following functions later
  172.  
  173.   fx16_8 asin() const {
  174.     fx16_8 o; o.v = (std::asin((double)v/256)*256 + 0.5);
  175.     return o;
  176.   }
  177.  
  178.   fx16_8 acos() const {
  179.     fx16_8 o; o.v = (std::acos((double)v/256)*256 + 0.5);
  180.     return o;
  181.   }
  182.  
  183.   fx16_8 atan() const {
  184.     fx16_8 o; o.v = (std::atan((double)v/256)*256 + 0.5);
  185.     return o;
  186.   }
  187.  
  188.   fx16_8 sqrt() const {
  189.     if(v < 0) throw std::domain_error("Cannot compute square root of a negative number");
  190.     fx16_8 o; o.v = (std::sqrt((double)v/256)*256 + 0.5);
  191.     return o;
  192.   }
  193. };
  194.  
  195.  
  196.  
  197.  
  198. struct fx_vec2;
  199. struct fx_vec3;
  200.  
  201.  
  202.  
  203. struct fx_vec2 {
  204.   fx16_8 x;
  205.   fx16_8 y;
  206.  
  207.  
  208.   fx_vec2 operator+(const fx_vec2& n) const { fx_vec2 o; o.x = x+n.x, o.y = y+n.y; return o; }
  209.  
  210.   fx_vec2 operator-(const fx_vec2& n) const { fx_vec2 o; o.x = x-n.x, o.y = y-n.y; return o; }
  211.  
  212.  
  213.   bool operator==(const fx_vec2& n){ return (x==n.x) && (y==n.y); }
  214.  
  215.  
  216.   fx_vec2 trunc() const { fx_vec2 o; o.x = x.trunc(),  o.y = y.trunc(); return o; }
  217.   fx_vec2 round() const { fx_vec2 o; o.x = x.round(),  o.y = y.round(); return o; }
  218. };
  219.  
  220.  
  221.  
  222. struct fx_vec3 {
  223.   fx16_8 x;
  224.   fx16_8 y;
  225.   fx16_8 z;
  226.  
  227.   fx_vec3() : x(0), y(0), z(0) {}
  228.   fx_vec3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
  229.  
  230.   void rotateRad(fx16_8 roll, fx16_8 pitch, fx16_8 yaw);
  231.   void rotateDeg(fx16_8 roll, fx16_8 pitch, fx16_8 yaw){
  232.     rotateRad(roll/fx_invpi_180, pitch/fx_invpi_180, yaw/fx_invpi_180);
  233.   }
  234. };
  235.  
  236.  
  237.  
  238. static inline fx16_8 fx_vec2_cross(const fx_vec2& a,
  239.                                    const fx_vec2& b,
  240.                                    const fx_vec2& origin = {0,0})
  241. {
  242.   const fx_vec2 oa = a-origin;
  243.   const fx_vec2 ob = b-origin;
  244.   return (oa.x*ob.y)-(oa.y*ob.x);
  245. }
  246.  
  247. //static inline fx_vec3 fx_vec2_3(const fx_vec2& v2){ return { .x = v2.x, .y = v2.y, .z = 0 }; }
  248. static inline fx_vec2 fx_vec3_2(const fx_vec3& v3){ fx_vec2 o; o.x=v3.x, o.y=v3.y; return o; }
  249.  
  250.  
  251.  
  252.  
  253. #endif /* _UTILS_FX16_8_HPP */
  254.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement