// File: ll3d_fpmath.h // // G A M E.O.N.E - LOW LEVEL LIB V1.0 // Copyright (C) 2001 LEVEL ONE ENTERTAINMENT, // Licensed under the terms of LGPL. //:--------------------------------------------------------------------------- //:Author: Alex Piko // //:Description // // Fixed Point class // //:----------------------------------------------------------------------------- #ifndef _LL3D_FPMATH_H #define _LL3D_FPMATH_H //#include #include "sys_types.h" #pragma warning(disable : 4244) #define M_SHIFT (16) // Bitshift #define E_MUL (65536.0f) // Zur Konvertierung von Float/Double #define I_STEP (0x10000) // Konstante für ++/-- Operator /* * 16x16 Bit Fixed Point */ /* #pragma pack(1) typedef struct { TxU32 fp; // fp } _fp16x16; #pragma pack() */ //:End Custom //:> +-------------------------------+ //:>---------------------| TxF16 Class Declaration |---------------------- //:> +-------------------------------+ //:Class class TxF16 // :private _fp16x16 { TxI32 fp; // fp public: //::1 // +---------------+ // | Constructor | // +---------------+ inline TxF16() {} inline TxF16(const TxF16& fx16) { fp = fx16.fp; } inline TxF16(const char& i) { fp = TxI32(i) << M_SHIFT; } inline TxF16(const unsigned char& i) { fp = TxI32(i) << M_SHIFT; } inline TxF16(const short& i) { fp = TxI32(i) << M_SHIFT; } inline TxF16(const unsigned short& i) { fp = TxI32(i) << M_SHIFT; } inline TxF16(const int& i) { fp = TxI32(i) << M_SHIFT; } inline TxF16(const unsigned int& i) { fp = TxI32(i) << M_SHIFT; } inline TxF16(const long& i) { fp = TxI32(i) << M_SHIFT; } inline TxF16(const unsigned long& i) { fp = TxI32(i) << M_SHIFT; } inline TxF16(const float& i) { fp = i * E_MUL; } inline TxF16(const double& i) { fp = float(i) * E_MUL; } //::8 // +-----------------+ // | operator ==() | // +-----------------+ inline bool operator ==(const TxF16& fx16) { return fp == fx16.fp; } inline bool operator ==(const char& i) { return *this == TxF16(i); } inline bool operator ==(const unsigned char& i) { return *this == TxF16(i); } inline bool operator ==(const short& i) { return *this == TxF16(i); } inline bool operator ==(const unsigned short& i) { return *this == TxF16(i); } inline bool operator ==(const int& i) { return *this == TxF16(i); } inline bool operator ==(const unsigned int& i) { return *this == TxF16(i); } inline bool operator ==(const long& i) { return *this == TxF16(i); } inline bool operator ==(const unsigned long& i) { return *this == TxF16(i); } inline bool operator ==(const float& i) { return *this == TxF16(i); } inline bool operator ==(const double& i) { return *this == TxF16(i); } //::8 // +-----------------+ // | operator !=() | // +-----------------+ inline bool operator !=(const TxF16& fx16) { return fp != fx16.fp; } inline bool operator !=(const char& i) { return *this != TxF16(i); } inline bool operator !=(const unsigned char& i) { return *this != TxF16(i); } inline bool operator !=(const short& i) { return *this != TxF16(i); } inline bool operator !=(const unsigned short& i) { return *this != TxF16(i); } inline bool operator !=(const int& i) { return *this != TxF16(i); } inline bool operator !=(const unsigned int& i) { return *this != TxF16(i); } inline bool operator !=(const long& i) { return *this != TxF16(i); } inline bool operator !=(const unsigned long& i) { return *this != TxF16(i); } inline bool operator !=(const float& i) { return *this != TxF16(i); } inline bool operator !=(const double& i) { return *this != TxF16(i); } //::8 // +----------------+ // | operator <() | // +----------------+ inline bool operator <(const TxF16& fx16) { return fp < fx16.fp; } inline bool operator <(const char& i) { return *this < TxF16(i); } inline bool operator <(const unsigned char& i) { return *this < TxF16(i); } inline bool operator <(const short& i) { return *this < TxF16(i); } inline bool operator <(const unsigned short& i) { return *this < TxF16(i); } inline bool operator <(const int& i) { return *this < TxF16(i); } inline bool operator <(const unsigned int& i) { return *this < TxF16(i); } inline bool operator <(const long& i) { return *this < TxF16(i); } inline bool operator <(const unsigned long& i) { return *this < TxF16(i); } inline bool operator <(const float& i) { return *this < TxF16(i); } inline bool operator <(const double& i) { return *this < TxF16(i); } //::8 // +----------------+ // | operator >() | // +----------------+ inline bool operator >(const TxF16& fx16) { return fp > fx16.fp; } inline bool operator >(const char& i) { return *this > TxF16(i); } inline bool operator >(const unsigned char& i) { return *this > TxF16(i); } inline bool operator >(const short& i) { return *this > TxF16(i); } inline bool operator >(const unsigned short& i) { return *this > TxF16(i); } inline bool operator >(const int& i) { return *this > TxF16(i); } inline bool operator >(const unsigned int& i) { return *this > TxF16(i); } inline bool operator >(const long& i) { return *this > TxF16(i); } inline bool operator >(const unsigned long& i) { return *this > TxF16(i); } inline bool operator >(const float& i) { return *this > TxF16(i); } inline bool operator >(const double& i) { return *this > TxF16(i); } //::8 // +-----------------+ // | operator <=() | // +-----------------+ inline bool operator <=(const TxF16& fx16) { return fp <= fx16.fp; } inline bool operator <=(const char& i) { return *this <= TxF16(i); } inline bool operator <=(const unsigned char& i) { return *this <= TxF16(i); } inline bool operator <=(const short& i) { return *this <= TxF16(i); } inline bool operator <=(const unsigned short& i) { return *this <= TxF16(i); } inline bool operator <=(const int& i) { return *this <= TxF16(i); } inline bool operator <=(const unsigned int& i) { return *this <= TxF16(i); } inline bool operator <=(const long& i) { return *this <= TxF16(i); } inline bool operator <=(const unsigned long& i) { return *this <= TxF16(i); } inline bool operator <=(const float& i) { return *this <= TxF16(i); } inline bool operator <=(const double& i) { return *this <= TxF16(i); } //::8 // +-----------------+ // | operator >=() | // +-----------------+ inline bool operator >=(const TxF16& fx16) { return fp >= fx16.fp; } inline bool operator >=(const char& i) { return *this >= TxF16(i); } inline bool operator >=(const unsigned char& i) { return *this >= TxF16(i); } inline bool operator >=(const short& i) { return *this >= TxF16(i); } inline bool operator >=(const unsigned short& i) { return *this >= TxF16(i); } inline bool operator >=(const int& i) { return *this >= TxF16(i); } inline bool operator >=(const unsigned int& i) { return *this >= TxF16(i); } inline bool operator >=(const long& i) { return *this >= TxF16(i); } inline bool operator >=(const unsigned long& i) { return *this >= TxF16(i); } inline bool operator >=(const float& i) { return *this >= TxF16(i); } inline bool operator >=(const double& i) { return *this >= TxF16(i); } // +----------------+ // | operator =() | // +----------------+ inline const TxF16 & operator =(const TxF16& fx16); inline const TxF16 & operator =(const char& i) { fp = TxI32(i) << M_SHIFT; return *this; } inline const TxF16 & operator =(const unsigned char& i) { fp = TxI32(i) << M_SHIFT; return *this; } inline const TxF16 & operator =(const short& i) { fp = TxI32(i) << M_SHIFT; return *this; } inline const TxF16 & operator =(const unsigned short& i) { fp = TxI32(i) << M_SHIFT; return *this; } inline const TxF16 & operator =(const int& i) { fp = TxI32(i) << M_SHIFT; return *this; } inline const TxF16 & operator =(const unsigned int& i) { fp = TxI32(i) << M_SHIFT; return *this; } inline const TxF16 & operator =(const long& i) { fp = TxI32(i) << M_SHIFT; return *this; } inline const TxF16 & operator =(const unsigned long& i) { fp = TxI32(i) << M_SHIFT; return *this; } inline const TxF16 & operator =(const float& i) { fp = i * E_MUL; return *this; } inline const TxF16 & operator =(const double& i) { fp = float(i) * E_MUL; return *this; } // +-----------------+ // | operator *=() | // +-----------------+ inline const TxF16 & operator *=(const TxF16& fx16); inline const TxF16 & operator *=(const char& i) { return *this *= TxF16(i); } inline const TxF16 & operator *=(const unsigned char& i) { return *this *= TxF16(i); } inline const TxF16 & operator *=(const short& i) { return *this *= TxF16(i); } inline const TxF16 & operator *=(const unsigned short& i) { return *this *= TxF16(i); } inline const TxF16 & operator *=(const int& i) { return *this *= TxF16(i); } inline const TxF16 & operator *=(const unsigned int& i) { return *this *= TxF16(i); } inline const TxF16 & operator *=(const long& i) { return *this *= TxF16(i); } inline const TxF16 & operator *=(const unsigned long& i) { return *this *= TxF16(i); } inline const TxF16 & operator *=(const float& i) { return *this *= TxF16(i); } inline const TxF16 & operator *=(const double& i) { return *this *= TxF16(i); } // +-----------------+ // | operator /=() | // +-----------------+ inline const TxF16 & operator /=(const TxF16& fx16); inline const TxF16 & operator /=(const char& i) { return *this /= TxF16(i); } inline const TxF16 & operator /=(const unsigned char& i) { return *this /= TxF16(i); } inline const TxF16 & operator /=(const short& i) { return *this /= TxF16(i); } inline const TxF16 & operator /=(const unsigned short& i) { return *this /= TxF16(i); } inline const TxF16 & operator /=(const int& i) { return *this /= TxF16(i); } inline const TxF16 & operator /=(const unsigned int& i) { return *this /= TxF16(i); } inline const TxF16 & operator /=(const long& i) { return *this /= TxF16(i); } inline const TxF16 & operator /=(const unsigned long& i) { return *this /= TxF16(i); } inline const TxF16 & operator /=(const float& i) { return *this /= TxF16(i); } inline const TxF16 & operator /=(const double& i) { return *this /= TxF16(i); } //::3 // +----------------+ // | operator *() | // +----------------+ inline TxF16 operator *(const TxF16& fx16) const; inline TxF16 operator *(const char& i) const { return *this * TxF16(i); } inline TxF16 operator *(const unsigned char& i) const { return *this * TxF16(i); } inline TxF16 operator *(const short& i) const { return *this * TxF16(i); } inline TxF16 operator *(const unsigned short& i) const { return *this * TxF16(i); } inline TxF16 operator *(const int& i) const { return *this * TxF16(i); } inline TxF16 operator *(const unsigned int& i) const { return *this * TxF16(i); } inline TxF16 operator *(const long& i) const { return *this * TxF16(i); } inline TxF16 operator *(const unsigned long& i) const { return *this * TxF16(i); } inline TxF16 operator *(const float& i) const { return *this * TxF16(i); } inline TxF16 operator *(const double& i) const { return *this * TxF16(i); } //::3 // +----------------+ // | operator /() | // +----------------+ inline TxF16 operator /(const TxF16& fx16) const; inline TxF16 operator /(const char& i) const { return *this / TxF16(i); } inline TxF16 operator /(const unsigned char& i) const { return *this / TxF16(i); } inline TxF16 operator /(const short& i) const { return *this / TxF16(i); } inline TxF16 operator /(const unsigned short& i) const { return *this / TxF16(i); } inline TxF16 operator /(const int& i) const { return *this / TxF16(i); } inline TxF16 operator /(const unsigned int& i) const { return *this / TxF16(i); } inline TxF16 operator /(const long& i) const { return *this / TxF16(i); } inline TxF16 operator /(const unsigned long& i) const { return *this / TxF16(i); } inline TxF16 operator /(const float& i) const { return *this / TxF16(i); } inline TxF16 operator /(const double& i) const { return *this / TxF16(i); } //::3 // +----------------+ // | operator -() | // +----------------+ inline TxF16 operator -(const TxF16& fx16) const; inline TxF16 operator -(const char& i) const { return *this - TxF16(i); } inline TxF16 operator -(const unsigned char& i) const { return *this - TxF16(i); } inline TxF16 operator -(const short& i) const { return *this - TxF16(i); } inline TxF16 operator -(const unsigned short& i)const { return *this - TxF16(i); } inline TxF16 operator -(const int& i) const { return *this - TxF16(i); } inline TxF16 operator -(const unsigned int& i) const { return *this - TxF16(i); } inline TxF16 operator -(const long& i) const { return *this - TxF16(i); } inline TxF16 operator -(const unsigned long& i) const { return *this - TxF16(i); } inline TxF16 operator -(const float& i) const { return *this - TxF16(i); } inline TxF16 operator -(const double& i) const { return *this - TxF16(i); } //::3 // +----------------+ // | operator +() | // +----------------+ inline TxF16 operator +(const TxF16& fx16) const; inline TxF16 operator +(const char& i) const { return *this + TxF16(i); } inline TxF16 operator +(const unsigned char& i) const { return *this + TxF16(i); } inline TxF16 operator +(const short& i) const { return *this + TxF16(i); } inline TxF16 operator +(const unsigned short& i)const { return *this + TxF16(i); } inline TxF16 operator +(const int& i) const { return *this + TxF16(i); } inline TxF16 operator +(const unsigned int& i) const { return *this + TxF16(i); } inline TxF16 operator +(const long& i) const { return *this + TxF16(i); } inline TxF16 operator +(const unsigned long& i) const { return *this + TxF16(i); } inline TxF16 operator +(const float& i) const { return *this + TxF16(i); } inline TxF16 operator +(const double& i) const { return *this + TxF16(i); } //::3 // +-----------------+ // | operator -=() | // +-----------------+ inline const TxF16 & operator -=(const TxF16& fx16); inline const TxF16 & operator -=(const char& i) { return *this -= TxF16(i); } inline const TxF16 & operator -=(const unsigned char& i) { return *this -= TxF16(i); } inline const TxF16 & operator -=(const short& i) { return *this -= TxF16(i); } inline const TxF16 & operator -=(const unsigned short& i) { return *this -= TxF16(i); } inline const TxF16 & operator -=(const int& i) { return *this -= TxF16(i); } inline const TxF16 & operator -=(const unsigned int& i) { return *this -= TxF16(i); } inline const TxF16 & operator -=(const long& i) { return *this -= TxF16(i); } inline const TxF16 & operator -=(const unsigned long& i) { return *this -= TxF16(i); } inline const TxF16 & operator -=(const float& i) { return *this -= TxF16(i); } inline const TxF16 & operator -=(const double& i) { return *this -= TxF16(i); } //::3 // +-----------------+ // | operator +=() | // +-----------------+ inline const TxF16 & operator +=(const TxF16& fx16); inline const TxF16 & operator +=(const char& i) { return *this += TxF16(i); } inline const TxF16 & operator +=(const unsigned char& i) { return *this += TxF16(i); } inline const TxF16 & operator +=(const short& i) { return *this += TxF16(i); } inline const TxF16 & operator +=(const unsigned short& i) { return *this += TxF16(i); } inline const TxF16 & operator +=(const int& i) { return *this += TxF16(i); } inline const TxF16 & operator +=(const unsigned int& i) { return *this += TxF16(i); } inline const TxF16 & operator +=(const long& i) { return *this += TxF16(i); } inline const TxF16 & operator +=(const unsigned long& i) { return *this += TxF16(i); } inline const TxF16 & operator +=(const float& i) { return *this += TxF16(i); } inline const TxF16 & operator +=(const double& i) { return *this += TxF16(i); } //::4 // +-----------------+ // | operator &=() | // +-----------------+ inline const TxF16 & operator &=(const TxF16 &fx16); // +----------------+ // | operator &() | // +----------------+ inline TxF16 operator &(const TxF16 &fx16) const; //::13 // +-----------------+ // | operator ^=() | // +-----------------+ inline const TxF16 & operator ^=(const TxF16 &fx16); //::13 // +----------------+ // | operator ^() | // +----------------+ inline TxF16 operator ^(const TxF16 &fx16) const; //::5 // +-----------------+ // | operator |=() | // +-----------------+ inline const TxF16 & operator |=(const TxF16 &fx16); //::15 // +----------------+ // | operator ~() | // +----------------+ inline TxF16 operator ~() const; //::15 // +-----------------+ // | operator --() | // +-----------------+ inline const TxF16 & operator --(); //::15 // +-----------------+ // | operator ++() | // +-----------------+ inline const TxF16 & operator ++(); // +----------------+ // | operator %() | // +----------------+ inline TxF16 operator %(const TxF16 &fx16) const; //::16 // +---------------+ // | operator () | // +---------------+ inline operator TxU32() { return TxU32(fp) >> M_SHIFT; } inline operator TxI32() { return fp >> M_SHIFT; } inline operator float() { return float(fp) / E_MUL; } inline operator TxF16() { return *this; } inline operator char() { return char( fp >> M_SHIFT); } inline operator unsigned char() { return unsigned char( TxU32(fp) >> M_SHIFT); } inline operator short() { return short( fp >> M_SHIFT); } inline operator unsigned short() { return unsigned short( TxU32(fp) >> M_SHIFT); } inline operator int() { return int( fp >> M_SHIFT); } inline operator unsigned int() { return unsigned int( TxU32(fp) >> M_SHIFT); } inline operator long() const { return long( fp >> M_SHIFT); } //inline operator unsigned long() { return unsigned long( TxU32(fp) >> M_SHIFT); } inline operator float() const { return float( float(fp) * E_MUL); } inline operator double() const { return double( float(fp) * E_MUL); } //::16 // +-----------------+ // | Funktionen () | // +-----------------+ inline int IntFloor(); inline int IntCeil(); inline int IntNearest(); inline TxF16 Floor(); inline TxF16 Abs(); inline TxF16 Sign(); inline TxF16 Round(); inline TxF16 Ceil(); }; //:> +------------------------------------------+ //:>----------------| Inline Member Function Definitions |---------------- //:> +------------------------------------------+ // +----------------+ // | operator =() | // +----------------+ inline const TxF16 & TxF16::operator =(const TxF16& fx16) { fp = fx16.fp; return *this; } // +----------------+ // | operator *() | // +----------------+ inline TxF16 TxF16::operator *(const TxF16& i) const { TxF16 t; __int64 l = (__int64)fp * i.fp; if( l < 0 ) { t.fp = l >> M_SHIFT; } else { t.fp = l >> M_SHIFT; t.fp &= 0x7FFFFFFF; } return t; } // +----------------+ // | operator /() | // +----------------+ inline TxF16 TxF16::operator /(const TxF16& i) const { TxF16 t; __int64 i64 = fp; i64 <<= M_SHIFT; i64 /= i.fp; t.fp = TxI32(i64); return t; } //::3 // +----------------+ // | operator -() | // +----------------+ inline TxF16 TxF16::operator -(const TxF16& fx16) const { TxF16 t; t.fp = fp - fx16.fp; return t; } //::3 // +----------------+ // | operator +() | // +----------------+ inline TxF16 TxF16::operator +(const TxF16& fx16) const { TxF16 t; t.fp = fp + fx16.fp; return t; } // +-----------------+ // | operator *=() | // +-----------------+ inline const TxF16 & TxF16::operator *=(const TxF16& fx16) { //fp = ( (__int64)fp * (__int64)fx16.fp) >> M_SHIFT; __int64 l = (__int64)fp * fx16.fp; if( l < 0 ) { fp = l >> M_SHIFT; } else { fp = l >> M_SHIFT; fp &= 0x7FFFFFFF; } return *this; } // +-----------------+ // | operator /=() | // +-----------------+ inline const TxF16 & TxF16::operator /=(const TxF16& fx16) { __int64 i64 = fp; i64 <<= M_SHIFT; i64 /= fx16.fp; fp = TxI32(i64); return *this; } //::3 // +-----------------+ // | operator -=() | // +-----------------+ inline const TxF16 & TxF16::operator -=(const TxF16& fx16) { fp -= fx16.fp; return *this; } //::3 // +-----------------+ // | operator +=() | // +-----------------+ inline const TxF16 & TxF16::operator +=(const TxF16& fx16) { fp += fx16.fp; return *this; } //::3 // +----------------+ // | operator &() | // +----------------+ inline TxF16 TxF16::operator &(const TxF16& i) const { TxF16 t; t.fp = fp & i.fp; return t; } //::4 // +-----------------+ // | operator &=() | // +-----------------+ inline const TxF16 & TxF16::operator &=(const TxF16 &txf16) { fp &= txf16.fp; return *this; } //::13 // +-----------------+ // | operator ^=() | // +-----------------+ inline const TxF16 & TxF16::operator ^=(const TxF16 &txf16) { fp ^= txf16.fp; return *this; } //::13 // +----------------+ // | operator ^() | // +----------------+ inline TxF16 TxF16::operator ^(const TxF16 &txf16) const { TxF16 t; t.fp = fp ^ txf16.fp; return *this; } // +----------------+ // | operator ~() | // +----------------+ inline TxF16 TxF16::operator ~() const { TxF16 t; t.fp = ~ fp; return t; } //::5 // +-----------------+ // | operator |=() | // +-----------------+ inline const TxF16 & TxF16::operator |=(const TxF16 &fx16) { fp |= fx16.fp; return *this; } //::5 // +-----------------+ // | operator --() | // +-----------------+ inline const TxF16 & TxF16::operator --() { fp += I_STEP; return *this; } //::5 // +-----------------+ // | operator ++() | // +-----------------+ inline const TxF16 & TxF16::operator ++() { fp -= I_STEP; return *this; } // +----------------+ // | operator %() | // +----------------+ inline TxF16 TxF16::operator %(const TxF16 &fx16) const { TxF16 t; t.fp = fp % fx16.fp; return t; } //::16 // +---------------+ // | IntFloor () | // +---------------+ inline int TxF16::IntFloor() { int floor = fp >> M_SHIFT; if( fp < 0 && fp&(I_STEP-1) ) { floor ++; } return floor; } //::16 // +--------------+ // | IntCeil () | // +--------------+ inline int TxF16::IntCeil() { int ceil = fp >> M_SHIFT; if( fp < 0 && fp&(I_STEP-1) ) { ceil --; } return ceil; } //::16 // +----------------+ // | IntNearest () | // +----------------+ inline int TxF16::IntNearest() { int floor = (fp + (I_STEP>>1)) >> M_SHIFT; if( fp < 0 && fp&(I_STEP-1) ) { floor --; } return floor; } //::16 // +---------+ // | Abs () | // +---------+ inline TxF16 TxF16::Abs() { TxF16 t; t.fp = fp; if( fp < 0 ) { t.fp = ~t.fp; // negieren t.fp ++; // + 1 } return t; } //::16 // +----------+ // | Sign () | // +----------+ inline TxF16 TxF16::Sign() { if ( fp < 0 )return TxF16(-1); else if( fp > 0 ) return TxF16(1); else return TxF16(0); } //::16 // +-----------+ // | Round () | // +-----------+ inline TxF16 TxF16::Round() { TxF16 t; t.fp = fp + (I_STEP>>1); if( fp < 0 && fp&(I_STEP-1) ) { t.fp += I_STEP; } return t; } //::16 // +------------+ // | Floor () | // +------------+ inline TxF16 TxF16::Floor() { TxF16 t; t.fp = fp; if( fp < 0 && fp&(I_STEP-1) ) { t.fp += I_STEP; } return t; } //::16 // +-----------+ // | Ceil () | // +-----------+ inline TxF16 TxF16::Ceil() { TxF16 t; t.fp = fp; if( fp < 0 && fp&(I_STEP-1) ) { t -= I_STEP; } return t; } #endif //_LL3D_FPMATH_H