#ifndef PLATFORM_HPP #define PLATFORM_HPP //// Platform tweaks //// #include "RakNetTypes.h" #ifdef _WIN32_WCE //makslane # define _byteswap_ushort(s) ((s >> 8) | (s << 8)) # define _byteswap_ulong(s) (byteswap_ushort(s&0xffff)<<16) | (byteswap_ushort(s>>16)) # define byteswap_ushort _byteswap_ushort # define byteswap_ulong _byteswap_ulong #endif #if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) # if defined(__sparc) || defined(__sparc__) || defined(__powerpc__) || \ defined(__ppc__) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || \ defined(_M_PPC) || defined(_M_MPPC) || defined(_M_MRX000) || \ defined(__POWERPC) || defined(m68k) || defined(powerpc) || \ defined(sel) || defined(pyr) || defined(mc68000) || defined(is68k) || \ defined(tahoe) || defined(ibm032) || defined(ibm370) || defined(MIPSEB) || \ defined(__convex__) || defined(DGUX) || defined(hppa) || defined(apollo) || \ defined(_CRAY) || defined(__hp9000) || defined(__hp9000s300) || defined(_AIX) || \ defined(__AIX) || defined(__pyr__) || defined(hp9000s700) || defined(_IBMR2) # define BIG_ENDIAN # elif defined(__i386__) || defined(i386) || defined(intel) || defined(_M_IX86) || \ defined(__alpha__) || defined(__alpha) || defined(__ia64) || defined(__ia64__) || \ defined(_M_ALPHA) || defined(ns32000) || defined(__ns32000__) || defined(sequent) || \ defined(MIPSEL) || defined(_MIPSEL) || defined(sun386) || defined(__sun386__) || \ defined(x86_64) || defined(__x86_64) # define LITTLE_ENDIAN # else # error "Add your platform to the list" # endif #endif //// Compiler tweaks //// // Structure packing syntax #if defined(__GNUC__) #ifndef PACKED # define PACKED __attribute__((__packed__)) #endif # define ASSEMBLY_ATT_SYNTAX # define ASSEMBLY_BLOCK asm #elif defined(_WIN32) # define PACKED # define PRAGMA_PACK /* pragma push/pop */ #ifndef DEBUG # define DEBUG _DEBUG #endif # if !defined(_M_X64) # define ASSEMBLY_INTEL_SYNTAX # define ASSEMBLY_BLOCK __asm # endif #elif defined(__BORLANDC__) // Borland # define ASSEMBLY_INTEL_SYNTAX # define ASSEMBLY_BLOCK _asm #else # error "Fix code for your compiler's packing syntax" #endif // Stringize #define STRINGIZE(X) DO_STRINGIZE(X) #define DO_STRINGIZE(X) #X //// Elementary types //// struct u128 { uint32_t u[4]; }; union Float32 { float f; uint32_t i; Float32(float n) { f = n; } Float32(uint32_t n) { i = n; } }; //// Coordinate system //// // Order of vertices in any quad enum QuadCoords { QUAD_UL, // upper left (0,0) QUAD_LL, // lower left (0,1) QUAD_LR, // lower right (1,1) QUAD_UR, // upper right (1,0) }; //// Rotation macros //// #ifndef ROL8 #define ROL8(n, r) ( ((uint8_t)(n) << (r)) | ((uint8_t)(n) >> ( 8 - (r))) ) /* only works for uint8_t */ #endif #ifndef ROR8 #define ROR8(n, r) ( ((uint8_t)(n) >> (r)) | ((uint8_t)(n) << ( 8 - (r))) ) /* only works for uint8_t */ #endif #ifndef ROL16 #define ROL16(n, r) ( ((uint16_t)(n) << (r)) | ((uint16_t)(n) >> (16 - (r))) ) /* only works for uint16_t */ #endif #ifndef ROR16 #define ROR16(n, r) ( ((uint16_t)(n) >> (r)) | ((uint16_t)(n) << (16 - (r))) ) /* only works for uint16_t */ #endif #ifndef ROL32 #define ROL32(n, r) ( ((uint32_t)(n) << (r)) | ((uint32_t)(n) >> (32 - (r))) ) /* only works for uint32_t */ #endif #ifndef ROR32 #define ROR32(n, r) ( ((uint32_t)(n) >> (r)) | ((uint32_t)(n) << (32 - (r))) ) /* only works for uint32_t */ #endif #ifndef ROL64 #define ROL64(n, r) ( ((uint64_t)(n) << (r)) | ((uint64_t)(n) >> (64 - (r))) ) /* only works for uint64_t */ #endif #ifndef ROR64 #define ROR64(n, r) ( ((uint64_t)(n) >> (r)) | ((uint64_t)(n) << (64 - (r))) ) /* only works for uint64_t */ #endif //// Byte-order swapping //// #ifndef BOSWAP16 #define BOSWAP16(n) ROL16(n, 8) #endif #ifndef BOSWAP32 #define BOSWAP32(n) ( (ROL32(n, 8) & 0x00ff00ff) | (ROL32(n, 24) & 0xff00ff00) ) #endif #ifndef BOSWAP64 #define BOSWAP64(n) ( ((uint64_t)BOSWAP32((uint32_t)n) << 32) | BOSWAP32((uint32_t)(n >> 32)) ) #endif //// Miscellaneous bitwise macros //// #define BITCLRHI8(reg, count) ((uint8_t)((uint8_t)(reg) << (count)) >> (count)) /* sets to zero a number of high bits in a byte */ #define BITCLRLO8(reg, count) ((uint8_t)((uint8_t)(reg) >> (count)) << (count)) /* sets to zero a number of low bits in a byte */ #define BITCLRHI16(reg, count) ((uint16_t)((uint16_t)(reg) << (count)) >> (count)) /* sets to zero a number of high bits in a 16-bit word */ #define BITCLRLO16(reg, count) ((uint16_t)((uint16_t)(reg) >> (count)) << (count)) /* sets to zero a number of low bits in a 16-bit word */ #define BITCLRHI32(reg, count) ((uint32_t)((uint32_t)(reg) << (count)) >> (count)) /* sets to zero a number of high bits in a 32-bit word */ #define BITCLRLO32(reg, count) ((uint32_t)((uint32_t)(reg) >> (count)) << (count)) /* sets to zero a number of low bits in a 32-bit word */ //// Integer macros //// #define AT_LEAST_2_BITS(n) ( (n) & ((n) - 1) ) #define LEAST_SIGNIFICANT_BIT(n) ( (n) & -(n) ) /* 0 -> 0 */ #define IS_POWER_OF_2(n) ( n && !AT_LEAST_2_BITS(n) ) // Bump 'n' to the next unit of 'width' // 0=CEIL_UNIT(0, 16), 1=CEIL_UNIT(1, 16), 1=CEIL_UNIT(16, 16), 2=CEIL_UNIT(17, 16) #define CEIL_UNIT(n, width) ( ( (n) + (width) - 1 ) / (width) ) // 0=CEIL(0, 16), 16=CEIL(1, 16), 16=CEIL(16, 16), 32=CEIL(17, 16) #define CEIL(n, width) ( CEIL_UNIT(n, width) * (width) ) //// String and buffer macros //// // Same as strncpy() in all ways except that the result is guaranteed to // be a nul-terminated C string #ifndef STRNCPY # define STRNCPY(dest, src, size) { strncpy(dest, src, size); (dest)[(size)-1] = '\0'; } #endif // Because memory clearing is a frequent operation #define MEMCLR(dest, size) memset(dest, 0, size) // Works for arrays, also #define OBJCLR(object) memset(&(object), 0, sizeof(object)) //// Intrinsics //// #if defined(_MSC_VER) # include # pragma intrinsic(_lrotl) # pragma intrinsic(_lrotr) # pragma intrinsic(_byteswap_ushort) # pragma intrinsic(_byteswap_ulong) # undef ROL32 # undef ROR32 # undef BOSWAP16 # undef BOSWAP32 # define ROL32(n, r) _lrotl(n, r) # define ROR32(n, r) _lrotr(n, r) # define BOSWAP16(n) _byteswap_ushort(n) # define BOSWAP32(n) _byteswap_ulong(n) #endif // getLE() converts from little-endian word to native byte-order word // getBE() converts from big-endian word to native byte-order word #if defined(LITTLE_ENDIAN) # define swapLE(n) # define getLE(n) (n) # define getLE16(n) (n) # define getLE32(n) (n) # define getLE64(n) (n) inline void swapBE(uint16_t &n) { n = BOSWAP16(n); } inline void swapBE(uint32_t &n) { n = BOSWAP32(n); } inline void swapBE(uint64_t &n) { n = BOSWAP64(n); } inline uint16_t getBE(uint16_t n) { return BOSWAP16(n); } inline uint32_t getBE(uint32_t n) { return BOSWAP32(n); } inline uint64_t getBE(uint64_t n) { return BOSWAP64(n); } inline uint16_t getBE16(uint16_t n) { return BOSWAP16(n); } inline uint32_t getBE32(uint32_t n) { return BOSWAP32(n); } inline uint64_t getBE64(uint64_t n) { return BOSWAP64(n); } inline void swapBE(int16_t &n) { n = BOSWAP16((uint16_t)n); } inline void swapBE(int32_t &n) { n = BOSWAP32((uint32_t)n); } inline void swapBE(int64_t &n) { n = BOSWAP64((uint64_t)n); } inline int16_t getBE(int16_t n) { return BOSWAP16((uint16_t)n); } inline int32_t getBE(int32_t n) { return BOSWAP32((uint32_t)n); } inline int64_t getBE(int64_t n) { return BOSWAP64((uint64_t)n); } inline float getBE(float n) { Float32 c = n; c.i = BOSWAP32(c.i); return c.f; } #else # define swapBE(n) # define getBE(n) (n) # define getBE16(n) (n) # define getBE32(n) (n) # define getBE64(n) (n) inline void swapLE(uint16_t &n) { n = BOSWAP16(n); } inline void swapLE(uint32_t &n) { n = BOSWAP32(n); } inline void swapLE(uint64_t &n) { n = BOSWAP64(n); } inline uint16_t getLE(uint16_t n) { return BOSWAP16(n); } inline uint32_t getLE(uint32_t n) { return BOSWAP32(n); } inline uint64_t getLE(uint64_t n) { return BOSWAP64(n); } inline uint16_t getLE16(uint16_t n) { return BOSWAP16(n); } inline uint32_t getLE32(uint32_t n) { return BOSWAP32(n); } inline uint64_t getLE32(uint64_t n) { return BOSWAP64(n); } inline void swapLE(int16_t &n) { n = BOSWAP16((uint16_t)n); } inline void swapLE(int32_t &n) { n = BOSWAP32((uint32_t)n); } inline void swapLE(int64_t &n) { n = BOSWAP64((uint64_t)n); } inline int16_t getLE(int16_t n) { return BOSWAP16((uint16_t)n); } inline int32_t getLE(int32_t n) { return BOSWAP32((uint32_t)n); } inline int64_t getLE(int64_t n) { return BOSWAP64((uint64_t)n); } inline float getLE(float n) { Float32 c = n; c.i = BOSWAP32(c.i); return c.f; } #endif #endif // include guard