- Main Page
- Classes
- Files
- Directories
- Related Pages

# glfixed.h

    00001 /*
    00002 Copyright (c) 2000-2003 Lee Thomason (www.grinninglizard.com)
    00003
    00004 Grinning Lizard Utilities. Note that software that uses the
    00005 utility package (including Lilith3D and Kyra) have more restrictive
    00006 licences which applies to code outside of the utility package.
    00007
    00008
    00009 This software is provided 'as-is', without any express or implied
    00010 warranty. In no event will the authors be held liable for any
    00011 damages arising from the use of this software.
    00012
    00013 Permission is granted to anyone to use this software for any
    00014 purpose, including commercial applications, and to alter it and
    00015 redistribute it freely, subject to the following restrictions:
    00016
    00017 1. The origin of this software must not be misrepresented; you must
    00018 not claim that you wrote the original software. If you use this
    00019 software in a product, an acknowledgment in the product documentation
    00020 would be appreciated but is not required.
    00021
    00022 2. Altered source versions must be plainly marked as such, and
    00023 must not be misrepresented as being the original software.
    00024
    00025 3. This notice may not be removed or altered from any source
    00026 distribution.
    00027 */
    00028
    00029 #ifndef GlFixed_MATH_INCLUDED
    00030 #define GlFixed_MATH_INCLUDED
    00031
    00032 #include <limits.h>
    00033 #include "../../grinliz/gltypes.h"
    00034 #include "../../grinliz/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         // This could be done with overloaded operators, but I dislike overloaded
    00094         // operators for casting because I think they are confusing when they
    00095         // are used. -lee
    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         // Negation.
    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