#pragma once #include "common/IErrors.h" #pragma warning(disable: 4221) #include typedef unsigned char UInt8; //!< An unsigned 8-bit integer value typedef unsigned short UInt16; //!< An unsigned 16-bit integer value typedef unsigned long UInt32; //!< An unsigned 32-bit integer value typedef unsigned long long UInt64; //!< An unsigned 64-bit integer value typedef signed char SInt8; //!< A signed 8-bit integer value typedef signed short SInt16; //!< A signed 16-bit integer value typedef signed long SInt32; //!< A signed 32-bit integer value typedef signed long long SInt64; //!< A signed 64-bit integer value typedef float Float32; //!< A 32-bit floating point value typedef double Float64; //!< A 64-bit floating point value inline UInt32 Extend16(UInt32 in) { return (in & 0x8000) ? (0xFFFF0000 | in) : in; } inline UInt32 Extend8(UInt32 in) { return (in & 0x80) ? (0xFFFFFF00 | in) : in; } inline UInt16 Swap16(UInt16 in) { return ((in >> 8) & 0x00FF) | ((in << 8) & 0xFF00); } inline UInt32 Swap32(UInt32 in) { return ((in >> 24) & 0x000000FF) | ((in >> 8) & 0x0000FF00) | ((in << 8) & 0x00FF0000) | ((in << 24) & 0xFF000000); } inline UInt64 Swap64(UInt64 in) { UInt64 temp; temp = Swap32(in); temp <<= 32; temp |= Swap32(in >> 32); return temp; } inline void SwapFloat(float * in) { UInt32 * temp = (UInt32 *)in; *temp = Swap32(*temp); } inline void SwapDouble(double * in) { UInt64 * temp = (UInt64 *)in; *temp = Swap64(*temp); } inline bool IsBigEndian(void) { union { UInt16 u16; UInt8 u8[2]; } temp; temp.u16 = 0x1234; return temp.u8[0] == 0x12; } inline bool IsLittleEndian(void) { return !IsBigEndian(); } #define CHAR_CODE(a, b, c, d) (((a & 0xFF) << 0) | ((b & 0xFF) << 8) | ((c & 0xFF) << 16) | ((d & 0xFF) << 24)) #define MACRO_SWAP16(a) ((((a) & 0x00FF) << 8) | (((a) & 0xFF00) >> 8)) #define MACRO_SWAP32(a) ((((a) & 0x000000FF) << 24) | (((a) & 0x0000FF00) << 8) | (((a) & 0x00FF0000) >> 8) | (((a) & 0xFF000000) >> 24)) #define VERSION_CODE(primary, secondary, sub) (((primary & 0xFFF) << 20) | ((secondary & 0xFFF) << 8) | ((sub & 0xFF) << 0)) #define VERSION_CODE_PRIMARY(in) ((in >> 20) & 0xFFF) #define VERSION_CODE_SECONDARY(in) ((in >> 8) & 0xFFF) #define VERSION_CODE_SUB(in) ((in >> 0) & 0xFF) #define MAKE_COLOR(a, r, g, b) (((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0)) #define COLOR_ALPHA(in) ((in >> 24) & 0xFF) #define COLOR_RED(in) ((in >> 16) & 0xFF) #define COLOR_GREEN(in) ((in >> 8) & 0xFF) #define COLOR_BLUE(in) ((in >> 0) & 0xFF) /** * A 64-bit variable combiner * * Useful for endian-independent value extraction. */ union VarCombiner { UInt64 u64; SInt64 s64; double f64; struct { UInt32 b; UInt32 a; } u32; struct { SInt32 b; SInt32 a; } s32; struct { float b; float a; } f32; struct { UInt16 d; UInt16 c; UInt16 b; UInt16 a; } u16; struct { SInt16 d; SInt16 c; SInt16 b; SInt16 a; } s16; struct { UInt8 h; UInt8 g; UInt8 f; UInt8 e; UInt8 d; UInt8 c; UInt8 b; UInt8 a; } u8; struct { SInt8 h; SInt8 g; SInt8 f; SInt8 e; SInt8 d; SInt8 c; SInt8 b; SInt8 a; } s8; }; /** * A bitfield. */ template class Bitfield { public: Bitfield() { } ~Bitfield() { } void Clear(void) { field = 0; } //!< Clears all bits void RawSet(UInt32 data) { field = data; } //!< Modifies all bits void Set(UInt32 data) { field |= data; } //!< Sets individual bits void Clear(UInt32 data) { field &= ~data; } //!< Clears individual bits void UnSet(UInt32 data) { Clear(data); } //!< Clears individual bits void Mask(UInt32 data) { field &= data; } //!< Masks individual bits void Toggle(UInt32 data) { field ^= data; } //!< Toggles individual bits void Write(UInt32 data, bool state) { if(state) Set(data); else Clear(data); } T Get(void) const { return field; } //!< Gets all bits T Get(UInt32 data) const { return field & data; } //!< Gets individual bits T Extract(UInt32 bit) const { return (field >> bit) & 1; } //!< Extracts a bit T ExtractField(UInt32 shift, UInt32 length) //!< Extracts a series of bits { return (field >> shift) & (0xFFFFFFFF >> (32 - length)); } bool IsSet(UInt32 data) const { return ((field & data) == data) ? true : false; } //!< Are all these bits set? bool IsUnSet(UInt32 data) const { return (field & data) ? false : true; } //!< Are all these bits clear? bool IsClear(UInt32 data) const { return IsUnSet(data); } //!< Are all these bits clear? private: T field; //!< bitfield data }; typedef Bitfield Bitfield8; //!< An 8-bit bitfield typedef Bitfield Bitfield16; //!< A 16-bit bitfield typedef Bitfield Bitfield32; //!< A 32-bit bitfield STATIC_ASSERT(sizeof(Bitfield8) == 1); STATIC_ASSERT(sizeof(Bitfield16) == 2); STATIC_ASSERT(sizeof(Bitfield32) == 4); /** * A bitstring * * Essentially a long bitvector. */ class Bitstring { public: Bitstring(); Bitstring(UInt32 inLength); ~Bitstring(); void Alloc(UInt32 inLength); void Dispose(void); void Clear(void); void Clear(UInt32 idx); void Set(UInt32 idx); bool IsSet(UInt32 idx); bool IsClear(UInt32 idx); private: UInt8 * data; UInt32 length; //!< length in bytes }; /** * Time storage */ class Time { public: Time() { Clear(); } ~Time() { } //! Deinitialize the class void Clear(void) { seconds = minutes = hours = 0; hasData = false; } //! Sets the class to the current time //! @todo implement this void SetToNow(void) { Set(1, 2, 3); } //! Sets the class to the specified time void Set(UInt8 inS, UInt8 inM, UInt8 inH) { seconds = inS; minutes = inM; hours = inH; hasData = true; } //! Gets whether the class has been initialized or not bool IsSet(void) { return hasData; } UInt8 GetSeconds(void) { return seconds; } //!< return the seconds portion of the time UInt8 GetMinutes(void) { return minutes; } //!< return the minutes portion of the time UInt8 GetHours(void) { return hours; } //!< return the hours portion of the time private: UInt8 seconds, minutes, hours; bool hasData; }; const float kFloatEpsilon = 0.0001f; inline bool FloatEqual(float a, float b) { float magnitude = a - b; if(magnitude < 0) magnitude = -magnitude; return magnitude < kFloatEpsilon; } class Vector2 { public: Vector2() { } Vector2(const Vector2 & in) { x = in.x; y = in.y; } Vector2(float inX, float inY) { x = inX; y = inY; } ~Vector2() { } void Set(float inX, float inY) { x = inX; y = inY; } void SetX(float inX) { x = inX; } void SetY(float inY) { y = inY; } void Get(float * outX, float * outY) { *outX = x; *outY = y; } float GetX(void) { return x; } float GetY(void) { return y; } void Normalize(void) { float mag = Magnitude(); x /= mag; y /= mag; } float Magnitude(void) { return sqrt(x*x + y*y); } void Reverse(void) { float temp = -x; x = -y; y = temp; } void Scale(float scale) { x *= scale; y *= scale; } void SwapBytes(void) { SwapFloat(&x); SwapFloat(&y); } Vector2 & operator+=(const Vector2 & rhs) { x += rhs.x; y += rhs.y; return *this; } Vector2 & operator-=(const Vector2 & rhs) { x -= rhs.x; y -= rhs.y; return *this; } Vector2 & operator*=(float rhs) { x *= rhs; y *= rhs; return *this; } Vector2 & operator/=(float rhs) { x /= rhs; y /= rhs; return *this; } float x; float y; }; inline Vector2 operator+(const Vector2 & lhs, const Vector2 & rhs) { return Vector2(lhs.x + rhs.x, lhs.y + rhs.y); }; inline Vector2 operator-(const Vector2 & lhs, const Vector2 & rhs) { return Vector2(lhs.x - rhs.x, lhs.y - rhs.y); }; inline Vector2 operator*(const Vector2 & lhs, float rhs) { return Vector2(lhs.x * rhs, lhs.y * rhs); }; inline Vector2 operator/(const Vector2 & lhs, float rhs) { return Vector2(lhs.x / rhs, lhs.y / rhs); }; inline bool MaskCompare(void * lhs, void * rhs, void * mask, UInt32 size) { UInt8 * lhs8 = (UInt8 *)lhs; UInt8 * rhs8 = (UInt8 *)rhs; UInt8 * mask8 = (UInt8 *)mask; for(UInt32 i = 0; i < size; i++) if((lhs8[i] & mask8[i]) != (rhs8[i] & mask8[i])) return false; return true; } class Vector3 { public: Vector3() { } Vector3(const Vector3 & in) { x = in.x; y = in.y; z = in.z; } Vector3(float inX, float inY, float inZ) { x = inX; y = inY; z = inZ; } ~Vector3() { } void Set(float inX, float inY, float inZ) { x = inX; y = inY; z = inZ; } void Get(float * outX, float * outY, float * outZ) { *outX = x; *outY = y; *outZ = z; } void Normalize(void) { float mag = Magnitude(); x /= mag; y /= mag; z /= mag; } float Magnitude(void) { return sqrt(x*x + y*y + z*z); } void Scale(float scale) { x *= scale; y *= scale; z *= scale; } void SwapBytes(void) { SwapFloat(&x); SwapFloat(&y); SwapFloat(&z); } Vector3 & operator+=(const Vector3 & rhs) { x += rhs.x; y += rhs.y; z += rhs.z; return *this; } Vector3 & operator-=(const Vector3 & rhs) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; } Vector3 & operator*=(const Vector3 & rhs) { x *= rhs.x; y *= rhs.y; z *= rhs.z; return *this; } Vector3 & operator/=(const Vector3 & rhs) { x /= rhs.x; y /= rhs.y; z /= rhs.z; return *this; } union { struct { float x, y, z; }; float d[3]; }; }; inline Vector3 operator+(const Vector3 & lhs, const Vector3 & rhs) { return Vector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z); } inline Vector3 operator-(const Vector3 & lhs, const Vector3 & rhs) { return Vector3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z); } inline Vector3 operator*(const Vector3 & lhs, const Vector3 & rhs) { return Vector3(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z); } inline Vector3 operator/(const Vector3 & lhs, const Vector3 & rhs) { return Vector3(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z); }