Main Page   Class Hierarchy   Compound List   File List   Compound Members  

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 "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         // 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

Generated on Mon Sep 15 12:01:10 2003 for Kyra by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001