00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef GlFixed_MATH_INCLUDED
00030 #define GlFixed_MATH_INCLUDED
00031
00032 #include <limits.h>
00033 #include "gltypes.h"
00034 #include "gldebug.h"
00035
00036 #define GlFixed_0 ( 0 ) // Help the compliler - use 1<<16 instead of a const.
00037 #define GlFixed_1 ( 1<<16 ) // Help the compliler - use 1<<16 instead of a const.
00038
00039 inline S32 GlIntToFixed( int x ) { return x << 16; }
00040 inline S32 GlDoubleToFixed( double x ) { return S32( x * 65536.0 + 0.5); }
00041 inline double GlFixedToDouble( S32 f ) { return double( f ) / 65536.0; }
00042 inline float GlFixedToFloat( S32 f ) { return float( f ) / 65536.0f; }
00043 inline int GlFixedToInt( S32 f ) { return f >> 16; }
00044 inline int GlFixedToIntRound( S32 f ) { return ( f + 0x0800 ) >> 16; }
00045 inline int GlFixedToIntRoundUp( S32 f ) { return ( f + 0xffff ) >> 16; }
00046
00047
00048 inline S32 GlFixedMult( S32 _x, S32 _y )
00049 {
00050 #ifdef VALIDATE_DEBUG
00051 S64 x = _x;
00052 S64 y = _y;
00053 S64 ret = ( ( x * y ) >> 16 );
00054 GLASSERT( ret <= INT_MAX && ret >= INT_MIN );
00055 return S32( ret );
00056 #else
00057 return (S32) ( ( S64( _x ) * S64( _y ) ) >> 16 );
00058 #endif
00059 }
00060
00061
00062 inline S32 GlFixedDiv( S32 _x, S32 _y )
00063 {
00064 #ifdef VALIDATE_DEBUG
00065 S64 x = ( S64( _x ) << 16 );
00066 S64 y = _y;
00067
00068 S64 ret = x / y;
00069 GLASSERT( ret <= INT_MAX && ret >= INT_MIN );
00070 return S32( ret );
00071 #else
00072 return S32( ( S64( _x ) << 16 ) / S64( _y ) );
00073 #endif
00074 }
00075
00076
00079 class GlFixed
00080 {
00081 public:
00082 GlFixed() {}
00083
00084 GlFixed( const GlFixed &x ) { v = x.v; }
00085 GlFixed( int x ) { v = GlIntToFixed( x ); }
00086 GlFixed( const double x ) { v = GlDoubleToFixed( x ); }
00087
00088 #ifdef DEBUG
00089 void DebugDump() { GLOUTPUT( "fixed=%.2f\n", GlFixedToDouble( v ) ); }
00090 #endif
00091
00092
00093
00094
00095
00096
00097 int ToInt() const { return GlFixedToInt( v ); }
00098 int ToIntRoundUp() const { return GlFixedToIntRoundUp( v ); }
00099 int ToIntRound() const { return GlFixedToIntRound( v ); }
00100 double ToDouble() const { return GlFixedToDouble( v ); }
00101 float ToFloat() const { return GlFixedToFloat( v ); }
00102
00103 GlFixed Abs() { GlFixed t; ( v < 0 ) ? t.v = -v : t.v = v; return t; }
00104
00105 GlFixed& operator = (const GlFixed &x) { v = x.v; return *this; }
00106 GlFixed& operator = (const int x) { v = GlIntToFixed( x ); return *this; }
00107 GlFixed& operator = (const double x) { v = GlDoubleToFixed( x ); return *this; }
00108
00109 GlFixed& operator += (const GlFixed x) { v += x.v; return *this; }
00110 GlFixed& operator += (const int x) { v += GlIntToFixed(x); return *this; }
00111 GlFixed& operator += (const double x) { v += GlDoubleToFixed(x); return *this; }
00112
00113 GlFixed& operator -= (const GlFixed x) { v -= x.v; return *this; }
00114 GlFixed& operator -= (const int x) { v -= GlIntToFixed(x); return *this; }
00115 GlFixed& operator -= (const double x) { v -= GlDoubleToFixed(x); return *this; }
00116
00117 GlFixed& operator *= (const GlFixed x) { v = GlFixedMult(v, x.v); return *this; }
00118 GlFixed& operator *= (const int x) { v *= x; return *this; }
00119 GlFixed& operator *= (const double x) { v = GlDoubleToFixed(GlFixedToDouble(v) * x); return *this; }
00120
00121 GlFixed& operator /= (const GlFixed x) { v = GlFixedDiv(v, x.v); return *this; }
00122 GlFixed& operator /= (const int x) { v /= x; return *this; }
00123 GlFixed& operator /= (const double x) { v = GlFixedDiv( v, GlDoubleToFixed(x) ); return *this; }
00124
00125 GlFixed& operator <<= (const int x) { v <<= x; return *this; }
00126 GlFixed& operator >>= (const int x) { v >>= x; return *this; }
00127
00128 GlFixed& operator ++ () { v += GlFixed_1; return *this; }
00129 GlFixed& operator -- () { v -= GlFixed_1; return *this; }
00130
00131 GlFixed operator ++ (int) { GlFixed t; t.v = v; v += GlFixed_1; return t; }
00132 GlFixed operator -- (int) { GlFixed t; t.v = v; v -= GlFixed_1; return t; }
00133
00134
00135 GlFixed operator - () const { GlFixed t; t.v = -v; return t; }
00136
00137 inline friend GlFixed operator + (const GlFixed x, const GlFixed y) { GlFixed t; t.v = x.v + y.v; return t; }
00138 inline friend GlFixed operator + (const int x, const GlFixed y) { GlFixed t; t.v = GlIntToFixed(x) + y.v; return t; }
00139 inline friend GlFixed operator + (const GlFixed x, const int y ) { GlFixed t; t.v = x.v + GlIntToFixed(y); return t; }
00140
00141 inline friend GlFixed operator - (const GlFixed x, const GlFixed y) { GlFixed t; t.v = x.v - y.v; return t; }
00142 inline friend GlFixed operator - (const int x, const GlFixed y) { GlFixed t; t.v = GlIntToFixed(x) - y.v; return t; }
00143 inline friend GlFixed operator - (const GlFixed x, const int y) { GlFixed t; t.v = x.v - GlIntToFixed(y); return t; }
00144 inline friend GlFixed operator - (const double x, const GlFixed y) { GlFixed t; t.v = GlDoubleToFixed(x) - y.v; return t; }
00145 inline friend GlFixed operator - (const GlFixed x, const double y) { GlFixed t; t.v = x.v - GlDoubleToFixed(y); return t; }
00146
00147 inline friend GlFixed operator * (const GlFixed x, const GlFixed y) { GlFixed t; t.v = GlFixedMult(x.v, y.v); return t; }
00148 inline friend GlFixed operator * (const int x, const GlFixed y) { GlFixed t; t.v = GlFixedMult(GlIntToFixed(x), y.v); return t; }
00149 inline friend GlFixed operator * (const GlFixed x, const int y) { GlFixed t; t.v = GlFixedMult(x.v, GlIntToFixed(y)); return t; }
00150 inline friend GlFixed operator * (const double x, const GlFixed y) { GlFixed t; t.v = GlFixedMult(GlDoubleToFixed(x), y.v); return t; }
00151 inline friend GlFixed operator * (const GlFixed x, const double y) { GlFixed t; t.v = GlFixedMult(x.v, GlDoubleToFixed(y)); return t; }
00152
00153 inline friend GlFixed operator / (const GlFixed x, const GlFixed y) { GlFixed t; t.v = GlFixedDiv(x.v, y.v); return t; }
00154 inline friend GlFixed operator / (const int x, const GlFixed y) { GlFixed t; t.v = GlFixedDiv(GlIntToFixed(x), y.v); return t; }
00155 inline friend GlFixed operator / (const GlFixed x, const int y) { GlFixed t; t.v = GlFixedDiv(x.v, GlIntToFixed(y)); return t; }
00156
00157 inline friend GlFixed operator << (const GlFixed x, const int y) { GlFixed t; t.v = x.v << y; return t; }
00158 inline friend GlFixed operator >> (const GlFixed x, const int y) { GlFixed t; t.v = x.v >> y; return t; }
00159
00160 inline friend bool operator == (const GlFixed x, const GlFixed y) { return (x.v == y.v); }
00161 inline friend bool operator == (const int x, const GlFixed y) { return (GlIntToFixed(x) == y.v); }
00162 inline friend bool operator == (const GlFixed x, const int y) { return (x.v == GlIntToFixed(y)); }
00163
00164 inline friend bool operator != (const GlFixed x, const GlFixed y) { return (x.v != y.v); }
00165 inline friend bool operator != (const int x, const GlFixed y) { return (GlIntToFixed(x) != y.v); }
00166 inline friend bool operator != (const GlFixed x, const int y) { return (x.v !=GlIntToFixed(y)); }
00167
00168 inline friend bool operator < (const GlFixed x, const GlFixed y) { return (x.v < y.v); }
00169 inline friend bool operator < (const int x, const GlFixed y) { return (GlIntToFixed(x) < y.v); }
00170 inline friend bool operator < (const GlFixed x, const int y) { return (x.v < GlIntToFixed(y) ); }
00171
00172 inline friend bool operator > (const GlFixed x, const GlFixed y) { return (x.v > y.v); }
00173 inline friend bool operator > (const int x, const GlFixed y) { return (GlIntToFixed(x) > y.v); }
00174 inline friend bool operator > (const GlFixed x, const int y) { return (x.v > GlIntToFixed(y)); }
00175
00176 inline friend bool operator <= (const GlFixed x, const GlFixed y) { return (x.v <= y.v); }
00177 inline friend bool operator <= (const int x, const GlFixed y) { return (GlIntToFixed(x) <= y.v); }
00178 inline friend bool operator <= (const GlFixed x, const int y) { return (x.v <= GlIntToFixed(y)); }
00179
00180 inline friend bool operator >= (const GlFixed x, const GlFixed y) { return (x.v >= y.v); }
00181 inline friend bool operator >= (const int x, const GlFixed y) { return (GlIntToFixed(x) >= y.v); }
00182 inline friend bool operator >= (const GlFixed x, const int y) { return (x.v >= GlIntToFixed(y)); }
00183
00184 S32 v;
00185 };
00186
00187
00188 #endif