/// ======================================================================== // (C) Copyright 1994- 2014 RAD Game Tools, Inc. Global types header file // ======================================================================== #ifndef __RADRR_COREH__ #define __RADRR_COREH__ #define RADCOPYRIGHT "Copyright (C) 1994-2014, RAD Game Tools, Inc." // __RAD16__ means 16 bit code (Win16) // __RAD32__ means 32 bit code (DOS, Win386, Win32s, Mac AND Win64) // __RAD64__ means 64 bit code (x64) // Note oddness - __RAD32__ essentially means "at *least* 32-bit code". // So, on 64-bit systems, both __RAD32__ and __RAD64__ will be defined. // __RADDOS__ means DOS code (16 or 32 bit) // __RADWIN__ means Windows API (Win16, Win386, Win32s, Win64, Xbox, Xenon) // __RADWINEXT__ means Windows 386 extender (Win386) // __RADNT__ means Win32 or Win64 code // __RADWINRTAPI__ means Windows RT API (Win 8, Win Phone, ARM, Durango) // __RADMAC__ means Macintosh // __RADCARBON__ means Carbon // __RADMACH__ means MachO // __RADXBOX__ means the XBox console // __RADXENON__ means the Xenon console // __RADDURANGO__ or __RADXBOXONE__ means Xbox One // __RADNGC__ means the Nintendo GameCube // __RADWII__ means the Nintendo Wii // __RADWIIU__ means the Nintendo Wii U // __RADNDS__ means the Nintendo DS // __RADTWL__ means the Nintendo DSi (__RADNDS__ also defined) // __RAD3DS__ means the Nintendo 3DS // __RADPS2__ means the Sony PlayStation 2 // __RADPSP__ means the Sony PlayStation Portable // __RADPS3__ means the Sony PlayStation 3 // __RADPS4__ means the Sony PlayStation 4 // __RADANDROID__ means Android NDK // __RADNACL__ means Native Client SDK // __RADNTBUILDLINUX__ means building Linux on NT // __RADLINUX__ means actually building on Linux (most likely with GCC) // __RADPSP2__ means NGP // __RADBSD__ means a BSD-style UNIX (OS X, FreeBSD, OpenBSD, NetBSD) // __RADPOSIX__ means POSIX-compliant // __RADQNX__ means QNX // __RADIPHONE__ means iphone // __RADIPHONESIM__ means iphone simulator // __RADX86__ means Intel x86 // __RADMMX__ means Intel x86 MMX instructions are allowed // __RADX64__ means Intel/AMD x64 (NOT IA64=Itanium) // __RAD68K__ means 68K // __RADPPC__ means PowerPC // __RADMIPS__ means Mips (only R5900 right now) // __RADARM__ mean ARM processors // __RADLITTLEENDIAN__ means processor is little-endian (x86) // __RADBIGENDIAN__ means processor is big-endian (680x0, PPC) // __RADNOVARARGMACROS__ means #defines can't use ... #ifdef WINAPI_FAMILY // If this is #defined, we might be in a Windows Store App. But // VC++ by default #defines this to a symbolic name, not an integer // value, and those names are defined in "winapifamily.h". So if // WINAPI_FAMILY is #defined, #include the header so we can parse it. #include #define RAD_WINAPI_IS_APP (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) #else #define RAD_WINAPI_IS_APP 0 #endif #ifndef __RADRES__ // Theoretically, this is to pad structs on platforms that don't support pragma // pack or do it poorly. (PS3, PS2) In general it is assumed that your padding // is set via pragma, so this is just a struct. #define RADSTRUCT struct #ifdef __GNUC_MINOR__ // make a combined GCC version for testing : #define __RAD_GCC_VERSION__ \ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) /* Test for GCC > 3.2.0 */ // #if GCC_VERSION > 30200 #endif #if defined(__RADX32__) #define __RADX86__ #define __RADMMX__ #define __RAD32__ #define __RADLITTLEENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict // known platforms under the RAD generic build type #if defined(_WIN32) || defined(_Windows) || defined(WIN32) || \ defined(__WINDOWS__) || defined(_WINDOWS) #define __RADNT__ #define __RADWIN__ #elif (defined(__MWERKS__) && !defined(__INTEL__)) || defined(__MRC__) || \ defined(THINK_C) || defined(powerc) || defined(macintosh) || \ defined(__powerc) || defined(__APPLE__) || defined(__MACH__) #define __RADMAC__ #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(__linux__) #define __RADLINUX__ #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #endif #elif defined(ANDROID) #define __RADANDROID__ #define __RAD32__ #define __RADLITTLEENDIAN__ #ifdef __i386__ #define __RADX86__ #else #define __RADARM__ #endif #define RADINLINE inline #define RADRESTRICT __restrict #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(__QNX__) #define __RAD32__ #define __RADQNX__ #ifdef __arm__ #define __RADARM__ #elif defined __i386__ #define __RADX86__ #else #error Unknown processor #endif #define __RADLITTLEENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(__linux__) && \ defined(__arm__) // This should pull in Raspberry Pi as well #define __RAD32__ #define __RADLINUX__ #define __RADARM__ #define __RADLITTLEENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(__native_client__) #define __RADNACL__ #define __RAD32__ #define __RADLITTLEENDIAN__ #define __RADX86__ #define RADINLINE inline #define RADRESTRICT __restrict #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(_DURANGO) || defined(_SEKRIT) || defined(_SEKRIT1) || \ defined(_XBOX_ONE) #define __RADDURANGO__ 1 #define __RADXBOXONE__ 1 #if !defined(__RADSEKRIT__) // keep sekrit around for a bit for compat #define __RADSEKRIT__ 1 #endif #define __RADWIN__ #define __RAD32__ #define __RAD64__ #define __RADX64__ #define __RADMMX__ #define __RADX86__ #define __RAD64REGS__ #define __RADLITTLEENDIAN__ #define RADINLINE __inline #define RADRESTRICT __restrict #define __RADWINRTAPI__ #elif defined(__ORBIS__) #define __RADPS4__ #if !defined(__RADSEKRIT2__) // keep sekrit2 around for a bit for compat #define __RADSEKRIT2__ 1 #endif #define __RAD32__ #define __RAD64__ #define __RADX64__ #define __RADMMX__ #define __RADX86__ #define __RAD64REGS__ #define __RADLITTLEENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(WINAPI_FAMILY) && RAD_WINAPI_IS_APP #define __RADWINRTAPI__ #define __RADWIN__ #define RADINLINE __inline #define RADRESTRICT __restrict #if defined(_M_IX86) // WinRT on x86 #define __RAD32__ #define __RADX86__ #define __RADMMX__ #define __RADLITTLEENDIAN__ #elif defined(_M_X64) // WinRT on x64 #define __RAD32__ #define __RAD64__ #define __RADX86__ #define __RADX64__ #define __RADMMX__ #define __RAD64REGS__ #define __RADLITTLEENDIAN__ #elif defined(_M_ARM) // WinRT on ARM #define __RAD32__ #define __RADARM__ #define __RADLITTLEENDIAN__ #else #error Unrecognized WinRT platform! #endif #elif defined(_WIN64) #define __RADWIN__ #define __RADNT__ // See note at top for why both __RAD32__ and __RAD64__ are defined. #define __RAD32__ #define __RAD64__ #define __RADX64__ #define __RADMMX__ #define __RADX86__ #define __RAD64REGS__ #define __RADLITTLEENDIAN__ #define RADINLINE __inline #define RADRESTRICT __restrict #elif defined(GENERIC_ARM) #define __RAD32__ #define __RADARM__ #define __RADLITTLEENDIAN__ #define __RADFIXEDPOINT__ #define RADINLINE inline #if (defined(__GCC__) || defined(__GNUC__)) #define RADRESTRICT __restrict #else #define RADRESTRICT // __restrict not supported on cw #endif #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(CAFE) // has to be before HOLLYWOOD_REV since it also defines it #define __RADWIIU__ #define __RAD32__ #define __RADPPC__ #define __RADBIGENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(HOLLYWOOD_REV) || defined(REVOLUTION) #define __RADWII__ #define __RAD32__ #define __RADPPC__ #define __RADBIGENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #elif defined(NN_PLATFORM_CTR) #define __RAD3DS__ #define __RAD32__ #define __RADARM__ #define __RADLITTLEENDIAN__ #define RADINLINE inline #define RADRESTRICT #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(GEKKO) #define __RADNGC__ #define __RAD32__ #define __RADPPC__ #define __RADBIGENDIAN__ #define RADINLINE inline #define RADRESTRICT // __restrict not supported on cw #elif defined(SDK_ARM9) || defined(SDK_TWL) || \ (defined(__arm) && defined(__MWERKS__)) #define __RADNDS__ #define __RAD32__ #define __RADARM__ #define __RADLITTLEENDIAN__ #define __RADFIXEDPOINT__ #define RADINLINE inline #if (defined(__GCC__) || defined(__GNUC__)) #define RADRESTRICT __restrict #else #define RADRESTRICT // __restrict not supported on cw #endif #if defined(SDK_TWL) #define __RADTWL__ #endif #elif defined(R5900) #define __RADPS2__ #define __RAD32__ #define __RADMIPS__ #define __RADLITTLEENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #define __RAD64REGS__ #define U128 u_long128 #if !defined(__MWERKS__) #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #endif #elif defined(__psp__) #define __RADPSP__ #define __RAD32__ #define __RADMIPS__ #define __RADLITTLEENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #elif defined(__psp2__) #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #define __RADPSP2__ #define __RAD32__ #define __RADARM__ #define __RADLITTLEENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict // need packed attribute for struct with snc? #elif defined(__CELLOS_LV2__) // CB change : 10-29-10 : RAD64REGS on PPU but NOT SPU #ifdef __SPU__ #define __RADSPU__ #define __RAD32__ #define __RADCELL__ #define __RADBIGENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #else #define __RAD64REGS__ #define __RADPS3__ #define __RADPPC__ #define __RAD32__ #define __RADCELL__ #define __RADBIGENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #define __RADALTIVEC__ #endif #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #ifndef __LP32__ #error "PS3 32bit ABI support only" #endif #elif (defined(__MWERKS__) && !defined(__INTEL__)) || defined(__MRC__) || \ defined(THINK_C) || defined(powerc) || defined(macintosh) || \ defined(__powerc) || defined(__APPLE__) || defined(__MACH__) #ifdef __APPLE__ #include "TargetConditionals.h" #endif #if ((defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \ (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR)) // iPhone/iPad/iOS #define __RADIPHONE__ #define __RADMACAPI__ #define __RAD32__ #if defined(__x86_64__) #define __RAD64__ #endif #define __RADLITTLEENDIAN__ #define RADINLINE inline #define RADRESTRICT __restrict #define __RADMACH__ #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR #if defined(__x86_64__) #define __RADX64__ #else #define __RADX86__ #endif #define __RADIPHONESIM__ #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE #define __RADARM__ #endif #else // An actual MacOSX machine #define __RADMAC__ #define __RADMACAPI__ #if defined(powerc) || defined(__powerc) || defined(__ppc__) #define __RADPPC__ #define __RADBIGENDIAN__ #define __RADALTIVEC__ #define RADRESTRICT #elif defined(__i386__) #define __RADX86__ #define __RADMMX__ #define __RADLITTLEENDIAN__ #define RADRESTRICT __restrict #elif defined(__x86_64__) #define __RAD32__ #define __RAD64__ #define __RADX86__ #define __RADX64__ #define __RAD64REGS__ #define __RADMMX__ #define __RADLITTLEENDIAN__ #define RADRESTRICT __restrict #else #define __RAD68K__ #define __RADBIGENDIAN__ #define __RADALTIVEC__ #define RADRESTRICT #endif #define __RAD32__ #if defined(__MWERKS__) #if (defined(__cplusplus) || !__option(only_std_keywords)) #define RADINLINE inline #endif #ifdef __MACH__ #define __RADMACH__ #endif #elif defined(__MRC__) #if defined(__cplusplus) #define RADINLINE inline #endif #elif defined(__GNUC__) || defined(__GNUG__) || defined(__MACH__) #define RADINLINE inline #define __RADMACH__ #undef RADRESTRICT /* could have been defined above... */ #define RADRESTRICT __restrict #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #endif #ifdef __RADX86__ #ifndef __RADCARBON__ #define __RADCARBON__ #endif #endif #ifdef TARGET_API_MAC_CARBON #if TARGET_API_MAC_CARBON #ifndef __RADCARBON__ #define __RADCARBON__ #endif #endif #endif #endif #elif defined(__linux__) #define __RADLINUX__ #define __RADMMX__ #define __RADLITTLEENDIAN__ #define __RADX86__ #ifdef __x86_64 #define __RAD32__ #define __RAD64__ #define __RADX64__ #define __RAD64REGS__ #else #define __RAD32__ #endif #define RADINLINE inline #define RADRESTRICT __restrict #undef RADSTRUCT #define RADSTRUCT struct __attribute__((__packed__)) #else #if _MSC_VER >= 1400 #undef RADRESTRICT #define RADRESTRICT __restrict #else #define RADRESTRICT #define __RADNOVARARGMACROS__ #endif #if defined(_XENON) || (defined(_XBOX_VER) && (_XBOX_VER == 200)) // Remember that Xenon also defines _XBOX #define __RADPPC__ #define __RADBIGENDIAN__ #define __RADALTIVEC__ #else #define __RADX86__ #define __RADMMX__ #define __RADLITTLEENDIAN__ #endif #ifdef __MWERKS__ #define _WIN32 #endif #ifdef __DOS__ #define __RADDOS__ #define S64_DEFINED // turn off these types #define U64_DEFINED #define S64 double // should error #define U64 double // should error #define __RADNOVARARGMACROS__ #endif #ifdef __386__ #define __RAD32__ #endif #ifdef _Windows // For Borland #ifdef __WIN32__ #define WIN32 #else #define __WINDOWS__ #endif #endif #ifdef _WINDOWS // For MS #ifndef _WIN32 #define __WINDOWS__ #endif #endif #ifdef _WIN32 #if defined(_XENON) || (defined(_XBOX_VER) && (_XBOX_VER == 200)) // Remember that Xenon also defines _XBOX #define __RADXENON__ #define __RAD64REGS__ #elif defined(_XBOX) #define __RADXBOX__ #elif !defined(__RADWINRTAPI__) #define __RADNT__ #endif #define __RADWIN__ #define __RAD32__ #else #ifdef __NT__ #if defined(_XENON) || (_XBOX_VER == 200) // Remember that Xenon also defines _XBOX #define __RADXENON__ #define __RAD64REGS__ #elif defined(_XBOX) #define __RADXBOX__ #else #define __RADNT__ #endif #define __RADWIN__ #define __RAD32__ #else #ifdef __WINDOWS_386__ #define __RADWIN__ #define __RADWINEXT__ #define __RAD32__ #define S64_DEFINED // turn off these types #define U64_DEFINED #define S64 double // should error #define U64 double // should error #else #ifdef __WINDOWS__ #define __RADWIN__ #define __RAD16__ #else #ifdef WIN32 #if defined(_XENON) || (_XBOX_VER == 200) // Remember that Xenon also defines _XBOX #define __RADXENON__ #elif defined(_XBOX) #define __RADXBOX__ #else #define __RADNT__ #endif #define __RADWIN__ #define __RAD32__ #endif #endif #endif #endif #endif #ifdef __WATCOMC__ #define RADINLINE #else #define RADINLINE __inline #endif #endif #if defined __RADMAC__ || defined __RADIPHONE__ #define __RADBSD__ #endif #if defined __RADBSD__ || defined __RADLINUX__ #define __RADPOSIX__ #endif #if (!defined(__RADDOS__) && !defined(__RADWIN__) && !defined(__RADMAC__) && \ !defined(__RADNGC__) && !defined(__RADNDS__) && !defined(__RADXBOX__) && \ !defined(__RADXENON__) && !defined(__RADDURANGO__) && \ !defined(__RADPS4__) && !defined(__RADLINUX__) && !defined(__RADPS2__) && \ !defined(__RADPSP__) && !defined(__RADPSP2__) && !defined(__RADPS3__) && \ !defined(__RADSPU__) && !defined(__RADWII__) && \ !defined(__RADIPHONE__) && !defined(__RADX32__) && \ !defined(__RADARM__) && !defined(__RADWIIU__) && \ !defined(__RADANDROID__) && !defined(__RADNACL__) && \ !defined(__RADQNX__)) #error \ "RAD.H did not detect your platform. Define DOS, WINDOWS, WIN32, macintosh, powerpc, or appropriate console." #endif #ifdef __RADFINAL__ #define RADTODO(str) \ { char __str[0] = str; } #else #define RADTODO(str) #endif #ifdef __RADX32__ #if defined(_MSC_VER) #define RADLINK __stdcall #define RADEXPLINK __stdcall #else #define RADLINK __attribute__((stdcall)) #define RADEXPLINK __attribute__((stdcall)) #endif #define RADEXPFUNC RADDEFFUNC #elif (defined(__RADNGC__) || defined(__RADWII__) || defined(__RADPS2__) || \ defined(__RADPSP__) || defined(__RADPSP2__) || defined(__RADPS3__) || \ defined(__RADSPU__) || defined(__RADNDS__) || defined(__RADIPHONE__) || \ (defined(__RADARM__) && !defined(__RADWINRTAPI__)) || \ defined(__RADWIIU__) || defined(__RADPS4__)) #define RADLINK #define RADEXPLINK #define RADEXPFUNC RADDEFFUNC #define RADASMLINK #elif defined(__RADANDROID__) #define RADLINK #define RADEXPLINK #define RADEXPFUNC RADDEFFUNC #define RADASMLINK #elif defined(__RADNACL__) #define RADLINK #define RADEXPLINK #define RADEXPFUNC RADDEFFUNC #define RADASMLINK #elif defined(__RADLINUX__) || defined(__RADQNX__) #ifdef __RAD64__ #define RADLINK #define RADEXPLINK #else #define RADLINK __attribute__((cdecl)) #define RADEXPLINK __attribute__((cdecl)) #endif #define RADEXPFUNC RADDEFFUNC #define RADASMLINK #elif defined(__RADMAC__) // this define is for CodeWarrior 11's stupid new libs (even though // we don't use longlong's). #define __MSL_LONGLONG_SUPPORT__ #define RADLINK #define RADEXPLINK #if defined(__CFM68K__) || defined(__MWERKS__) #ifdef __RADINDLL__ #define RADEXPFUNC RADDEFFUNC __declspec(export) #else #define RADEXPFUNC RADDEFFUNC __declspec(import) #endif #else #if defined(__RADMACH__) && !defined(__MWERKS__) #ifdef __RADINDLL__ #define RADEXPFUNC RADDEFFUNC __attribute__((visibility("default"))) #else #define RADEXPFUNC RADDEFFUNC #endif #else #define RADEXPFUNC RADDEFFUNC #endif #endif #define RADASMLINK #else #ifdef __RADNT__ #ifndef _WIN32 #define _WIN32 #endif #ifndef WIN32 #define WIN32 #endif #endif #ifdef __RADWIN__ #ifdef __RAD32__ #ifdef __RADXBOX__ #define RADLINK __stdcall #define RADEXPLINK __stdcall #define RADEXPFUNC RADDEFFUNC #elif defined(__RADXENON__) || defined(__RADDURANGO__) #define RADLINK __stdcall #define RADEXPLINK __stdcall #define RADEXPFUNC RADDEFFUNC #elif defined(__RADWINRTAPI__) #define RADLINK __stdcall #define RADEXPLINK __stdcall #if (defined(__RADINSTATICLIB__) || defined(__RADNOEXPORTS__) || \ (defined(__RADNOEXEEXPORTS__) && (!defined(__RADINDLL__)) && \ (!defined(__RADINSTATICLIB__)))) #define RADEXPFUNC RADDEFFUNC #else #ifndef __RADINDLL__ #define RADEXPFUNC RADDEFFUNC __declspec(dllimport) #else #define RADEXPFUNC RADDEFFUNC __declspec(dllexport) #endif #endif #elif defined(__RADNTBUILDLINUX__) #define RADLINK __cdecl #define RADEXPLINK __cdecl #define RADEXPFUNC RADDEFFUNC #else #ifdef __RADNT__ #define RADLINK __stdcall #define RADEXPLINK __stdcall #if (defined(__RADINSTATICLIB__) || defined(__RADNOEXPORTS__) || \ (defined(__RADNOEXEEXPORTS__) && (!defined(__RADINDLL__)) && \ (!defined(__RADINSTATICLIB__)))) #define RADEXPFUNC RADDEFFUNC #else #ifndef __RADINDLL__ #define RADEXPFUNC RADDEFFUNC __declspec(dllimport) #ifdef __BORLANDC__ #if __BORLANDC__ <= 0x460 #undef RADEXPFUNC #define RADEXPFUNC RADDEFFUNC #endif #endif #else #define RADEXPFUNC RADDEFFUNC __declspec(dllexport) #endif #endif #else #define RADLINK __pascal #define RADEXPLINK __far __pascal #define RADEXPFUNC RADDEFFUNC #endif #endif #else #define RADLINK __pascal #define RADEXPLINK __far __pascal __export #define RADEXPFUNC RADDEFFUNC #endif #else #define RADLINK __pascal #define RADEXPLINK __pascal #define RADEXPFUNC RADDEFFUNC #endif #define RADASMLINK __cdecl #endif #if !defined(__RADXBOX__) && !defined(__RADXENON__) && \ !defined(__RADDURANGO__) && !defined(__RADXBOXONE__) #ifdef __RADWIN__ #ifndef _WINDOWS #define _WINDOWS #endif #endif #endif #ifdef __RADLITTLEENDIAN__ #ifdef __RADBIGENDIAN__ #error both endians !? #endif #endif #if !defined(__RADLITTLEENDIAN__) && !defined(__RADBIGENDIAN__) #error neither endian! #endif //----------------------------------------------------------------- #ifndef RADDEFFUNC #ifdef __cplusplus #define RADDEFFUNC extern "C" #define RADDEFSTART extern "C" { #define RADDEFEND } #define RADDEFINEDATA extern "C" #define RADDECLAREDATA extern "C" #define RADDEFAULT(val) = val #define RR_NAMESPACE rr #define RR_NAMESPACE_START namespace RR_NAMESPACE { #define RR_NAMESPACE_END \ } \ ; #define RR_NAMESPACE_USE using namespace RR_NAMESPACE; #else #define RADDEFFUNC #define RADDEFSTART #define RADDEFEND #define RADDEFINEDATA #define RADDECLAREDATA extern #define RADDEFAULT(val) #define RR_NAMESPACE #define RR_NAMESPACE_START #define RR_NAMESPACE_END #define RR_NAMESPACE_USE #endif #endif // probably s.b: RAD_DECLARE_ALIGNED(type, name, alignment) #if (defined(__RADWII__) || defined(__RADWIIU__) || defined(__RADPSP__) || \ defined(__RADPSP2__) || defined(__RADPS3__) || defined(__RADSPU__) || \ defined(__RADPS4__) || defined(__RADLINUX__) || defined(__RADMAC__)) || \ defined(__RADNDS__) || defined(__RAD3DS__) || defined(__RADIPHONE__) || \ defined(__RADANDROID__) || defined(__RADQNX__) #define RAD_ALIGN(type, var, num) type __attribute__((aligned(num))) var #elif (defined(__RADNGC__) || defined(__RADPS2__)) #define RAD_ALIGN(type, var, num) __attribute__((aligned(num))) type var #elif (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__RADWINRTAPI__) #define RAD_ALIGN(type, var, num) type __declspec(align(num)) var #else // NOTE: / / is a guaranteed parse error in C/C++. #define RAD_ALIGN(type, var, num) RAD_ALIGN_USED_BUT_NOT_DEFINED / / #endif // WARNING : RAD_TLS should really only be used for debug/tools stuff // it's not reliable because even if we are built as a lib, our lib can // be put into a DLL and then it doesn't work #if defined(__RADNT__) || defined(__RADXENON__) #ifndef __RADINDLL__ // note that you can't use this in windows DLLs #define RAD_TLS(type, var) __declspec(thread) type var #endif #elif defined(__RADPS3__) || defined(__RADLINUX__) || defined(__RADMAC__) // works on PS3/gcc I believe : #define RAD_TLS(type, var) __thread type var #else // RAD_TLS not defined #endif // Note that __RAD16__/__RAD32__/__RAD64__ refers to the size of a pointer. // The size of integers is specified explicitly in the code, i.e. u32 or // whatever. #define RAD_S8 signed char #define RAD_U8 unsigned char #if defined(__RAD64__) // Remember that __RAD32__ will also be defined! #if defined(__RADX64__) // x64 still has 32-bit ints! #define RAD_U32 unsigned int #define RAD_S32 signed int // But pointers are 64 bits. #if (_MSC_VER >= 1300 && defined(_Wp64) && _Wp64) #define RAD_SINTa __w64 signed int64_t #define RAD_UINTa __w64 unsigned int64_t #else // non-vc.net compiler or /Wp64 turned off #define RAD_UINTa unsigned long long #define RAD_SINTa signed long long #endif #else #error Unknown 64-bit processor (see radbase.h) #endif #elif defined(__RAD32__) #define RAD_U32 unsigned int #define RAD_S32 signed int // Pointers are 32 bits. #if ((defined(_MSC_VER) && (_MSC_VER >= 1300)) && (defined(_Wp64) && (_Wp64))) #define RAD_SINTa __w64 signed long #define RAD_UINTa __w64 unsigned long #else // non-vc.net compiler or /Wp64 turned off #ifdef _Wp64 #define RAD_SINTa signed long #define RAD_UINTa unsigned long #else #define RAD_SINTa signed int #define RAD_UINTa unsigned int #endif #endif #else #define RAD_U32 unsigned long #define RAD_S32 signed long // Pointers in 16-bit land are still 32 bits. #define RAD_UINTa unsigned long #define RAD_SINTa signed long #endif #define RAD_F32 float #if defined(__RADPS2__) || defined(__RADPSP__) typedef RADSTRUCT RAD_F64 // do this so that we don't accidentally use doubles { // while using the same space RAD_U32 vals[2]; } RAD_F64; #define RAD_F64_OR_32 float // type is F64 if available, otherwise F32 #else #define RAD_F64 double #define RAD_F64_OR_32 double // type is F64 if available, otherwise F32 #endif #if (defined(__RADMAC__) || defined(__MRC__) || defined(__RADNGC__) || \ defined(__RADLINUX__) || defined(__RADWII__) || defined(__RADWIIU__) || \ defined(__RADNDS__) || defined(__RADPSP__) || defined(__RADPS3__) || \ defined(__RADPS4__) || defined(__RADSPU__) || defined(__RADIPHONE__) || \ defined(__RADNACL__) || defined(__RADANDROID__) || defined(__RADQNX__)) #define RAD_U64 unsigned long long #define RAD_S64 signed long long #elif defined(__RADPS2__) #define RAD_U64 unsigned long #define RAD_S64 signed long #elif defined(__RADARM__) #define RAD_U64 unsigned long long #define RAD_S64 signed long long #elif defined(__RADX64__) || defined(__RAD32__) #define RAD_U64 unsigned int64_t #define RAD_S64 signed int64_t #else // 16-bit typedef RADSTRUCT RAD_U64 // do this so that we don't accidentally use U64s { // while using the same space RAD_U32 vals[2]; } RAD_U64; typedef RADSTRUCT RAD_S64 // do this so that we don't accidentally use S64s { // while using the same space RAD_S32 vals[2]; } RAD_S64; #endif #if defined(__RAD32__) #define PTR4 #define RAD_U16 unsigned short #define RAD_S16 signed short #else #define PTR4 __far #define RAD_U16 unsigned int #define RAD_S16 signed int #endif //------------------------------------------------- // RAD_PTRBITS and such defined here without using sizeof() // so that they can be used in align() and other macros #ifdef __RAD64__ #define RAD_PTRBITS 64 #define RAD_PTRBYTES 8 #define RAD_TWOPTRBYTES 16 #else #define RAD_PTRBITS 32 #define RAD_PTRBYTES 4 #define RAD_TWOPTRBYTES 8 #endif //------------------------------------------------- // UINTr = int the size of a register #ifdef __RAD64REGS__ #define RAD_UINTr RAD_U64 #define RAD_SINTr RAD_S64 #else #define RAD_UINTr RAD_U32 #define RAD_SINTr RAD_S32 #endif //=========================================================================== /* // CB : meh this is enough of a mess that it's probably best to just let each #if defined(__RADX86__) && defined(_MSC_VER) && _MSC_VER >= 1300 #define __RADX86INTRIN2003__ #endif */ // RADASSUME(expr) tells the compiler that expr is always true // RADUNREACHABLE must never be reachable - even in event of error // eg. it's okay for compiler to generate completely invalid code after // RADUNREACHABLE #ifdef _MSC_VER #define RADFORCEINLINE __forceinline #if _MSC_VER >= 1300 #define RADNOINLINE __declspec(noinline) #else #define RADNOINLINE #endif #define RADUNREACHABLE __assume(0) #define RADASSUME(exp) __assume(exp) #elif defined(__clang__) #ifdef _DEBUG #define RADFORCEINLINE inline #else #define RADFORCEINLINE inline __attribute((always_inline)) #endif #define RADNOINLINE __attribute__((noinline)) #define RADUNREACHABLE __builtin_unreachable() #if __has_builtin(__builtin_assume) #define RADASSUME(exp) __builtin_assume(exp) #else #define RADASSUME(exp) \ RAD_STATEMENT_WRAPPER(if (!(exp)) __builtin_unreachable();) #endif #elif (defined(__GCC__) || defined(__GNUC__)) || defined(ANDROID) #ifdef _DEBUG #define RADFORCEINLINE inline #else #define RADFORCEINLINE inline __attribute((always_inline)) #endif #define RADNOINLINE __attribute__((noinline)) #if __RAD_GCC_VERSION__ >= 40500 #define RADUNREACHABLE __builtin_unreachable() #define RADASSUME(exp) \ RAD_STATEMENT_WRAPPER(if (!(exp)) __builtin_unreachable();) #else #define RADUNREACHABLE RAD_INFINITE_LOOP(RR_BREAK();) #define RADASSUME(exp) #endif #elif defined(__CWCC__) #define RADFORCEINLINE inline #define RADNOINLINE __attribute__((never_inline)) #define RADUNREACHABLE #define RADASSUME(x) (void)0 #else // ? #define RADFORCEINLINE ? #define RADFORCEINLINE inline #define RADNOINLINE #define RADASSUME(x) (void)0 #endif //=========================================================================== // RAD_ALIGN_HINT tells the compiler how a given pointer is aligned // it *must* be true, but the compiler may or may not use that information // it is not for cases where the pointer is to an inherently aligned data type, // it's when the compiler cannot tell the alignment but you have extra // information. // eg : // U8 * ptr = rrMallocAligned(256,16); // RAD_ALIGN_HINT(ptr,16,0); #ifdef __RADSPU__ #define RAD_ALIGN_HINT(ptr, alignment, offset) \ __align_hint(ptr, alignment, offset); \ RR_ASSERT(((UINTa)(ptr) & ((alignment) - 1)) == (UINTa)(offset)) #else #define RAD_ALIGN_HINT(ptr, alignment, offset) \ RADASSUME(((UINTa)(ptr) & ((alignment) - 1)) == (UINTa)(offset)) #endif //=========================================================================== // RAD_EXPECT is to tell the compiler the *likely* value of an expression // different than RADASSUME in that expr might not have that value // it's use for branch code layout and static branch prediction // condition can technically be a variable but should usually be 0 or 1 #if (defined(__GCC__) || defined(__GNUC__)) || defined(__clang__) // __builtin_expect returns value of expr #define RAD_EXPECT(expr, cond) __builtin_expect(expr, cond) #else #define RAD_EXPECT(expr, cond) (expr) #endif // helpers for doing an if ( ) with expect : // if ( RAD_LIKELY(expr) ) { ... } #define RAD_LIKELY(expr) RAD_EXPECT(expr, 1) #define RAD_UNLIKELY(expr) RAD_EXPECT(expr, 0) //=========================================================================== // __RADX86ASM__ means you can use __asm {} style inline assembly #if defined(__RADX86__) && !defined(__RADX64__) && defined(_MSC_VER) #define __RADX86ASM__ #endif //------------------------------------------------- // typedefs : #ifndef RADNOTYPEDEFS #ifndef S8_DEFINED #define S8_DEFINED typedef RAD_S8 S8; #endif #ifndef U8_DEFINED #define U8_DEFINED typedef RAD_U8 U8; #endif #ifndef S16_DEFINED #define S16_DEFINED typedef RAD_S16 S16; #endif #ifndef U16_DEFINED #define U16_DEFINED typedef RAD_U16 U16; #endif #ifndef S32_DEFINED #define S32_DEFINED typedef RAD_S32 S32; #endif #ifndef U32_DEFINED #define U32_DEFINED typedef RAD_U32 U32; #endif #ifndef S64_DEFINED #define S64_DEFINED typedef RAD_S64 S64; #endif #ifndef U64_DEFINED #define U64_DEFINED typedef RAD_U64 U64; #endif #ifndef F32_DEFINED #define F32_DEFINED typedef RAD_F32 F32; #endif #ifndef F64_DEFINED #define F64_DEFINED typedef RAD_F64 F64; #endif #ifndef F64_OR_32_DEFINED #define F64_OR_32_DEFINED typedef RAD_F64_OR_32 F64_OR_32; #endif // UINTa and SINTa are the ints big enough for an address #ifndef SINTa_DEFINED #define SINTa_DEFINED typedef RAD_SINTa SINTa; #endif #ifndef UINTa_DEFINED #define UINTa_DEFINED typedef RAD_UINTa UINTa; #endif #ifndef UINTr_DEFINED #define UINTr_DEFINED typedef RAD_UINTr UINTr; #endif #ifndef SINTr_DEFINED #define SINTr_DEFINED typedef RAD_SINTr SINTr; #endif #elif !defined(RADNOTYPEDEFINES) #ifndef S8_DEFINED #define S8_DEFINED #define S8 RAD_S8 #endif #ifndef U8_DEFINED #define U8_DEFINED #define U8 RAD_U8 #endif #ifndef S16_DEFINED #define S16_DEFINED #define S16 RAD_S16 #endif #ifndef U16_DEFINED #define U16_DEFINED #define U16 RAD_U16 #endif #ifndef S32_DEFINED #define S32_DEFINED #define S32 RAD_S32 #endif #ifndef U32_DEFINED #define U32_DEFINED #define U32 RAD_U32 #endif #ifndef S64_DEFINED #define S64_DEFINED #define S64 RAD_S64 #endif #ifndef U64_DEFINED #define U64_DEFINED #define U64 RAD_U64 #endif #ifndef F32_DEFINED #define F32_DEFINED #define F32 RAD_F32 #endif #ifndef F64_DEFINED #define F64_DEFINED #define F64 RAD_F64 #endif #ifndef F64_OR_32_DEFINED #define F64_OR_32_DEFINED #define F64_OR_32 RAD_F64_OR_32 #endif // UINTa and SINTa are the ints big enough for an address (pointer) #ifndef SINTa_DEFINED #define SINTa_DEFINED #define SINTa RAD_SINTa #endif #ifndef UINTa_DEFINED #define UINTa_DEFINED #define UINTa RAD_UINTa #endif #ifndef UINTr_DEFINED #define UINTr_DEFINED #define UINTr RAD_UINTr #endif #ifndef SINTr_DEFINED #define SINTr_DEFINED #define SINTr RAD_SINTr #endif #endif /// Some error-checking. #if defined(__RAD64__) && !defined(__RAD32__) // See top of file for why this is. #error __RAD64__ must not be defined without __RAD32__ (see radbase.h) #endif #ifdef _MSC_VER // microsoft compilers #if _MSC_VER >= 1400 #define RAD_STATEMENT_START do { #define RAD_STATEMENT_END_FALSE \ __pragma(warning(push)) __pragma(warning(disable : 4127)) \ } \ while (0) __pragma(warning(pop)) #define RAD_STATEMENT_END_TRUE \ __pragma(warning(push)) __pragma(warning(disable : 4127)) \ } \ while (1) __pragma(warning(pop)) #else #define RAD_USE_STANDARD_LOOP_CONSTRUCT #endif #else #define RAD_USE_STANDARD_LOOP_CONSTRUCT #endif #ifdef RAD_USE_STANDARD_LOOP_CONSTRUCT #define RAD_STATEMENT_START do { #define RAD_STATEMENT_END_FALSE \ } \ while ((void)0, 0) #define RAD_STATEMENT_END_TRUE \ } \ while ((void)1, 1) #endif #define RAD_STATEMENT_WRAPPER(code) \ RAD_STATEMENT_START \ code RAD_STATEMENT_END_FALSE #define RAD_INFINITE_LOOP(code) \ RAD_STATEMENT_START \ code RAD_STATEMENT_END_TRUE // Must be placed after variable declarations for code compiled as .c #if defined(_MSC_VER) && _MSC_VER >= 1700 // in 2012 aka 11.0 and later #define RR_UNUSED_VARIABLE(x) (void)x #else #define RR_UNUSED_VARIABLE(x) (void)(sizeof(x)) #endif //----------------------------------------------- // RR_UINT3264 is a U64 in 64-bit code and a U32 in 32-bit code // eg. it's pointer sized and the same type as a U32/U64 of the same size // // @@ CB 05/21/2012 : I think RR_UINT3264 may be deprecated // it was useful back when UINTa was /Wp64 // but since we removed that maybe it's not anymore ? // #ifdef __RAD64__ #define RR_UINT3264 U64 #else #define RR_UINT3264 U32 #endif // RR_COMPILER_ASSERT( sizeof(RR_UINT3264) == sizeof(UINTa) ); //-------------------------------------------------- // RR_LINESTRING is the current line number as a string #define RR_STRINGIZE(L) #L #define RR_DO_MACRO(M, X) M(X) #define RR_STRINGIZE_DELAY(X) RR_DO_MACRO(RR_STRINGIZE, X) #define RR_LINESTRING RR_STRINGIZE_DELAY(__LINE__) #define RR_CAT(X, Y) X##Y // RR_STRING_JOIN joins strings in the preprocessor and works with LINESTRING #define RR_STRING_JOIN(arg1, arg2) RR_STRING_JOIN_DELAY(arg1, arg2) #define RR_STRING_JOIN_DELAY(arg1, arg2) RR_STRING_JOIN_IMMEDIATE(arg1, arg2) #define RR_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1##arg2 // RR_NUMBERNAME is a macro to make a name unique, so that you can use it to // declare // variable names and they won't conflict with each other // using __LINE__ is broken in MSVC with /ZI , but __COUNTER__ is an MSVC // extension that works #ifdef _MSC_VER #define RR_NUMBERNAME(name) RR_STRING_JOIN(name, __COUNTER__) #else #define RR_NUMBERNAME(name) RR_STRING_JOIN(name, __LINE__) #endif //-------------------------------------------------- // current plan is to use "rrbool" with plain old "true" and "false" // if true and false give us trouble we might have to go to rrtrue and rrfalse // BTW there's a danger for evil bugs here !! If you're checking == true // then the rrbool must be set to exactly "1" not just "not zero" !! #ifndef RADNOTYPEDEFS #ifndef RRBOOL_DEFINED #define RRBOOL_DEFINED typedef S32 rrbool; typedef S32 RRBOOL; #endif #elif !defined(RADNOTYPEDEFINES) #ifndef RRBOOL_DEFINED #define RRBOOL_DEFINED #define rrbool S32 #define RRBOOL S32 #endif #endif //-------------------------------------------------- // Range macros #ifndef RR_MIN #define RR_MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef RR_MAX #define RR_MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef RR_ABS #define RR_ABS(a) (((a) < 0) ? -(a) : (a)) #endif #ifndef RR_CLAMP #define RR_CLAMP(val, lo, hi) RR_MAX(RR_MIN(val, hi), lo) #endif //-------------------------------------------------- // Data layout macros #define RR_ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) // MEMBER_OFFSET tells you the offset of a member in a type #ifdef __RAD3DS__ #define RR_MEMBER_OFFSET(type, member) \ (unsigned int)(((char *)&(((type *)0)->member) - (char *)0)) #elif defined(__RADANDROID__) || defined(__RADPSP__) || defined(__RADPS3__) || \ defined(__RADSPU__) // offsetof() gets mucked with by system headers on android, making things // dependent on #include order. #define RR_MEMBER_OFFSET(type, member) __builtin_offsetof(type, member) #elif defined(__RADLINUX__) #define RR_MEMBER_OFFSET(type, member) (offsetof(type, member)) #else #define RR_MEMBER_OFFSET(type, member) ((size_t)(UINTa) & (((type *)0)->member)) #endif // MEMBER_SIZE tells you the size of a member in a type #define RR_MEMBER_SIZE(type, member) (sizeof(((type *)0)->member)) // just to make gcc shut up about derefing null : #define RR_MEMBER_OFFSET_PTR(type, member, ptr) \ ((SINTa) & (((type *)(ptr))->member) - (SINTa)(ptr)) #define RR_MEMBER_SIZE_PTR(type, member, ptr) (sizeof(((type *)(ptr))->member)) // MEMBER_TO_OWNER takes a pointer to a member and gives you back the base of // the object // you should then RR_ASSERT( &(ret->member) == ptr ); #define RR_MEMBER_TO_OWNER(type, member, ptr) \ (type *)(((char *)(ptr)) - RR_MEMBER_OFFSET_PTR(type, member, ptr)) //-------------------------------------------------- // Cache / prefetch macros : // RR_PREFETCH for various platforms : // // RR_PREFETCH_SEQUENTIAL : prefetch memory for reading in a sequential scan // platforms that automatically prefetch sequential (eg. PC) should //be a no-op here // RR_PREFETCH_WRITE_INVALIDATE : prefetch memory for writing - contents of // memory are undefined // (may be a no-op, may be a normal prefetch, may zero memory) // warning : RR_PREFETCH_WRITE_INVALIDATE may write memory so don't //do it past the end of buffers #ifdef __RADX86__ #define RR_PREFETCH_SEQUENTIAL(ptr, offset) // nop #define RR_PREFETCH_WRITE_INVALIDATE(ptr, offset) // nop #elif defined(__RADXENON__) #define RR_PREFETCH_SEQUENTIAL(ptr, offset) __dcbt((int)(offset), (void *)(ptr)) #define RR_PREFETCH_WRITE_INVALIDATE(ptr, offset) \ __dcbz128((int)(offset), (void *)(ptr)) #elif defined(__RADPS3__) #define RR_PREFETCH_SEQUENTIAL(ptr, offset) \ __dcbt((char *)(ptr) + (int)(offset)) #define RR_PREFETCH_WRITE_INVALIDATE(ptr, offset) \ __dcbz((char *)(ptr) + (int)(offset)) #elif defined(__RADSPU__) #define RR_PREFETCH_SEQUENTIAL(ptr, offset) // intentional NOP #define RR_PREFETCH_WRITE_INVALIDATE(ptr, offset) // nop #elif defined(__RADWII__) || defined(__RADWIIU__) #define RR_PREFETCH_SEQUENTIAL(ptr, offset) // intentional NOP for now #define RR_PREFETCH_WRITE_INVALIDATE(ptr, offset) // nop #elif defined(__RAD3DS__) #define RR_PREFETCH_SEQUENTIAL(ptr, offset) __pld((char *)(ptr) + (int)(offset)) #define RR_PREFETCH_WRITE_INVALIDATE(ptr, offset) \ __pldw((char *)(ptr) + (int)(offset)) #else // other platform #define RR_PREFETCH_SEQUENTIAL(ptr, offset) // need_prefetch // compile error #define RR_PREFETCH_WRITE_INVALIDATE(ptr, offset) // need_writezero // error #endif //-------------------------------------------------- // LIGHTWEIGHT ASSERTS without rrAssert.h RADDEFSTART // set up RR_BREAK : #ifdef __RADNGC__ #define RR_BREAK() asm(" .long 0x00000001") #define RR_CACHE_LINE_SIZE xxx #elif defined(__RADWII__) #define RR_BREAK() __asm__ volatile("trap") #define RR_CACHE_LINE_SIZE 32 #elif defined(__RADWIIU__) #define RR_BREAK() asm("trap") #define RR_CACHE_LINE_SIZE 32 #elif defined(__RAD3DS__) #define RR_BREAK() *((int volatile *)0) = 0 #define RR_CACHE_LINE_SIZE 32 #elif defined(__RADNDS__) #define RR_BREAK() asm("BKPT 0") #define RR_CACHE_LINE_SIZE xxx #elif defined(__RADPS2__) #define RR_BREAK() __asm__ volatile("break") #define RR_CACHE_LINE_SIZE 64 #elif defined(__RADPSP__) #define RR_BREAK() __asm__("break 0") #define RR_CACHE_LINE_SIZE 64 #elif defined(__RADPSP2__) #define RR_BREAK() \ { __asm__ volatile("bkpt 0x0000"); } #define RR_CACHE_LINE_SIZE 32 #elif defined(__RADQNX__) #define RR_BREAK() __builtin_trap() #define RR_CACHE_LINE_SIZE 32 #elif defined(__RADARM__) && defined(__RADLINUX__) #define RR_BREAK() __builtin_trap() #define RR_CACHE_LINE_SIZE 32 #elif defined(__RADSPU__) #define RR_BREAK() __asm volatile("stopd 0,1,1") #define RR_CACHE_LINE_SIZE 128 #elif defined(__RADPS3__) // #ifdef snPause // in LibSN.h // snPause // __asm__ volatile ( "tw 31,1,1" ) #define RR_BREAK() __asm__ volatile("tw 31,1,1") // #define RR_BREAK() __asm__ volatile("trap"); #define RR_CACHE_LINE_SIZE 128 #elif defined(__RADMAC__) #if defined(__GNUG__) || defined(__GNUC__) #ifdef __RADX86__ #define RR_BREAK() __asm__ volatile("int $3") #else #define RR_BREAK() __builtin_trap() #endif #else #ifdef __RADMACH__ void DebugStr(unsigned char const *); #else void pascal DebugStr(unsigned char const *); #endif #define RR_BREAK() DebugStr("\pRR_BREAK() was called") #endif #define RR_CACHE_LINE_SIZE 64 #elif defined(__RADIPHONE__) #define RR_BREAK() __builtin_trap() #define RR_CACHE_LINE_SIZE 32 #elif defined(__RADXENON__) #define RR_BREAK() assert(0) #define RR_CACHE_LINE_SIZE 128 #elif defined(__RADANDROID__) #define RR_BREAK() __builtin_trap() #define RR_CACHE_LINE_SIZE 32 #elif defined(__RADPS4__) #define RR_BREAK() __builtin_trap() #define RR_CACHE_LINE_SIZE 64 #elif defined(__RADNACL__) #define RR_BREAK() __builtin_trap() #define RR_CACHE_LINE_SIZE 64 #else // x86 : #define RR_CACHE_LINE_SIZE 64 #ifdef __RADLINUX__ #define RR_BREAK() __asm__ volatile("int $3") #elif defined(__WATCOMC__) void RR_BREAK(void); #pragma aux RR_BREAK = "int 0x3"; #elif defined(__RADWIN__) && defined(_MSC_VER) && _MSC_VER >= 1300 #define RR_BREAK __debugbreak #else #define RR_BREAK() RAD_STATEMENT_WRAPPER(__asm {int 3}) #endif #endif // simple RR_ASSERT : // CB 5-27-10 : use RR_DO_ASSERTS to toggle asserts on and off : #if (defined(_DEBUG) && !defined(NDEBUG)) || defined(ASSERT_IN_RELEASE) #define RR_DO_ASSERTS #endif /********* rrAsserts : RR_ASSERT(exp) - the normal assert thing, toggled with RR_DO_ASSERTS RR_ASSERT_ALWAYS(exp) - assert that you want to test even in ALL builds (including final!) RR_ASSERT_RELEASE(exp) - assert that you want to test even in release builds (not for final!) RR_ASSERT_LITE(exp) - normal assert is not safe from threads or inside malloc; use this instead RR_DURING_ASSERT(exp) - wrap operations that compute stuff for assert in here RR_DO_ASSERTS - toggle tells you if asserts are enabled or not RR_BREAK() - generate a debug break - always ! RR_ASSERT_BREAK() - RR_BREAK for asserts ; disable with RAD_NO_BREAK RR_ASSERT_FAILURE(str) - just break with a messsage; like assert with no condition RR_ASSERT_FAILURE_ALWAYS(str) - RR_ASSERT_FAILURE in release builds too RR_CANT_GET_HERE() - put in spots execution should never go RR_COMPILER_ASSERT(exp) - checks constant conditions at compile time RADTODO - note to search for nonfinal stuff RR_PRAGMA_MESSAGE - message dealy, use with #pragma in MSVC *************/ //----------------------------------------------------------- #if defined(__GNUG__) || defined(__GNUC__) || \ (defined(_MSC_VER) && _MSC_VER > 1200) #define RR_FUNCTION_NAME __FUNCTION__ #else #define RR_FUNCTION_NAME 0 // __func__ is in the C99 standard #endif //----------------------------------------------------------- // rrDisplayAssertion might just log, or it might pop a message box, depending // on settings // rrDisplayAssertion returns whether you should break or not typedef rrbool(RADLINK fp_rrDisplayAssertion)(int *Ignored, const char *fileName, const int line, const char *function, const char *message); extern fp_rrDisplayAssertion *g_fp_rrDisplayAssertion; // if I have func pointer, call it, else true ; true = do int 3 #define rrDisplayAssertion(i, n, l, f, m) \ ((g_fp_rrDisplayAssertion) ? (*g_fp_rrDisplayAssertion)(i, n, l, f, m) : 1) //----------------------------------------------------------- // RAD_NO_BREAK : option if you don't like your assert to break // CB : RR_BREAK is *always* a break ; RR_ASSERT_BREAK is optional #ifdef RAD_NO_BREAK #define RR_ASSERT_BREAK() 0 #else #define RR_ASSERT_BREAK() RR_BREAK() #endif // assert_always is on FINAL ! #define RR_ASSERT_ALWAYS(exp) \ RAD_STATEMENT_WRAPPER(static int Ignored = 0; if (!(exp)) { \ if (rrDisplayAssertion(&Ignored, __FILE__, __LINE__, RR_FUNCTION_NAME, \ #exp)) \ RR_ASSERT_BREAK(); \ }) // RR_ASSERT_FAILURE is like an assert without a condition - if you hit it, // you're bad #define RR_ASSERT_FAILURE_ALWAYS(str) \ RAD_STATEMENT_WRAPPER(static int Ignored = 0; \ if (rrDisplayAssertion(&Ignored, __FILE__, __LINE__, \ RR_FUNCTION_NAME, str)) \ RR_ASSERT_BREAK();) #define RR_ASSERT_LITE_ALWAYS(exp) \ RAD_STATEMENT_WRAPPER(if (!(exp)) { RR_ASSERT_BREAK(); }) //----------------------------------- #ifdef RR_DO_ASSERTS #define RR_ASSERT(exp) RR_ASSERT_ALWAYS(exp) #define RR_ASSERT_LITE(exp) RR_ASSERT_LITE_ALWAYS(exp) #define RR_ASSERT_NO_ASSUME(exp) RR_ASSERT_ALWAYS(exp) // RR_DURING_ASSERT is to set up expressions or declare variables that are only // used in asserts #define RR_DURING_ASSERT(exp) exp #define RR_ASSERT_FAILURE(str) RR_ASSERT_FAILURE_ALWAYS(str) // RR_CANT_GET_HERE is for like defaults in switches that should never be hit #define RR_CANT_GET_HERE() \ RAD_STATEMENT_WRAPPER(RR_ASSERT_FAILURE("can't get here"); RADUNREACHABLE;) #else // RR_DO_ASSERTS //----------------------------------- #define RR_ASSERT(exp) (void)0 #define RR_ASSERT_LITE(exp) (void)0 #define RR_ASSERT_NO_ASSUME(exp) (void)0 #define RR_DURING_ASSERT(exp) (void)0 #define RR_ASSERT_FAILURE(str) (void)0 #define RR_CANT_GET_HERE() RADUNREACHABLE #endif // RR_DO_ASSERTS //----------------------------------- //================================================================= // RR_ASSERT_RELEASE is on in release build, but not final #ifndef __RADFINAL__ #define RR_ASSERT_RELEASE(exp) RR_ASSERT_ALWAYS(exp) #define RR_ASSERT_LITE_RELEASE(exp) RR_ASSERT_LITE_ALWAYS(exp) #else #define RR_ASSERT_RELEASE(exp) (void)0 #define RR_ASSERT_LITE_RELEASE(exp) (void)0 #endif // BH: This never gets compiled away except for __RADFINAL__ #define RR_ASSERT_ALWAYS_NO_SHIP RR_ASSERT_RELEASE #define rrAssert RR_ASSERT #define rrassert RR_ASSERT #ifdef _MSC_VER // without this, our assert errors... #if _MSC_VER >= 1300 #pragma warning(disable : 4127) // conditional expression is constant #endif #endif //--------------------------------------- // Get/Put from memory in little or big endian : // // val = RR_GET32_BE(ptr) // RR_PUT32_BE(ptr,val) // // available here : // RR_[GET/PUT][16/32]_[BE/LE][_UNALIGNED][_OFFSET] // // if you don't specify _UNALIGNED , then ptr & offset shoud both be //aligned to type size _OFFSET is in *bytes* ! // you can #define RR_GET_RESTRICT to make all RR_GETs be RESTRICT // if you set nothing they are not #ifdef RR_GET_RESTRICT #define RR_GET_PTR_POST RADRESTRICT #endif #ifndef RR_GET_PTR_POST #define RR_GET_PTR_POST #endif // native version of get/put is always trivial : #define RR_GET16_NATIVE(ptr) *((const U16 *RR_GET_PTR_POST)(ptr)) #define RR_PUT16_NATIVE(ptr, val) *((U16 * RR_GET_PTR_POST)(ptr)) = (val) // offset is in bytes #define RR_U16_PTR_OFFSET(ptr, offset) \ ((U16 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) #define RR_GET16_NATIVE_OFFSET(ptr, offset) *(RR_U16_PTR_OFFSET((ptr), offset)) #define RR_PUT16_NATIVE_OFFSET(ptr, val, offset) \ *(RR_U16_PTR_OFFSET((ptr), offset)) = (val) #define RR_GET32_NATIVE(ptr) *((const U32 *RR_GET_PTR_POST)(ptr)) #define RR_PUT32_NATIVE(ptr, val) *((U32 * RR_GET_PTR_POST)(ptr)) = (val) // offset is in bytes #define RR_U32_PTR_OFFSET(ptr, offset) \ ((U32 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) #define RR_GET32_NATIVE_OFFSET(ptr, offset) *(RR_U32_PTR_OFFSET((ptr), offset)) #define RR_PUT32_NATIVE_OFFSET(ptr, val, offset) \ *(RR_U32_PTR_OFFSET((ptr), offset)) = (val) #define RR_GET64_NATIVE(ptr) *((const U64 *RR_GET_PTR_POST)(ptr)) #define RR_PUT64_NATIVE(ptr, val) *((U64 * RR_GET_PTR_POST)(ptr)) = (val) // offset is in bytes #define RR_U64_PTR_OFFSET(ptr, offset) \ ((U64 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) #define RR_GET64_NATIVE_OFFSET(ptr, offset) *(RR_U64_PTR_OFFSET((ptr), offset)) #define RR_PUT64_NATIVE_OFFSET(ptr, val, offset) \ *(RR_U64_PTR_OFFSET((ptr), offset)) = (val) //--------------------------------------------------- #ifdef __RADLITTLEENDIAN__ #define RR_GET16_LE RR_GET16_NATIVE #define RR_PUT16_LE RR_PUT16_NATIVE #define RR_GET16_LE_OFFSET RR_GET16_NATIVE_OFFSET #define RR_PUT16_LE_OFFSET RR_PUT16_NATIVE_OFFSET #define RR_GET32_LE RR_GET32_NATIVE #define RR_PUT32_LE RR_PUT32_NATIVE #define RR_GET32_LE_OFFSET RR_GET32_NATIVE_OFFSET #define RR_PUT32_LE_OFFSET RR_PUT32_NATIVE_OFFSET #define RR_GET64_LE RR_GET64_NATIVE #define RR_PUT64_LE RR_PUT64_NATIVE #define RR_GET64_LE_OFFSET RR_GET64_NATIVE_OFFSET #define RR_PUT64_LE_OFFSET RR_PUT64_NATIVE_OFFSET #else #define RR_GET16_BE RR_GET16_NATIVE #define RR_PUT16_BE RR_PUT16_NATIVE #define RR_GET16_BE_OFFSET RR_GET16_NATIVE_OFFSET #define RR_PUT16_BE_OFFSET RR_PUT16_NATIVE_OFFSET #define RR_GET32_BE RR_GET32_NATIVE #define RR_PUT32_BE RR_PUT32_NATIVE #define RR_GET32_BE_OFFSET RR_GET32_NATIVE_OFFSET #define RR_PUT32_BE_OFFSET RR_PUT32_NATIVE_OFFSET #define RR_GET64_BE RR_GET64_NATIVE #define RR_PUT64_BE RR_PUT64_NATIVE #define RR_GET64_BE_OFFSET RR_GET64_NATIVE_OFFSET #define RR_PUT64_BE_OFFSET RR_PUT64_NATIVE_OFFSET #endif //------------------------- // non-native Get/Put implementations go here : #if defined(__RADX86__) // good implementation for X86 : #if (_MSC_VER >= 1300) unsigned short __cdecl _byteswap_ushort(unsigned short _Short); unsigned long __cdecl _byteswap_ulong(unsigned long _Long); #pragma intrinsic(_byteswap_ushort, _byteswap_ulong) #define RR_BSWAP16 _byteswap_ushort #define RR_BSWAP32 _byteswap_ulong unsigned int64_t __cdecl _byteswap_uint64(unsigned int64_t val); #pragma intrinsic(_byteswap_uint64) #define RR_BSWAP64 _byteswap_uint64 #elif defined(_MSC_VER) // VC6 RADFORCEINLINE unsigned long RR_BSWAP16(unsigned long _Long) { __asm { mov eax, [_Long] rol ax, 8 mov [_Long], eax; } return _Long; } RADFORCEINLINE unsigned long RR_BSWAP32(unsigned long _Long) { __asm { mov eax, [_Long] bswap eax mov [_Long], eax } return _Long; } RADFORCEINLINE unsigned int64_t RR_BSWAP64(unsigned int64_t _Long) { __asm { mov eax, DWORD PTR _Long mov edx, DWORD PTR _Long+4 bswap eax bswap edx mov DWORD PTR _Long, edx mov DWORD PTR _Long+4, eax } return _Long; } #elif defined(__GNUC__) || defined(__clang__) // GCC has __builtin_bswap16, but Clang only seems to have added it recently. // We use __builtin_bswap32/64 but 16 just uses the macro version. (No big // deal if that turns into shifts anyway) #define RR_BSWAP16(u16) ((U16)(((u16) >> 8) | ((u16) << 8))) #define RR_BSWAP32 __builtin_bswap32 #define RR_BSWAP64 __builtin_bswap64 #endif #define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) #define RR_PUT16_BE(ptr, val) *((U16 *)(ptr)) = (U16)RR_BSWAP16(val) #define RR_GET16_BE_OFFSET(ptr, offset) \ RR_BSWAP16(*RR_U16_PTR_OFFSET(ptr, offset)) #define RR_PUT16_BE_OFFSET(ptr, val, offset) \ *RR_U16_PTR_OFFSET(ptr, offset) = RR_BSWAP16(val) #define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) #define RR_PUT32_BE(ptr, val) *((U32 *)(ptr)) = RR_BSWAP32(val) #define RR_GET32_BE_OFFSET(ptr, offset) \ RR_BSWAP32(*RR_U32_PTR_OFFSET(ptr, offset)) #define RR_PUT32_BE_OFFSET(ptr, val, offset) \ *RR_U32_PTR_OFFSET(ptr, offset) = RR_BSWAP32(val) #define RR_GET64_BE(ptr) RR_BSWAP64(*((U64 *)(ptr))) #define RR_PUT64_BE(ptr, val) *((U64 *)(ptr)) = RR_BSWAP64(val) #define RR_GET64_BE_OFFSET(ptr, offset) \ RR_BSWAP64(*RR_U64_PTR_OFFSET(ptr, offset)) #define RR_PUT64_BE_OFFSET(ptr, val, offset) \ *RR_U64_PTR_OFFSET(ptr, offset) = RR_BSWAP64(val) // end _MSC_VER #elif defined(__RADXENON__) // Xenon has built-in funcs for this unsigned short __loadshortbytereverse(int offset, const void *base); unsigned long __loadwordbytereverse(int offset, const void *base); void __storeshortbytereverse(unsigned short val, int offset, void *base); void __storewordbytereverse(unsigned int val, int offset, void *base); #define RR_GET16_LE(ptr) __loadshortbytereverse(0, ptr) #define RR_PUT16_LE(ptr, val) __storeshortbytereverse((U16)(val), 0, ptr) #define RR_GET16_LE_OFFSET(ptr, offset) __loadshortbytereverse(offset, ptr) #define RR_PUT16_LE_OFFSET(ptr, val, offset) \ __storeshortbytereverse((U16)(val), offset, ptr) #define RR_GET32_LE(ptr) __loadwordbytereverse(0, ptr) #define RR_PUT32_LE(ptr, val) __storewordbytereverse((U32)(val), 0, ptr) #define RR_GET32_LE_OFFSET(ptr, offset) __loadwordbytereverse(offset, ptr) #define RR_PUT32_LE_OFFSET(ptr, val, offset) \ __storewordbytereverse((U32)(val), offset, ptr) #define RR_GET64_LE(ptr) \ (((U64)RR_GET32_OFFSET_LE(ptr, 4) << 32) | RR_GET32_LE(ptr)) #define RR_PUT64_LE(ptr, val) \ RR_PUT32_LE(ptr, (U32)(val)), RR_PUT32_OFFSET_LE(ptr, (U32)((val) >> 32), 4) #elif defined(__RADPS3__) #include #define RR_GET16_LE(ptr) __lhbrx(ptr) #define RR_PUT16_LE(ptr, val) __sthbrx(ptr, (U16)(val)) #define RR_GET16_LE_OFFSET(ptr, offset) __lhbrx(RR_U16_PTR_OFFSET(ptr, offset)) #define RR_PUT16_LE_OFFSET(ptr, val, offset) \ __sthbrx(RR_U16_PTR_OFFSET(ptr, offset), (U16)(val)) #define RR_GET32_LE(ptr) __lwbrx(ptr) #define RR_PUT32_LE(ptr, val) __stwbrx(ptr, (U32)(val)) #define RR_GET64_LE(ptr) __ldbrx(ptr) #define RR_PUT64_LE(ptr, val) __stdbrx(ptr, (U32)(val)) #define RR_GET32_LE_OFFSET(ptr, offset) __lwbrx(RR_U32_PTR_OFFSET(ptr, offset)) #define RR_PUT32_LE_OFFSET(ptr, val, offset) \ __stwbrx(RR_U32_PTR_OFFSET(ptr, offset), (U32)(val)) #elif defined(__RADWII__) #define RR_GET16_LE(ptr) __lhbrx(ptr, 0) #define RR_PUT16_LE(ptr, val) __sthbrx((U16)(val), ptr, 0) #define RR_GET16_LE_OFFSET(ptr, offset) __lhbrx(ptr, offset) #define RR_PUT16_LE_OFFSET(ptr, val, offset) __sthbrx((U16)(val), ptr, offset) #define RR_GET32_LE(ptr) __lwbrx(ptr, 0) #define RR_PUT32_LE(ptr, val) __stwbrx((U32)(val), ptr, 0) #define RR_GET32_LE_OFFSET(ptr, offset) __lwbrx(ptr, offset) #define RR_PUT32_LE_OFFSET(ptr, val, offset) __stwbrx((U32)(val), ptr, offset) #elif defined(__RAD3DS__) #define RR_GET16_BE(ptr) __rev16(*(U16 *)(ptr)) #define RR_PUT16_BE(ptr, val) *(U16 *)(ptr) = __rev16(val) #define RR_GET16_BE_OFFSET(ptr, offset) __rev16(*RR_U16_PTR_OFFSET(ptr, offset)) #define RR_PUT16_BE_OFFSET(ptr, offset, val) \ *RR_U16_PTR_OFFSET(ptr, offset) = __rev16(val) #define RR_GET32_BE(ptr) __rev(*(U32 *)(ptr)) #define RR_PUT32_BE(ptr, val) *(U32 *)(ptr) = __rev(val) #define RR_GET32_BE_OFFSET(ptr, offset) __rev(*RR_U32_PTR_OFFSET(ptr, offset)) #define RR_PUT32_BE_OFFSET(ptr, offset, val) \ *RR_U32_PTR_OFFSET(ptr, offset) = __rev(val) #elif defined(__RADIPHONE__) // iPhone does not seem to have intrinsics for this, so use generic fallback! // Bswap is just here for use of implementing get/put // caller should use Get/Put , not bswap #define RR_BSWAP16(u16) ((U16)(((u16) >> 8) | ((u16) << 8))) #define RR_BSWAP32(u32) \ ((U32)(((u32) >> 24) | (((u32) << 8) & 0x00FF0000) | \ (((u32) >> 8) & 0x0000FF00) | ((u32) << 24))) #define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) #define RR_PUT16_BE(ptr, val) *((U16 *)(ptr)) = RR_BSWAP16(val) #define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) #define RR_PUT32_BE(ptr, val) *((U32 *)(ptr)) = RR_BSWAP32(val) #elif defined(__RADWIIU__) #include #define RR_GET16_LE(ptr) (*(__bytereversed U16 *)(ptr)) #define RR_PUT16_LE(ptr, val) *(__bytereversed U16 *)(ptr) = val #define RR_GET16_LE_OFFSET(ptr, offset) \ (*(__bytereversed U16 *)RR_U16_PTR_OFFSET(ptr, offset)) #define RR_PUT16_LE_OFFSET(ptr, val, offset) \ *(__bytereversed U16 *)RR_U16_PTR_OFFSET(ptr, offset) = val #define RR_GET32_LE(ptr) (*(__bytereversed U32 *)(ptr)) #define RR_PUT32_LE(ptr, val) *(__bytereversed U32 *)(ptr) = val #define RR_GET32_LE_OFFSET(ptr, offset) \ (*(__bytereversed U32 *)RR_U32_PTR_OFFSET(ptr, offset)) #define RR_PUT32_LE_OFFSET(ptr, val, offset) \ *(__bytereversed U32 *)RR_U32_PTR_OFFSET(ptr, offset) = val #define RR_GET64_LE(ptr) (*(__bytereversed U64 *)(ptr)) #define RR_PUT64_LE(ptr, val) *(__bytereversed U64 *)(ptr) = val #define RR_GET64_LE_OFFSET(ptr, offset) \ (*(__bytereversed U64 *)RR_U32_PTR_OFFSET(ptr, offset)) #define RR_PUT64_LE_OFFSET(ptr, val, offset) \ *(__bytereversed U64 *)RR_U32_PTR_OFFSET(ptr, offset) = val #elif defined(__RADWINRTAPI__) && defined(__RADARM__) #include #define RR_BSWAP16(u16) _arm_rev16(u16) #define RR_BSWAP32(u32) _arm_rev(u32) #define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) #define RR_PUT16_BE(ptr, val) *((U16 *)(ptr)) = RR_BSWAP16(val) #define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) #define RR_PUT32_BE(ptr, val) *((U32 *)(ptr)) = RR_BSWAP32(val) #elif defined(__RADPSP2__) // no rev16 exposed #define RR_BSWAP16(u16) ((U16)(((u16) >> 8) | ((u16) << 8))) #define RR_BSWAP32(u32) __builtin_rev(u32) #define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) #define RR_PUT16_BE(ptr, val) *((U16 *)(ptr)) = RR_BSWAP16(val) #define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) #define RR_PUT32_BE(ptr, val) *((U32 *)(ptr)) = RR_BSWAP32(val) #else // other platforms ? // fall back : // Bswap is just here for use of implementing get/put // caller should use Get/Put , not bswap #define RR_BSWAP16(u16) ((U16)(((u16) >> 8) | ((u16) << 8))) #define RR_BSWAP32(u32) \ ((U32)(((u32) >> 24) | (((u32) << 8) & 0x00FF0000) | \ (((u32) >> 8) & 0x0000FF00) | ((u32) << 24))) #define RR_BSWAP64(u64) \ (((U64)RR_BSWAP32((U32)(u64)) << 32) | (U64)RR_BSWAP32((U32)((u64) >> 32))) #ifdef __RADLITTLEENDIAN__ // comment out fallbacks so users will get errors // #define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) // #define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) // #define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) // #define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) #else // comment out fallbacks so users will get errors // #define RR_GET16_LE(ptr) RR_BSWAP16(*((U16 *)(ptr))) // #define RR_PUT16_LE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) // #define RR_GET32_LE(ptr) RR_BSWAP32(*((U32 *)(ptr))) // #define RR_PUT32_LE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) #endif #endif //=================================================================== // @@ TEMP : Aliases for old names : remove me when possible : #define RR_GET32_OFFSET_LE RR_GET32_LE_OFFSET #define RR_GET32_OFFSET_BE RR_GET32_BE_OFFSET #define RR_PUT32_OFFSET_LE RR_PUT32_LE_OFFSET #define RR_PUT32_OFFSET_BE RR_PUT32_BE_OFFSET #define RR_GET16_OFFSET_LE RR_GET16_LE_OFFSET #define RR_GET16_OFFSET_BE RR_GET16_BE_OFFSET #define RR_PUT16_OFFSET_LE RR_PUT16_LE_OFFSET #define RR_PUT16_OFFSET_BE RR_PUT16_BE_OFFSET //=================================================================== // UNALIGNED VERSIONS : #if defined(__RADX86__) || \ defined(__RADPPC__) // platforms where unaligned is fast : #define RR_GET32_BE_UNALIGNED(ptr) RR_GET32_BE(ptr) #define RR_GET32_BE_UNALIGNED_OFFSET(ptr, offset) \ RR_GET32_BE_OFFSET(ptr, offset) #define RR_GET16_BE_UNALIGNED(ptr) RR_GET16_BE(ptr) #define RR_GET16_BE_UNALIGNED_OFFSET(ptr, offset) \ RR_GET16_BE_OFFSET(ptr, offset) #define RR_GET32_LE_UNALIGNED(ptr) RR_GET32_LE(ptr) #define RR_GET32_LE_UNALIGNED_OFFSET(ptr, offset) \ RR_GET32_LE_OFFSET(ptr, offset) #define RR_GET16_LE_UNALIGNED(ptr) RR_GET16_LE(ptr) #define RR_GET16_LE_UNALIGNED_OFFSET(ptr, offset) \ RR_GET16_LE_OFFSET(ptr, offset) #elif defined(__RAD3DS__) // arm has a "__packed" qualifier to tell the compiler to do unaligned accesses #define RR_U16_PTR_OFFSET_UNALIGNED(ptr, offset) \ ((__packed U16 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) #define RR_U32_PTR_OFFSET_UNALIGNED(ptr, offset) \ ((__packed U32 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) #define RR_GET32_BE_UNALIGNED(ptr) __rev(*RR_U32_PTR_OFFSET_UNALIGNED(ptr, 0)) #define RR_GET32_BE_UNALIGNED_OFFSET(ptr, offset) \ __rev(*RR_U32_PTR_OFFSET_UNALIGNED(ptr, offset)) #define RR_GET16_BE_UNALIGNED(ptr) __rev16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr, 0)) #define RR_GET16_BE_UNALIGNED_OFFSET(ptr, offset) \ __rev16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr, offset)) #define RR_GET32_LE_UNALIGNED(ptr) *RR_U32_PTR_OFFSET_UNALIGNED(ptr, 0) #define RR_GET32_LE_UNALIGNED_OFFSET(ptr, offset) \ *RR_U32_PTR_OFFSET_UNALIGNED(ptr, offset) #define RR_GET16_LE_UNALIGNED(ptr) *RR_U16_PTR_OFFSET_UNALIGNED(ptr, 0) #define RR_GET16_LE_UNALIGNED_OFFSET(ptr, offset) \ *RR_U16_PTR_OFFSET_UNALIGNED(ptr, offset) #elif defined(__RADPSP2__) #define RR_U16_PTR_OFFSET_UNALIGNED(ptr, offset) \ ((U16 __unaligned * RR_GET_PTR_POST)((char *)(ptr) + (offset))) #define RR_U32_PTR_OFFSET_UNALIGNED(ptr, offset) \ ((U32 __unaligned * RR_GET_PTR_POST)((char *)(ptr) + (offset))) #define RR_GET32_BE_UNALIGNED(ptr) \ RR_BSWAP32(*RR_U32_PTR_OFFSET_UNALIGNED(ptr, 0)) #define RR_GET32_BE_UNALIGNED_OFFSET(ptr, offset) \ RR_BSWAP32(*RR_U32_PTR_OFFSET_UNALIGNED(ptr, offset)) #define RR_GET16_BE_UNALIGNED(ptr) \ RR_BSWAP16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr, 0)) #define RR_GET16_BE_UNALIGNED_OFFSET(ptr, offset) \ RR_BSWAP16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr, offset)) #define RR_GET32_LE_UNALIGNED(ptr) *RR_U32_PTR_OFFSET_UNALIGNED(ptr, 0) #define RR_GET32_LE_UNALIGNED_OFFSET(ptr, offset) \ *RR_U32_PTR_OFFSET_UNALIGNED(ptr, offset) #define RR_GET16_LE_UNALIGNED(ptr) *RR_U16_PTR_OFFSET_UNALIGNED(ptr, 0) #define RR_GET16_LE_UNALIGNED_OFFSET(ptr, offset) \ *RR_U16_PTR_OFFSET_UNALIGNED(ptr, offset) #else // Unaligned via bytes : #define RR_GET32_BE_UNALIGNED(ptr) \ (((U32)(((const U8 *RR_GET_PTR_POST)(ptr)))[0] << 24) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)))[1] << 16) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)))[2] << 8) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)))[3] << 0)) #define RR_GET32_BE_UNALIGNED_OFFSET(ptr, offset) \ (((U32)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[0] << 24) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[1] << 16) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[2] << 8) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[3] << 0)) #define RR_GET16_BE_UNALIGNED(ptr) \ (((U16)(((const U8 *RR_GET_PTR_POST)(ptr)))[0] << 8) | \ ((U16)(((const U8 *RR_GET_PTR_POST)(ptr)))[1] << 0)) #define RR_GET16_BE_UNALIGNED_OFFSET(ptr, offset) \ (((U16)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[0] << 8) | \ ((U16)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[1] << 0)) #define RR_GET32_LE_UNALIGNED(ptr) \ (((U32)(((const U8 *RR_GET_PTR_POST)(ptr)))[3] << 24) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)))[2] << 16) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)))[1] << 8) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)))[0] << 0)) #define RR_GET32_LE_UNALIGNED_OFFSET(ptr, offset) \ (((U32)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[3] << 24) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[2] << 16) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[1] << 8) | \ ((U32)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[0] << 0)) #define RR_GET16_LE_UNALIGNED(ptr) \ (((U16)(((const U8 *RR_GET_PTR_POST)(ptr)))[1] << 8) | \ ((U16)(((const U8 *RR_GET_PTR_POST)(ptr)))[0] << 0)) #define RR_GET16_LE_UNALIGNED_OFFSET(ptr, offset) \ (((U16)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[1] << 8) | \ ((U16)(((const U8 *RR_GET_PTR_POST)(ptr)) + (offset))[0] << 0)) #endif //=================================================================== // RR_ROTL32 : 32-bit rotate // #ifdef _MSC_VER unsigned long __cdecl _lrotl(unsigned long, int); #pragma intrinsic(_lrotl) #define RR_ROTL32(x, k) _lrotl((unsigned long)(x), (int)(k)) #elif defined(__RADCELL__) || defined(__RADLINUX__) || defined(__RADWII__) || \ defined(__RADMACAPI__) || defined(__RADWIIU__) || defined(__RADPS4__) || \ defined(__RADPSP2__) // Compiler turns this into rotate correctly : #define RR_ROTL32(u32, num) (((u32) << (num)) | ((u32) >> (32 - (num)))) #elif defined(__RAD3DS__) #define RR_ROTL32(u32, num) __ror(u32, (-(num)) & 31) #else // comment out fallbacks so users will get errors // fallback implementation using shift and or : // #define RR_ROTL32(u32,num) ( ( (u32) << (num) ) | ( (u32) >> (32 - (num))) ) #endif //=================================================================== // RR_ROTL64 : 64-bit rotate #if (defined(_MSC_VER) && _MSC_VER >= 1300) unsigned int64_t __cdecl _rotl64(unsigned int64_t _Val, int _Shift); #pragma intrinsic(_rotl64) #define RR_ROTL64(x, k) _rotl64((unsigned int64_t)(x), (int)(k)) #elif defined(__RADCELL__) // PS3 GCC turns this into rotate correctly : #define RR_ROTL64(u64, num) (((u64) << (num)) | ((u64) >> (64 - (num)))) #elif defined(__RADLINUX__) || defined(__RADMACAPI__) // APTODO: Just to compile linux. Should we be doing better than this? If not, // combine with above. #define RR_ROTL64(u64, num) (((u64) << (num)) | ((u64) >> (64 - (num)))) #else // comment out fallbacks so users will get errors // fallback implementation using shift and or : // #define RR_ROTL64(u64,num) ( ( (u64) << (num) ) | ( (u64) >> (64 - (num))) ) #endif //=================================================================== RADDEFEND //=================================================================== // RR_COMPILER_ASSERT #if defined(__cplusplus) && !defined(RR_COMPILER_ASSERT) #if defined(_MSC_VER) && (_MSC_VER >= 1400) // better version of COMPILER_ASSERT using boost technique template struct RR_COMPILER_ASSERT_FAILURE; template <> struct RR_COMPILER_ASSERT_FAILURE<1> { enum { value = 1 }; }; template struct rr_compiler_assert_test {}; // __LINE__ macro broken when -ZI is used see Q199057 #define RR_COMPILER_ASSERT(B) \ typedef rr_compiler_assert_test)> \ rr_compiler_assert_typedef_ #endif #endif #ifndef RR_COMPILER_ASSERT // this happens at declaration time, so if it's inside a function in a C file, // drop {} around it #define RR_COMPILER_ASSERT(exp) \ typedef char RR_STRING_JOIN(_dummy_array, __LINE__)[(exp) ? 1 : -1] #endif //=================================================================== // some error checks : RR_COMPILER_ASSERT(sizeof(RAD_UINTa) == sizeof(RR_STRING_JOIN(RAD_U, RAD_PTRBITS))); RR_COMPILER_ASSERT(sizeof(RAD_UINTa) == RAD_PTRBYTES); RR_COMPILER_ASSERT(RAD_TWOPTRBYTES == 2 * RAD_PTRBYTES); //=================================================================== #endif // __RADRES__ // include "testconstant.inl" // uncomment and include to test statement // constants #endif // __RADRR_COREH__