summaryrefslogtreecommitdiff
path: root/external/vpc/public/tier0/platform.h
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /external/vpc/public/tier0/platform.h
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'external/vpc/public/tier0/platform.h')
-rw-r--r--external/vpc/public/tier0/platform.h2032
1 files changed, 2032 insertions, 0 deletions
diff --git a/external/vpc/public/tier0/platform.h b/external/vpc/public/tier0/platform.h
new file mode 100644
index 0000000..4dad5df
--- /dev/null
+++ b/external/vpc/public/tier0/platform.h
@@ -0,0 +1,2032 @@
+//===== Copyright 1997-2005, Valve Corporation, All rights reserved. ======//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//===========================================================================//
+
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+
+#ifdef SN_TARGET_PS3
+
+#define _PS3 1
+#define COMPILER_PS3 1
+#define PLATFORM_PS3 1
+
+// There are 2 compilers for the PS3: GCC and the SN Systems compiler.
+// They are mostly similar, but in a few places we need to distinguish between the two.
+#if defined( __SNC__ )
+#define COMPILER_SNC 1
+#elif defined( __GCC__ )
+#define COMPILER_GCC 1
+#else
+#error "Unrecognized PS3 compiler; either __SNC__ or __GCC__ must be defined"
+#endif
+
+#endif // SN_TARGET_PS3
+
+#ifdef __GCC__
+#define COMPILER_GCC 1
+#endif
+
+#if defined( _X360 ) || defined( _PS3 )
+#define PLATFORM_PPC 1
+#endif
+
+
+#ifdef COMPILER_MSVC
+#pragma once
+#endif
+
+#if defined (_PS3)
+ #include <ppu_intrinsics.h>
+
+ // We want to force the assert to be redefined, because the STD assert might have been
+ // included and redefined. ps3_assert.h will do a check for assert being redefined.
+ // #include "ps3/ps3_assert.h"
+ #ifndef COMPILER_PS3
+ #error "for PS3, VPC must define COMPILER_PS3 macro just like it does for COMPILER_MSVCX360 macro"
+ #endif
+ #if !defined( COMPILER_SNC ) && !defined( COMPILER_GCC )
+ #error "for PS3, VPC must define COMPILER_SNC or COMPILER_GCC macro, depending on the target compiler, just like it does for COMPILER_MSVCX360 macro"
+ #endif
+
+#elif defined( _X360 )
+ #define NO_STEAM
+ #define NO_VOICE
+ // for the 360, the ppc platform and the rtos are tightly coupled
+ // setup the 360 environment here !once! for much less leaf module include wackiness
+ // these are critical order and purposely appear *before* anything else
+ #define _XBOX
+ #include <xaudio2.h>
+ #include <xbdm.h>
+ #include <xgraphics.h>
+ #include <xui.h>
+ #include <pmcpbsetup.h>
+ #include <xmahardwareabstraction.h>
+ #undef _XBOX
+
+#endif
+
+#include "wchartypes.h"
+#include "tier0/valve_off.h"
+
+#ifdef _PS3
+
+ #include "ps3/ps3_platform.h"
+
+ #define NO_STEAM_GAMECOORDINATOR
+
+#else
+
+ #include <malloc.h>
+ #include <memory.h>
+ #include <limits.h>
+ #include <float.h>
+ #include <stdlib.h>
+ #include <string.h>
+#ifdef OSX
+ #include <signal.h>
+#endif
+
+#endif
+
+// This macro
+#if defined( _PS3 ) && defined ( COMPILER_SNC )
+
+// There are known bugs in the PS3 optimizer. The following macros allow us to lower optimization for a subset of a file
+// If you run into build problems with optimization on, try turning off optimization for the selected file. If that
+// fixes the problem, use process of elimination and the below macros to find the bare minimum that needs to be
+// unoptimized and report the compiler issue to Sony as well.
+//
+// The correlation between optimization levels and numbers passed to the _Pragma xopt and postopt calls is as follows:
+// See: Control-group reference tables / -Xshow
+// .... xopt
+// -O1 0
+// -O2 5
+// -O3 5
+//
+// These macros MUST be used in pairs - Otherwise, the compiler will barf 'At end of source: error 67: expected a "}"'
+
+// xopt disables some of the miscellaneous optimizations
+#if __option(xopt)
+#define SN_OPT_DISABLE extern "C++" { _Pragma("control %push xopt=0")
+#define SN_OPT_ENABLE _Pragma("control %pop xopt") }
+#else // !__option(xopt)
+#define SN_OPT_DISABLE
+#define SN_OPT_ENABLE
+#endif // !__option(xopt)
+
+// postopt disables the main optimizer
+#if __option(postopt) > 0
+#define SN_MAIN_OPT_DISABLE extern "C++" { _Pragma("control %push postopt=0")
+#define SN_MAIN_OPT_ENABLE _Pragma("control %pop postopt") }
+#else // !__option(postopt) > 0
+#define SN_MAIN_OPT_DISABLE
+#define SN_MAIN_OPT_ENABLE
+#endif // !__option(postopt) > 0
+
+#else // ! ( _PS3 && COMPILER_SNC )
+#define SN_OPT_DISABLE
+#define SN_OPT_ENABLE
+#define SN_MAIN_OPT_DISABLE
+#define SN_MAIN_OPT_ENABLE
+#endif // ! ( _PS3 && COMPILER_SNC )
+
+#ifdef __cplusplus
+#if defined( COMPILER_GCC ) || defined( COMPILER_PS3 )
+ #include <new>
+#else
+ #include <new.h>
+#endif
+#endif
+
+//-----------------------------------------------------------------------------
+// Old-school defines we don't want to use moving forward
+//-----------------------------------------------------------------------------
+#if CROSS_PLATFORM_VERSION < 1
+
+// feature enables
+#define NEW_SOFTWARE_LIGHTING
+#if !defined( _X360 )
+#define SUPPORT_PACKED_STORE
+#endif
+
+#if defined( BINK_VIDEO ) && ( defined( _X360 ) || defined( _PS3 ) )
+#define BINK_ENABLED_FOR_CONSOLE
+#endif
+
+#if !defined( PORTAL2 )
+//#define PORTAL2
+#endif
+
+// C functions for external declarations that call the appropriate C++ methods
+#ifndef EXPORT
+ #ifdef _WIN32
+ #define EXPORT _declspec( dllexport )
+ #else
+ #define EXPORT /* */
+ #endif
+#endif
+
+#endif // CROSS_PLATFORM_VERSION < 1
+
+#if defined(_STATIC_LINKED)
+#include "staticlink/system.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// NOTE: All compiler defines are set up in the base VPC scripts
+// COMPILER_MSVC, COMPILER_MSVC32, COMPILER_MSVC64, COMPILER_MSVCX360
+// COMPILER_GCC
+// The rationale for this is that we need COMPILER_MSVC for the pragma blocks
+// #pragma once that occur at the top of all header files, therefore we can't
+// place the defines for these in here.
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Set up platform defines.
+//-----------------------------------------------------------------------------
+#ifdef _WIN32
+ #define IsPlatformLinux() 0
+ #define IsPlatformPosix() 0
+ #define IsPlatformOSX() 0
+ #define IsOSXOpenGL() 0
+ #define IsPlatformPS3() 0
+ #define IsPlatformPS3_PPU() 0
+ #define IsPlatformPS3_SPU() 0
+ #define PLATFORM_WINDOWS 1
+ #define PLATFORM_OPENGL 0
+
+ #ifndef _X360
+ #define IsPlatformX360() 0
+ #define IsPlatformWindowsPC() 1
+ #define PLATFORM_WINDOWS_PC 1
+
+ #ifdef _WIN64
+ #define IsPlatformWindowsPC64() 1
+ #define IsPlatformWindowsPC32() 0
+ #define PLATFORM_WINDOWS_PC64 1
+ #else
+ #define IsPlatformWindowsPC64() 0
+ #define IsPlatformWindowsPC32() 1
+ #define PLATFORM_WINDOWS_PC32 1
+ #endif
+
+ #else // _X360
+
+ #define IsPlatformWindowsPC() 0
+ #define IsPlatformWindowsPC64() 0
+ #define IsPlatformWindowsPC32() 0
+ #define IsPlatformX360() 1
+ #define PLATFORM_X360 1
+
+ #endif // _X360
+#elif defined(_PS3)
+
+
+#define IsPlatformX360() 0
+#define IsPlatformPS3() 1
+#ifdef SPU
+#define IsPlatformPS3_PPU() 0
+#define IsPlatformPS3_SPU() 1
+#else
+#define IsPlatformPS3_PPU() 1
+#define IsPlatformPS3_SPU() 0
+#endif
+#define IsPlatformWindowsPC() 0
+#define IsPlatformWindowsPC64() 0
+#define IsPlatformWindowsPC32() 0
+#define IsPlatformPosix() 1
+#define PLATFORM_POSIX 1
+#define PLATFORM_OPENGL 0
+
+#define IsPlatformLinux() 0
+#define IsPlatformOSX() 0
+#define IsOSXOpenGL() 0
+
+
+#elif defined(POSIX)
+ #define IsPlatformX360() 0
+ #define IsPlatformPS3() 0
+ #define IsPlatformPS3_PPU() 0
+ #define IsPlatformPS3_SPU() 0
+ #define IsPlatformWindowsPC() 0
+ #define IsPlatformWindowsPC64() 0
+ #define IsPlatformWindowsPC32() 0
+ #define IsPlatformPosix() 1
+ #define PLATFORM_POSIX 1
+
+ #if defined( LINUX ) && !defined( OSX ) // for havok we define both symbols, so don't let the osx build wander down here
+ #define IsPlatformLinux() 1
+ #define IsPlatformOSX() 0
+ #define IsOSXOpenGL() 0
+ #define PLATFORM_OPENGL 0
+ #define PLATFORM_LINUX 1
+ #elif defined ( OSX )
+ #define IsPlatformLinux() 0
+ #define IsPlatformOSX() 1
+ #define IsOSXOpenGL() 1
+ #define PLATFORM_OSX 1
+ #define PLATFORM_OPENGL 1
+ #else
+ #define IsPlatformLinux() 0
+ #define IsPlatformOSX() 0
+ #define IsOSXOpenGL() 0
+ #define PLATFORM_OPENGL 0
+ #endif
+
+#else
+ #error
+#endif
+
+// IsXXXX platform pseudo-functions
+#if ( defined( PLATFORM_WINDOWS ) && ( PLATFORM_WINDOWS ) )
+#define IsPlatformWindows() 1
+#else
+#define IsPlatformWindows() 0
+#endif
+
+#if ( defined( PLATFORM_OPENGL ) && PLATFORM_OPENGL )
+#define IsOpenGL() 1
+#else
+#define IsOpenGL() 0
+#endif
+
+
+
+#ifndef _PS3
+//#include <malloc.h>
+//#include <new.h>
+#else
+#include <stdlib.h> // For malloc()
+#include <alloca.h> // for alloca()
+#define _alloca alloca
+ #ifdef __cplusplus
+ #include <new>
+ #endif
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Old-school defines we're going to support since much code uses them
+//-----------------------------------------------------------------------------
+#if CROSS_PLATFORM_VERSION < 2
+
+#define IsLinux() IsPlatformLinux()
+#define IsOSX() IsPlatformOSX()
+#define IsPosix() IsPlatformPosix()
+#define IsX360() IsPlatformX360()
+#define IsPS3() IsPlatformPS3()
+
+// Setup platform defines.
+#ifdef COMPILER_MSVC
+#define MSVC 1
+#endif
+
+#ifdef COMPILER_GCC
+#define GNUC 1
+#endif
+
+#if defined( _WIN32 )
+#define _WINDOWS 1
+#endif
+
+#ifdef PLATFORM_WINDOWS_PC
+#define IS_WINDOWS_PC 1
+#endif
+
+#endif // CROSS_PLATFORM_VERSION < 2
+
+// VXConsole is enabled for...
+#if defined(_X360) || defined(_PS3)
+#define USE_VXCONSOLE 1
+#define HasVxConsole() 1
+#else
+#define HasVxConsole() 0
+#endif
+
+//-----------------------------------------------------------------------------
+// Set up platform type defines.
+//-----------------------------------------------------------------------------
+#if defined( PLATFORM_X360 ) || defined( _PS3 )
+ #ifndef _GAMECONSOLE
+ #define _GAMECONSOLE
+ #endif
+ #define IsPC() 0
+ #define IsGameConsole() 1
+#else
+ #define IsPC() 1
+ #define IsGameConsole() 0
+#endif
+
+
+
+//-----------------------------------------------------------------------------
+// Set up build configuration defines.
+//-----------------------------------------------------------------------------
+#ifdef _CERT
+#define IsCert() 1
+#else
+#define IsCert() 0
+#endif
+
+#ifdef _DEBUG
+#define IsRelease() 0
+#define IsDebug() 1
+#else
+#define IsRelease() 1
+#define IsDebug() 0
+#endif
+
+#ifdef _RETAIL
+#define IsRetail() 1
+#else
+#define IsRetail() 0
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Portable data types
+//-----------------------------------------------------------------------------
+typedef unsigned char uint8;
+typedef signed char int8;
+
+#if defined( COMPILER_MSVC )
+
+ typedef __int16 int16;
+ typedef unsigned __int16 uint16;
+ typedef __int32 int32;
+ typedef unsigned __int32 uint32;
+ typedef __int64 int64;
+ typedef unsigned __int64 uint64;
+
+ // intp is an integer that can accomodate a pointer
+ // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *)
+ typedef intptr_t intp;
+ typedef uintptr_t uintp;
+
+ #if defined( COMPILER_MSVCX360 )
+ #ifdef __m128
+ #undef __m128
+ #endif
+ #define __m128 __vector4
+ #endif
+
+#else // !COMPILER_MSVC
+
+ typedef short int16;
+ typedef unsigned short uint16;
+ typedef int int32;
+ typedef unsigned int uint32;
+ typedef long long int64;
+ typedef unsigned long long uint64;
+ #ifdef PLATFORM_64BITS
+ typedef long long intp;
+ typedef unsigned long long uintp;
+ #else
+ typedef int intp;
+ typedef unsigned int uintp;
+ #endif
+ typedef void *HWND;
+#endif // else COMPILER_MSVC
+
+#if defined(_PS3) && !defined(NO_SIMD)
+typedef union __attribute__ ((aligned (16)))
+{
+ float m128_f32[4];
+} l_m128;
+
+typedef __vector float __vector4;
+typedef __vector4 __m128;
+
+const __m128 VMX_ZERO=(vector float)(0.0f);
+const __m128 VMX_ONE_HALF=(vector float)(0.5f);
+const __m128 VMX_ONE=(vector float)(1.0f);
+
+// Syntaxic sugar for multiply
+inline __attribute__ ((always_inline)) __m128 __vec_mul(const __m128 a, const __m128 b)
+{
+ return vec_madd(a,b,VMX_ZERO);
+}
+
+// Refined reciprocal function
+inline __attribute__ ((always_inline)) __m128 __vec_rec(const __m128 a)
+{
+ //Get the reciprocal estimate
+ vector float estimate = vec_re( a );
+
+ //One round of Newton-Raphson refinement
+ return vec_madd( vec_nmsub( estimate, a, VMX_ONE ), estimate, estimate );
+}
+
+// refined reciprocal square root
+inline __attribute__ ((always_inline)) __m128 __vec_rsqrt(const __m128 a)
+{
+ //Get the square root reciprocal estimate
+ __m128 estimate = vec_rsqrte( a );
+
+ //One round of Newton-Raphson refinement
+ __m128 estimateSquared = __vec_mul( estimate, estimate);
+ __m128 halfEstimate = __vec_mul( estimate, VMX_ONE_HALF);
+ return vec_madd( vec_nmsub( a, estimateSquared, VMX_ONE ), halfEstimate, estimate );
+}
+
+// refined square root
+inline __attribute__ ((always_inline)) __m128 __vec_sqrt(const __m128 a)
+{
+ return __vec_mul( a, __vec_rsqrt( a ));
+}
+
+// estimate square root
+inline __attribute__ ((always_inline)) __m128 __vec_sqrtest(const __m128 a)
+{
+ return __vec_mul( a, vec_rsqrte( a ));
+}
+
+// Syntaxic sugar for multiply
+inline __attribute__ ((always_inline)) __m128 __vec_div(const __m128 a, const __m128 b)
+{
+ return __vec_mul( a, __vec_rec( b ));
+}
+
+// load an unaligned array of float in a vector of floats
+inline __attribute__ ((always_inline)) __m128 __vec_ld_unaligned(const float* in)
+{
+ return vec_perm(vec_ld(0,in),
+ vec_ld(sizeof(__m128),in),
+ vec_lvsl( 0, in ));
+}
+
+// load an unaligned array of 3 floats in a vector of floats, last member being 0.
+inline __attribute__ ((always_inline)) __m128 __vec_ld_unaligned3(const float* in)
+{
+ return vec_and(__vec_ld_unaligned(in),(__m128)(vector unsigned int)(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF ,0));
+}
+
+// stores a vector of floats in an unaligned array of float
+inline __attribute__ ((always_inline)) void __vec_st_unaligned(__m128 in, float* out)
+{
+ __m128 temp0 = vec_ld(0,out);
+ __m128 temp1 = vec_ld(16,out);
+ vector unsigned char align = vec_lvsr(0,out);
+ vector unsigned char mask = vec_perm ((vector unsigned char)(0), (vector unsigned char)(0xFF), align);
+
+ in = vec_perm ( in, in, align);
+ temp0 = vec_sel ( temp0, in, (vector bool)mask);
+ temp1 = vec_sel ( in, temp1, (vector bool)mask);
+ vec_st ( temp0, 0, out);
+ vec_st ( temp1, 16, out);
+}
+
+// stores x,y,z from a vector of floats in an unaligned array of 3 floats
+inline __attribute__ ((always_inline)) void __vec_st_unaligned3(__m128 in, float* out)
+{
+ __m128 temp0 = vec_ld(0,out);
+ __m128 temp1 = vec_ld(16,out);
+ vector unsigned char align = vec_lvsr(0,out);
+ vector unsigned char mask = vec_perm ((vector unsigned char)(0),
+ (vector unsigned char)(0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0,0,0,0),
+ align);
+
+ in = vec_perm ( in, in, align);
+ temp0 = vec_sel ( temp0, in, (vector bool)mask);
+ temp1 = vec_sel ( in, temp1, (vector bool)mask);
+ vec_st ( temp0, 0, out);
+ vec_st ( temp1, 16, out);
+}
+
+#endif // defined(NO_SIMD)
+
+
+typedef float float32;
+typedef double float64;
+
+// for when we don't care about how many bits we use
+typedef unsigned int uint;
+
+#ifdef PLATFORM_POSIX
+#ifndef _PS3
+typedef unsigned int DWORD;
+typedef unsigned int *LPDWORD;
+#endif
+typedef unsigned short WORD;
+typedef void * HINSTANCE;
+#define _MAX_PATH PATH_MAX
+#endif
+
+// MSVC CRT uses 0x7fff while gcc uses MAX_INT, leading to mismatches between platforms
+// As a result, we pick the least common denominator here. This should be used anywhere
+// you might typically want to use RAND_MAX
+#define VALVE_RAND_MAX 0x7fff
+// Maximum and minimum representable values
+#ifndef PLATFORM_OSX
+
+#define INT8_MAX SCHAR_MAX
+#define INT16_MAX SHRT_MAX
+#define INT32_MAX LONG_MAX
+#define INT64_MAX (((int64)~0) >> 1)
+
+#define INT8_MIN SCHAR_MIN
+#define INT16_MIN SHRT_MIN
+#define INT32_MIN LONG_MIN
+#define INT64_MIN (((int64)1) << 63)
+
+#define UINT8_MAX ((uint8)~0)
+#define UINT16_MAX ((uint16)~0)
+#define UINT32_MAX ((uint32)~0)
+#define UINT64_MAX ((uint64)~0)
+
+#define UINT8_MIN 0
+#define UINT16_MIN 0
+#define UINT32_MIN 0
+#define UINT64_MIN 0
+
+#endif // PLATFORM_OSX
+
+#ifndef UINT_MIN
+#define UINT_MIN UINT32_MIN
+#endif
+
+#define FLOAT32_MAX FLT_MAX
+#define FLOAT64_MAX DBL_MAX
+
+#ifdef GNUC
+#undef offsetof
+// Note: can't use builtin offsetof because many use cases (esp. in templates) wouldn't compile due to restrictions on the builtin offsetof
+//#define offsetof( type, var ) __builtin_offsetof( type, var )
+#define offsetof(s,m) ( (size_t)&(((s *)0x1000000)->m) - 0x1000000u )
+#else
+#include <stddef.h>
+#undef offsetof
+#define offsetof(s,m) (size_t)&(((s *)0)->m)
+#endif
+
+
+#define FLOAT32_MIN FLT_MIN
+#define FLOAT64_MIN DBL_MIN
+
+//-----------------------------------------------------------------------------
+// Long is evil because it's treated differently by different compilers
+// Preventing its use is nasty however. This #define, which should be
+// turned on in individual VPC files, causes you to include tier0/valve_off.h
+// before standard C + windows headers, and include tier0/valve_on.h after
+// standard C + windows headers. So, there's some painful overhead to disabling long
+//-----------------------------------------------------------------------------
+#ifdef DISALLOW_USE_OF_LONG
+ #define long long_is_the_devil_stop_using_it_use_int32_or_int64
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Various compiler-specific keywords
+//-----------------------------------------------------------------------------
+#ifdef COMPILER_MSVC
+
+ #ifdef FORCEINLINE
+ #undef FORCEINLINE
+ #endif
+ #define STDCALL __stdcall
+ #ifndef FASTCALL
+ #define FASTCALL __fastcall
+ #endif
+ #define FORCEINLINE __forceinline
+ #define FORCEINLINE_TEMPLATE __forceinline
+ #define NULLTERMINATED __nullterminated
+
+ // This can be used to ensure the size of pointers to members when declaring
+ // a pointer type for a class that has only been forward declared
+ #define SINGLE_INHERITANCE __single_inheritance
+ #define MULTIPLE_INHERITANCE __multiple_inheritance
+ #define EXPLICIT explicit
+ #define NO_VTABLE __declspec( novtable )
+
+ // gcc doesn't allow storage specifiers on explicit template instatiation, but visual studio needs them to avoid link errors.
+ #define TEMPLATE_STATIC static
+
+ // Used for dll exporting and importing
+ #define DLL_EXPORT extern "C" __declspec( dllexport )
+ #define DLL_IMPORT extern "C" __declspec( dllimport )
+
+ // Can't use extern "C" when DLL exporting a class
+ #define DLL_CLASS_EXPORT __declspec( dllexport )
+ #define DLL_CLASS_IMPORT __declspec( dllimport )
+
+ // Can't use extern "C" when DLL exporting a global
+ #define DLL_GLOBAL_EXPORT extern __declspec( dllexport )
+ #define DLL_GLOBAL_IMPORT extern __declspec( dllimport )
+
+ // Pass hints to the compiler to prevent it from generating unnessecary / stupid code
+ // in certain situations. Several compilers other than MSVC also have an equivilent
+ // construct.
+ //
+ // Essentially the 'Hint' is that the condition specified is assumed to be true at
+ // that point in the compilation. If '0' is passed, then the compiler assumes that
+ // any subsequent code in the same 'basic block' is unreachable, and thus usually
+ // removed.
+ #define HINT(THE_HINT) __assume((THE_HINT))
+
+ // decls for aligning data
+ #define DECL_ALIGN(x) __declspec( align( x ) )
+
+ // GCC had a few areas where it didn't construct objects in the same order
+ // that Windows does. So when CVProfile::CVProfile() would access g_pMemAlloc,
+ // it would crash because the allocator wasn't initalized yet.
+ #define CONSTRUCT_EARLY
+
+ #define SELECTANY __declspec(selectany)
+
+ #define RESTRICT __restrict
+ #define RESTRICT_FUNC __declspec(restrict)
+ #define FMTFUNCTION( a, b )
+ #define NOINLINE
+
+#if !defined( NO_THREAD_LOCAL )
+ #define DECL_THREAD_LOCAL __declspec(thread)
+#endif
+
+ #define DISABLE_VC_WARNING( x ) __pragma(warning(disable:4310) )
+ #define DEFAULT_VC_WARNING( x ) __pragma(warning(default:4310) )
+
+
+#elif defined ( COMPILER_GCC ) || defined( COMPILER_SNC )
+
+ #if defined( COMPILER_SNC )
+ #define STDCALL
+ #define __stdcall
+ #elif (CROSS_PLATFORM_VERSION >= 1) && !defined( PLATFORM_64BITS ) && !defined( COMPILER_PS3 )
+ #define STDCALL __attribute__ ((__stdcall__))
+ #else
+ #define STDCALL
+ #define __stdcall __attribute__ ((__stdcall__))
+ #endif
+
+ #define FASTCALL
+ #ifdef _LINUX_DEBUGGABLE
+ #define FORCEINLINE
+ #else
+ #ifdef _PS3
+ // [IESTYN 7/29/2010] As of SDK 3.4.0, this causes bad code generation in NET_Tick::ReadFromBuffer in netmessages.cpp,
+ // which caused (seeming) random network packet corruption. It probably causes other bugs too.
+ #define FORCEINLINE inline /* __attribute__ ((always_inline)) */
+ #else
+ #define FORCEINLINE inline __attribute__ ((always_inline))
+ #endif
+ #endif
+
+ // GCC 3.4.1 has a bug in supporting forced inline of templated functions
+ // this macro lets us not force inlining in that case
+ #define FORCEINLINE_TEMPLATE inline
+ #define SINGLE_INHERITANCE
+ #define MULTIPLE_INHERITANCE
+ #define EXPLICIT
+ #define NO_VTABLE
+
+ #define NULLTERMINATED
+
+#if defined( COMPILER_SNC )
+ #define TEMPLATE_STATIC static
+#else
+ #define TEMPLATE_STATIC
+#endif
+
+ // Used for dll exporting and importing
+ #ifdef COMPILER_SNC
+ #define DLL_DECLARATION_DEFAULT_VISIBILITY
+ #else
+ #define DLL_DECLARATION_DEFAULT_VISIBILITY __attribute__ ((visibility("default")))
+ #endif
+ #define DLL_EXPORT extern "C" DLL_DECLARATION_DEFAULT_VISIBILITY
+ #define DLL_IMPORT extern "C"
+
+ // Can't use extern "C" when DLL exporting a class
+#ifndef _PS3
+ #define __stdcall __attribute__ ((__stdcall__))
+#endif
+ #define DLL_CLASS_EXPORT DLL_DECLARATION_DEFAULT_VISIBILITY
+ #define DLL_CLASS_IMPORT
+
+ // Can't use extern "C" when DLL exporting a global
+ #define DLL_GLOBAL_EXPORT DLL_DECLARATION_DEFAULT_VISIBILITY
+ #define DLL_GLOBAL_IMPORT extern
+
+ #define HINT(THE_HINT) __builtin_expect( THE_HINT, 1 )
+ #define DECL_ALIGN(x) __attribute__( ( aligned( x ) ) )
+ #define CONSTRUCT_EARLY __attribute__((init_priority(101)))
+ #define SELECTANY __attribute__((weak))
+ #define RESTRICT __restrict__
+ #define RESTRICT_FUNC RESTRICT_FUNC_NOT_YET_DEFINED_FOR_THIS_COMPILER
+ #define FMTFUNCTION( fmtargnumber, firstvarargnumber ) __attribute__ (( format( printf, fmtargnumber, firstvarargnumber )))
+ #define NOINLINE __attribute__ ((noinline))
+
+#if !defined( NO_THREAD_LOCAL )
+ #define DECL_THREAD_LOCAL __thread
+#endif
+
+ #define DISABLE_VC_WARNING( x )
+ #define DEFAULT_VC_WARNING( x )
+
+#else
+
+ #define DECL_ALIGN(x) /* */
+ #define SELECTANY static
+
+#endif
+
+#if defined( GNUC ) && !defined( COMPILER_PS3 ) // use pre-align on PS3
+// gnuc has the align decoration at the end
+#define ALIGN4
+#define ALIGN8
+#define ALIGN16
+#define ALIGN32
+#define ALIGN128
+
+#undef ALIGN16_POST
+#define ALIGN4_POST DECL_ALIGN(4)
+#define ALIGN8_POST DECL_ALIGN(8)
+#define ALIGN16_POST DECL_ALIGN(16)
+#define ALIGN32_POST DECL_ALIGN(32)
+#define ALIGN128_POST DECL_ALIGN(128)
+#else
+// MSVC has the align at the start of the struct
+// PS3 SNC supports both
+#define ALIGN4 DECL_ALIGN(4)
+#define ALIGN8 DECL_ALIGN(8)
+#define ALIGN16 DECL_ALIGN(16)
+#define ALIGN32 DECL_ALIGN(32)
+#define ALIGN128 DECL_ALIGN(128)
+
+#define ALIGN4_POST
+#define ALIGN8_POST
+#define ALIGN16_POST
+#define ALIGN32_POST
+#define ALIGN128_POST
+#endif
+
+// This can be used to declare an abstract (interface only) class.
+// Classes marked abstract should not be instantiated. If they are, and access violation will occur.
+//
+// Example of use:
+//
+// abstract_class CFoo
+// {
+// ...
+// }
+//
+// MSDN __declspec(novtable) documentation: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_langref_novtable.asp
+//
+// Note: NJS: This is not enabled for regular PC, due to not knowing the implications of exporting a class with no no vtable.
+// It's probable that this shouldn't be an issue, but an experiment should be done to verify this.
+//
+#ifndef COMPILER_MSVCX360
+ #define abstract_class class
+#else
+ #define abstract_class class NO_VTABLE
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Why do we need this? It would be nice to make it die die die
+//-----------------------------------------------------------------------------
+// Alloca defined for this platform
+#if defined( COMPILER_MSVC ) && !defined( WINDED )
+ #if defined(_M_IX86)
+ #define __i386__ 1
+ #endif
+#endif
+
+#if defined __i386__ && !defined __linux__
+ #define id386 1
+#else
+ #define id386 0
+#endif // __i386__
+
+
+//-----------------------------------------------------------------------------
+// Disable annoying unhelpful warnings
+//-----------------------------------------------------------------------------
+#ifdef COMPILER_MSVC
+// Remove warnings from warning level 4.
+#pragma warning(disable : 4514) // warning C4514: 'acosl' : unreferenced inline function has been removed
+#pragma warning(disable : 4100) // warning C4100: 'hwnd' : unreferenced formal parameter
+#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
+#pragma warning(disable : 4512) // warning C4512: 'InFileRIFF' : assignment operator could not be generated
+#pragma warning(disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning(disable : 4710) // warning C4710: function 'x' not inlined
+#pragma warning(disable : 4702) // warning C4702: unreachable code
+#pragma warning(disable : 4505) // unreferenced local function has been removed
+#pragma warning(disable : 4239) // nonstandard extension used : 'argument' ( conversion from class Vector to class Vector& )
+#pragma warning(disable : 4097) // typedef-name 'BaseClass' used as synonym for class-name 'CFlexCycler::CBaseFlex'
+#pragma warning(disable : 4324) // Padding was added at the end of a structure
+#pragma warning(disable : 4244) // type conversion warning.
+#pragma warning(disable : 4305) // truncation from 'const double ' to 'float '
+#pragma warning(disable : 4786) // Disable warnings about long symbol names
+#pragma warning(disable : 4250) // 'X' : inherits 'Y::Z' via dominance
+#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
+
+#if _MSC_VER >= 1300
+#pragma warning(disable : 4511) // Disable warnings about private copy constructors
+#pragma warning(disable : 4121) // warning C4121: 'symbol' : alignment of a member was sensitive to packing
+#pragma warning(disable : 4530) // warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc (disabled due to std headers having exception syntax)
+#endif
+
+#if _MSC_VER >= 1400
+#pragma warning(disable : 4996) // functions declared deprecated
+#endif
+
+// When we port to 64 bit, we'll have to resolve the int, ptr vs size_t 32/64 bit problems...
+#if !defined( COMPILER_MSVC64 )
+#if ( CROSS_PLATFORM_VERSION < 1 )
+#pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data
+#pragma warning( disable : 4311 ) // pointer truncation from 'char *' to 'int'
+#pragma warning( disable : 4312 ) // conversion from 'unsigned int' to 'memhandle_t' of greater size
+#endif
+#endif
+
+#elif defined( COMPILER_SNC )
+#pragma diag_suppress=1700 // warning 1700: class "%s" has virtual functions but non-virtual destructor
+// Uncomment the following line if you want to investigate a specific compiler remark without all the noise:
+// #pragma diag_suppress=1700, 83, 162, 182, 192, 194, 229, 238, 262, 341, 382, 401, 402, 403, 481, 817, 828, 833, 1363, 1771, 1774, 1779, 1780, 1783, 1785, 1786, 1788
+#endif
+
+// Pull in the /analyze code annotations.
+#include "annotations.h"
+
+//-----------------------------------------------------------------------------
+// Convert int<-->pointer, avoiding 32/64-bit compiler warnings:
+//-----------------------------------------------------------------------------
+#define INT_TO_POINTER( i ) (void *)( ( i ) + (char *)NULL )
+#define POINTER_TO_INT( p ) ( (int)(uint64)( p ) )
+
+
+//-----------------------------------------------------------------------------
+// Stack-based allocation related helpers
+//-----------------------------------------------------------------------------
+#if defined( COMPILER_GCC ) || defined( COMPILER_SNC )
+
+ #define stackalloc( _size ) alloca( ALIGN_VALUE( _size, 16 ) )
+
+ #ifdef PLATFORM_OSX
+ #define mallocsize( _p ) ( malloc_size( _p ) )
+ #else
+ #define mallocsize( _p ) ( malloc_usable_size( _p ) )
+ #endif
+
+#elif defined ( COMPILER_MSVC )
+
+ #define stackalloc( _size ) _alloca( ALIGN_VALUE( _size, 16 ) )
+ #define mallocsize( _p ) ( _msize( _p ) )
+
+#endif
+
+#define stackfree( _p ) 0
+
+//-----------------------------------------------------------------------------
+// Used to break into the debugger
+//-----------------------------------------------------------------------------
+#ifdef COMPILER_MSVC64
+ #define DebuggerBreak() __debugbreak()
+#elif COMPILER_MSVC32
+ #define DebuggerBreak() __asm { int 3 }
+#elif COMPILER_MSVCX360
+ #define DebuggerBreak() DebugBreak()
+#elif COMPILER_GCC
+ #if defined( _PS3 )
+ #define DebuggerBreak() { __asm volatile ("tw 31,1,1"); }
+ #elif defined( OSX )
+ #define DebuggerBreak() if ( Plat_IsInDebugSession() ) { __asm__ __volatile__ ( "int $3" ); } else { raise(SIGTRAP); }
+ #elif defined( PLATFORM_CYGWIN ) || defined( PLATFORM_POSIX )
+ #define DebuggerBreak() __asm__( "int $0x3;")
+ #else
+ #define DebuggerBreak() asm( "int3" )
+ #endif
+#elif defined( COMPILER_SNC ) && defined( COMPILER_PS3 )
+static bool sPS3_SuppressAssertsInThisFile = false; // you can throw this in the debugger to temporarily disable asserts inside any particular .cpp module.
+ #define DebuggerBreak() if (!sPS3_SuppressAssertsInThisFile) __builtin_snpause(); // <sergiy> from SNC Migration Guide, tw 31,1,1
+#else
+#error DebuggerBreak() is not defined for this platform!
+#endif
+
+#if defined( _X360 ) || defined( _PS3 )
+ #if defined( fsel )
+ #error
+ #endif
+#else
+
+FORCEINLINE float fsel(float fComparand, float fValGE, float fLT)
+{
+ return fComparand >= 0 ? fValGE : fLT;
+}
+FORCEINLINE double fsel(double fComparand, double fValGE, double fLT)
+{
+ return fComparand >= 0 ? fValGE : fLT;
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+// DLL export for platform utilities
+//-----------------------------------------------------------------------------
+#ifndef STATIC_TIER0
+
+#ifdef TIER0_DLL_EXPORT
+#define PLATFORM_INTERFACE DLL_EXPORT
+#define PLATFORM_OVERLOAD DLL_GLOBAL_EXPORT
+#define PLATFORM_CLASS DLL_CLASS_EXPORT
+#else
+#define PLATFORM_INTERFACE DLL_IMPORT
+#define PLATFORM_OVERLOAD DLL_GLOBAL_IMPORT
+#define PLATFORM_CLASS DLL_CLASS_IMPORT
+#endif
+
+#else // BUILD_AS_DLL
+
+#define PLATFORM_INTERFACE extern
+#define PLATFORM_OVERLOAD
+#define PLATFORM_CLASS
+
+#endif // BUILD_AS_DLL
+
+
+//-----------------------------------------------------------------------------
+// Returns true if debugger attached, false otherwise
+//-----------------------------------------------------------------------------
+#if defined( PLATFORM_WINDOWS ) || defined( _PS3 )
+PLATFORM_INTERFACE void Plat_DebugString( const tchar * );
+#else
+#define Plat_DebugString(s) ((void)0)
+#endif
+
+PLATFORM_INTERFACE bool Plat_IsInDebugSession();
+
+#define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak()
+
+
+//-----------------------------------------------------------------------------
+// Message Box
+//-----------------------------------------------------------------------------
+#if defined( PLATFORM_WINDOWS_PC )
+PLATFORM_INTERFACE void Plat_MessageBox( const char *pTitle, const tchar *pMessage );
+#else
+#define Plat_MessageBox( t, m ) ((void)0)
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Posix platform helpers
+//-----------------------------------------------------------------------------
+#ifdef PLATFORM_POSIX
+
+// Visual Studio likes to put an underscore in front of anything that looks like a portable function.
+#define _strupr strupr
+#define _getcwd getcwd
+#define _open open
+#define _lseek lseek
+#define _read read
+#define _close close
+#define _vsnprintf vsnprintf
+#define _stat stat
+#define _O_RDONLY O_RDONLY
+#define _stricmp strcasecmp
+#define _finite finite
+#define _unlink unlink
+#define _putenv putenv
+#define _chdir chdir
+#define _access access
+
+#define strcmpi stricmp
+#define stricmp strcasecmp
+#define _alloca alloca
+#define GetProcAddress dlsym
+#define _chdir chdir
+#ifndef _PS3
+#define _strnicmp strnicmp
+#endif
+#define strnicmp strncasecmp
+#define _snwprintf swprintf
+#define swprintf_s swprintf
+#define wcsicmp _wcsicmp
+#define _wcsicmp wcscmp
+#define _tempnam tempnam
+#define strtok_s strtok_r
+#define _mkdir(dir) mkdir( dir, S_IRWXU | S_IRWXG | S_IRWXO )
+#define _wtoi(arg) wcstol(arg, NULL, 10)
+#define _wtoi64(arg) wcstoll(arg, NULL, 10)
+
+#ifndef _PS3
+typedef uint32 HMODULE;
+#endif
+typedef void *HANDLE;
+#define __cdecl
+
+#if !defined( _snprintf ) // some vpc's define this on the command line
+#define _snprintf snprintf
+#endif
+
+#include <alloca.h>
+#include <unistd.h> // get unlink
+#include <errno.h>
+
+#endif // PLATFORM_POSIX
+
+#ifdef PLATFORM_WINDOWS
+#ifndef SOCKLEN_T
+#define SOCKLEN_T
+typedef int socklen_t;
+#endif
+#endif
+
+//-----------------------------------------------------------------------------
+// Generally useful platform-independent macros (move to another file?)
+//-----------------------------------------------------------------------------
+
+// need macro for constant expression
+#define ALIGN_VALUE( val, alignment ) ( ( val + alignment - 1 ) & ~( alignment - 1 ) )
+
+// Force a function call site -not- to inlined. (useful for profiling)
+#define DONT_INLINE(a) (((int)(a)+1)?(a):(a))
+
+// Marks the codepath from here until the next branch entry point as unreachable,
+// and asserts if any attempt is made to execute it.
+#define UNREACHABLE() { Assert(0); HINT(0); }
+
+// In cases where no default is present or appropriate, this causes MSVC to generate
+// as little code as possible, and throw an assertion in debug.
+#define NO_DEFAULT default: UNREACHABLE();
+
+// Defines MAX_PATH
+#ifndef MAX_PATH
+ #define MAX_PATH 260
+#endif
+
+
+//-----------------------------------------------------------------------------
+// FP exception handling
+//-----------------------------------------------------------------------------
+//#define CHECK_FLOAT_EXCEPTIONS 1
+//#define CHECK_FPU_CONTROL_WORD_SET 1 // x360 only
+
+#if defined( COMPILER_MSVC64 )
+
+ inline void SetupFPUControlWord()
+ {
+ }
+
+#elif defined ( COMPILER_MSVC32 )
+
+ inline void SetupFPUControlWordForceExceptions()
+ {
+ // use local to get and store control word
+ uint16 tmpCtrlW;
+ __asm
+ {
+ fnclex /* clear all current exceptions */
+ fnstcw word ptr [tmpCtrlW] /* get current control word */
+ and [tmpCtrlW], 0FCC0h /* Keep infinity control + rounding control */
+ or [tmpCtrlW], 0230h /* set to 53-bit, mask only inexact, underflow */
+ fldcw word ptr [tmpCtrlW] /* put new control word in FPU */
+ }
+ }
+
+ #ifdef CHECK_FLOAT_EXCEPTIONS
+
+ inline void SetupFPUControlWord()
+ {
+ SetupFPUControlWordForceExceptions();
+ }
+
+ #else
+
+ inline void SetupFPUControlWord()
+ {
+ // use local to get and store control word
+ uint16 tmpCtrlW;
+ __asm
+ {
+ fnstcw word ptr [tmpCtrlW] /* get current control word */
+ and [tmpCtrlW], 0FCC0h /* Keep infinity control + rounding control */
+ or [tmpCtrlW], 023Fh /* set to 53-bit, mask only inexact, underflow */
+ fldcw word ptr [tmpCtrlW] /* put new control word in FPU */
+ }
+ }
+
+ #endif
+
+#elif defined ( COMPILER_GCC )
+
+// Works for PS3
+ inline void SetupFPUControlWord()
+ {
+#ifdef _PS3
+// TODO: PS3 compiler spits out the following errors:
+// C:/tmp/ccIN0aaa.s: Assembler messages:
+// C:/tmp/ccIN0aaa.s(80): Error: Unrecognized opcode: `fnstcw'
+// C:/tmp/ccIN0aaa.s(93): Error: Unrecognized opcode: `fldcw'
+#else
+ __volatile unsigned short int __cw;
+ __asm __volatile ("fnstcw %0" : "=m" (__cw));
+ __cw = __cw & 0x0FCC0; // keep infinity control, keep rounding mode
+ __cw = __cw | 0x023F; // set 53-bit, no exceptions
+ __asm __volatile ("fldcw %0" : : "m" (__cw));
+#endif
+ }
+
+#elif defined ( COMPILER_SNC )
+
+// Works for PS3
+ inline void SetupFPUControlWord()
+ {
+#ifdef _PS3
+// TODO: PS3 compiler spits out the following errors:
+// C:/tmp/ccIN0aaa.s: Assembler messages:
+// C:/tmp/ccIN0aaa.s(80): Error: Unrecognized opcode: `fnstcw'
+// C:/tmp/ccIN0aaa.s(93): Error: Unrecognized opcode: `fldcw'
+#else
+ __volatile unsigned short int __cw;
+ __asm __volatile ("fnstcw %0" : "=m" (__cw));
+ __cw = __cw & 0x0FCC0; // keep infinity control, keep rounding mode
+ __cw = __cw | 0x023F; // set 53-bit, no exceptions
+ __asm __volatile ("fldcw %0" : : "m" (__cw));
+#endif
+ }
+
+#elif defined( COMPILER_MSVCX360 )
+
+ #ifdef CHECK_FPU_CONTROL_WORD_SET
+ FORCEINLINE bool IsFPUControlWordSet()
+ {
+ float f = 0.996f;
+ union
+ {
+ double flResult;
+ int pResult[2];
+ };
+ flResult = __fctiw( f );
+ return ( pResult[1] == 1 );
+ }
+ #else
+ #define IsFPUControlWordSet() 1
+ #endif
+
+ inline void SetupFPUControlWord()
+ {
+ // Set round-to-nearest in FPSCR
+ // (cannot assemble, must use op-code form)
+ __emit( 0xFF80010C ); // mtfsfi 7,0
+
+ // Favour compatibility over speed (make sure the VPU set to Java-compliant mode)
+ // NOTE: the VPU *always* uses round-to-nearest
+ __vector4 a = { 0.0f, 0.0f, 0.0f, 0.0f };
+ a; // Avoid compiler warning
+ __asm
+ {
+ mtvscr a; // Clear the Vector Status & Control Register to zero
+ }
+ }
+
+#endif // COMPILER_MSVCX360
+
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Standard functions for handling endian-ness
+//-----------------------------------------------------------------------------
+
+//-------------------------------------
+// Basic swaps
+//-------------------------------------
+
+template <typename T>
+inline T WordSwapC( T w )
+{
+ uint16 temp;
+
+ temp = ((*((uint16 *)&w) & 0xff00) >> 8);
+ temp |= ((*((uint16 *)&w) & 0x00ff) << 8);
+
+ return *((T*)&temp);
+}
+
+template <typename T>
+inline T DWordSwapC( T dw )
+{
+ uint32 temp;
+
+ temp = *((uint32 *)&dw) >> 24;
+ temp |= ((*((uint32 *)&dw) & 0x00FF0000) >> 8);
+ temp |= ((*((uint32 *)&dw) & 0x0000FF00) << 8);
+ temp |= ((*((uint32 *)&dw) & 0x000000FF) << 24);
+
+ return *((T*)&temp);
+}
+
+//-------------------------------------
+// Fast swaps
+//-------------------------------------
+
+#if defined( COMPILER_MSVCX360 )
+
+ #define WordSwap WordSwap360Intr
+ #define DWordSwap DWordSwap360Intr
+
+ template <typename T>
+ inline T WordSwap360Intr( T w )
+ {
+ T output;
+ __storeshortbytereverse( w, 0, &output );
+ return output;
+ }
+
+ template <typename T>
+ inline T DWordSwap360Intr( T dw )
+ {
+ T output;
+ __storewordbytereverse( dw, 0, &output );
+ return output;
+ }
+
+#elif defined( COMPILER_MSVC32 )
+
+ #define WordSwap WordSwapAsm
+ #define DWordSwap DWordSwapAsm
+
+ #pragma warning(push)
+ #pragma warning (disable:4035) // no return value
+
+ template <typename T>
+ inline T WordSwapAsm( T w )
+ {
+ __asm
+ {
+ mov ax, w
+ xchg al, ah
+ }
+ }
+
+ template <typename T>
+ inline T DWordSwapAsm( T dw )
+ {
+ __asm
+ {
+ mov eax, dw
+ bswap eax
+ }
+ }
+
+ #pragma warning(pop)
+
+#else
+
+ #define WordSwap WordSwapC
+ #define DWordSwap DWordSwapC
+
+#endif
+
+//-------------------------------------
+// The typically used methods.
+//-------------------------------------
+
+#if defined( _SGI_SOURCE ) || defined( PLATFORM_X360 ) || defined( _PS3 )
+#define PLAT_BIG_ENDIAN 1
+#else
+#define PLAT_LITTLE_ENDIAN 1
+#endif
+
+
+// If a swapped float passes through the fpu, the bytes may get changed.
+// Prevent this by swapping floats as DWORDs.
+#define SafeSwapFloat( pOut, pIn ) (*((uint*)pOut) = DWordSwap( *((uint*)pIn) ))
+
+#if defined(PLAT_LITTLE_ENDIAN)
+#define BigShort( val ) WordSwap( val )
+#define BigWord( val ) WordSwap( val )
+#define BigLong( val ) DWordSwap( val )
+#define BigDWord( val ) DWordSwap( val )
+#define LittleShort( val ) ( val )
+#define LittleWord( val ) ( val )
+#define LittleLong( val ) ( val )
+#define LittleDWord( val ) ( val )
+#define SwapShort( val ) BigShort( val )
+#define SwapWord( val ) BigWord( val )
+#define SwapLong( val ) BigLong( val )
+#define SwapDWord( val ) BigDWord( val )
+
+// Pass floats by pointer for swapping to avoid truncation in the fpu
+#define BigFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn )
+#define LittleFloat( pOut, pIn ) ( *pOut = *pIn )
+#define SwapFloat( pOut, pIn ) BigFloat( pOut, pIn )
+
+#elif defined(PLAT_BIG_ENDIAN)
+
+#define BigShort( val ) ( val )
+#define BigWord( val ) ( val )
+#define BigLong( val ) ( val )
+#define BigDWord( val ) ( val )
+#define LittleShort( val ) WordSwap( val )
+#define LittleWord( val ) WordSwap( val )
+#define LittleLong( val ) DWordSwap( val )
+#define LittleDWord( val ) DWordSwap( val )
+#define SwapShort( val ) LittleShort( val )
+#define SwapWord( val ) LittleWord( val )
+#define SwapLong( val ) LittleLong( val )
+#define SwapDWord( val ) LittleDWord( val )
+
+// Pass floats by pointer for swapping to avoid truncation in the fpu
+#define BigFloat( pOut, pIn ) ( *pOut = *pIn )
+#define LittleFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn )
+#define SwapFloat( pOut, pIn ) LittleFloat( pOut, pIn )
+
+#else
+
+// @Note (toml 05-02-02): this technique expects the compiler to
+// optimize the expression and eliminate the other path. On any new
+// platform/compiler this should be tested.
+inline short BigShort( short val ) { int test = 1; return ( *(char *)&test == 1 ) ? WordSwap( val ) : val; }
+inline uint16 BigWord( uint16 val ) { int test = 1; return ( *(char *)&test == 1 ) ? WordSwap( val ) : val; }
+inline long BigLong( long val ) { int test = 1; return ( *(char *)&test == 1 ) ? DWordSwap( val ) : val; }
+inline uint32 BigDWord( uint32 val ) { int test = 1; return ( *(char *)&test == 1 ) ? DWordSwap( val ) : val; }
+inline short LittleShort( short val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : WordSwap( val ); }
+inline uint16 LittleWord( uint16 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : WordSwap( val ); }
+inline long LittleLong( long val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : DWordSwap( val ); }
+inline uint32 LittleDWord( uint32 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : DWordSwap( val ); }
+inline short SwapShort( short val ) { return WordSwap( val ); }
+inline uint16 SwapWord( uint16 val ) { return WordSwap( val ); }
+inline long SwapLong( long val ) { return DWordSwap( val ); }
+inline uint32 SwapDWord( uint32 val ) { return DWordSwap( val ); }
+
+// Pass floats by pointer for swapping to avoid truncation in the fpu
+inline void BigFloat( float *pOut, const float *pIn ) { int test = 1; ( *(char *)&test == 1 ) ? SafeSwapFloat( pOut, pIn ) : ( *pOut = *pIn ); }
+inline void LittleFloat( float *pOut, const float *pIn ) { int test = 1; ( *(char *)&test == 1 ) ? ( *pOut = *pIn ) : SafeSwapFloat( pOut, pIn ); }
+inline void SwapFloat( float *pOut, const float *pIn ) { SafeSwapFloat( pOut, pIn ); }
+
+#endif
+
+#if PLAT_BIG_ENDIAN
+ #if defined( _PS3 )
+ inline uint32 LoadLittleDWord( uint32 *base, unsigned int dwordIndex )
+ {
+ return __lwbrx( base + dwordIndex );
+ }
+
+ inline void StoreLittleDWord( uint32 *base, unsigned int dwordIndex, uint32 dword )
+ {
+ __stwbrx( base + dwordIndex, dword );
+ }
+ inline uint64 LoadLittleInt64( uint64 *base, unsigned int nWordIndex )
+ {
+ return __ldbrx( base + nWordIndex );
+ }
+
+ inline void StoreLittleInt64( uint64 *base, unsigned int nWordIndex, uint64 nWord )
+ {
+ __stdbrx( base + nWordIndex, nWord );
+ }
+ #else
+ inline uint32 LoadLittleDWord( uint32 *base, unsigned int dwordIndex )
+ {
+ return __loadwordbytereverse( dwordIndex<<2, base );
+ }
+
+ inline void StoreLittleDWord( uint32 *base, unsigned int dwordIndex, uint32 dword )
+ {
+ __storewordbytereverse( dword, dwordIndex<<2, base );
+ }
+ inline uint64 LoadLittleInt64( uint64 *base, unsigned int nWordIndex )
+ {
+ return __loaddoublewordbytereverse( nWordIndex<<2, base );
+ }
+
+ inline void StoreLittleInt64( uint64 *base, unsigned int nWordIndex, uint64 nWord )
+ {
+ __storedoublewordbytereverse( nWord, nWordIndex<<2, base );
+ }
+ #endif
+#else
+ inline uint32 LoadLittleDWord( uint32 *base, unsigned int dwordIndex )
+ {
+ return LittleDWord( base[dwordIndex] );
+ }
+
+ inline void StoreLittleDWord( uint32 *base, unsigned int dwordIndex, uint32 dword )
+ {
+ base[dwordIndex] = LittleDWord(dword);
+ }
+#endif
+
+
+// When in benchmark mode, the timer returns a simple incremented value each time you call it.
+//
+// It should not be changed after startup unless you really know what you're doing. The only place
+// that should do this is the benchmark code itself so it can output a legit duration.
+PLATFORM_INTERFACE void Plat_SetBenchmarkMode( bool bBenchmarkMode );
+PLATFORM_INTERFACE bool Plat_IsInBenchmarkMode();
+
+
+PLATFORM_INTERFACE double Plat_FloatTime(); // Returns time in seconds since the module was loaded.
+PLATFORM_INTERFACE uint32 Plat_MSTime(); // Time in milliseconds.
+PLATFORM_INTERFACE uint64 Plat_GetClockStart(); // Snapshot of the clock when app started.
+PLATFORM_INTERFACE uint64 Timer_GetTimeUS();
+
+// Get the local calendar time.
+// Same as time() followed by localtime(), but non-crash-prone and threadsafe.
+PLATFORM_INTERFACE void Plat_GetLocalTime( struct tm *pNow );
+
+// Convert a time_t (specified in nTime - seconds since Jan 1, 1970 UTC) to a local calendar time in a threadsafe and non-crash-prone way.
+PLATFORM_INTERFACE void Plat_ConvertToLocalTime( uint64 nTime, struct tm *pNow );
+
+// Get a time string (same as ascstring, but threadsafe).
+PLATFORM_INTERFACE void Plat_GetTimeString( struct tm *pTime, char *pOut, int nMaxBytes );
+
+// converts a time_t to a struct tm without the local time conversion of ConvertToLocalTime
+PLATFORM_INTERFACE void Plat_gmtime( uint64 nTime, struct tm *pTime );
+PLATFORM_INTERFACE time_t Plat_timegm( struct tm *timeptr );
+
+// Get the process' executable filename.
+PLATFORM_INTERFACE void Plat_GetModuleFilename( char *pOut, int nMaxBytes );
+
+PLATFORM_INTERFACE void Plat_ExitProcess( int nCode );
+
+// b/w compatibility
+#define Sys_FloatTime Plat_FloatTime
+
+// Protect against bad auto operator=
+#define DISALLOW_OPERATOR_EQUAL( _classname ) \
+ private: \
+ _classname &operator=( const _classname & ); \
+ public:
+
+// Define a reasonable operator=
+#define IMPLEMENT_OPERATOR_EQUAL( _classname ) \
+ public: \
+ _classname &operator=( const _classname &src ) \
+ { \
+ memcpy( this, &src, sizeof(_classname) ); \
+ return *this; \
+ }
+
+// Processor Information:
+struct CPUInformation
+{
+ int m_Size; // Size of this structure, for forward compatability.
+
+ bool m_bRDTSC : 1, // Is RDTSC supported?
+ m_bCMOV : 1, // Is CMOV supported?
+ m_bFCMOV : 1, // Is FCMOV supported?
+ m_bSSE : 1, // Is SSE supported?
+ m_bSSE2 : 1, // Is SSE2 Supported?
+ m_b3DNow : 1, // Is 3DNow! Supported?
+ m_bMMX : 1, // Is MMX supported?
+ m_bHT : 1; // Is HyperThreading supported?
+
+ uint8 m_nLogicalProcessors; // Number op logical processors.
+ uint8 m_nPhysicalProcessors; // Number of physical processors
+
+ bool m_bSSE3 : 1,
+ m_bSSSE3 : 1,
+ m_bSSE4a : 1,
+ m_bSSE41 : 1,
+ m_bSSE42 : 1;
+
+ int64 m_Speed; // In cycles per second.
+
+ tchar* m_szProcessorID; // Processor vendor Identification.
+
+ CPUInformation(): m_Size(0){}
+};
+
+PLATFORM_INTERFACE const CPUInformation& GetCPUInformation();
+
+PLATFORM_INTERFACE void GetCurrentDate( int *pDay, int *pMonth, int *pYear );
+PLATFORM_INTERFACE void GetCurrentDayOfTheWeek( int *pDay ); // 0 = Sunday
+PLATFORM_INTERFACE void GetCurrentDayOfTheYear( int *pDay ); // 0 = Jan 1
+
+// ---------------------------------------------------------------------------------- //
+// Performance Monitoring Events - L2 stats etc...
+// ---------------------------------------------------------------------------------- //
+PLATFORM_INTERFACE void InitPME();
+PLATFORM_INTERFACE void ShutdownPME();
+
+
+//-----------------------------------------------------------------------------
+// Security related functions
+//-----------------------------------------------------------------------------
+// Ensure that the hardware key's drivers have been installed.
+PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyDriver();
+
+// Ok, so this isn't a very secure way to verify the hardware key for now. It
+// is primarially depending on the fact that all the binaries have been wrapped
+// with the secure wrapper provided by the hardware keys vendor.
+PLATFORM_INTERFACE bool Plat_VerifyHardwareKey();
+
+// The same as above, but notifies user with a message box when the key isn't in
+// and gives him an opportunity to correct the situation.
+PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyPrompt();
+
+// Can be called in real time, doesn't perform the verify every frame. Mainly just
+// here to allow the game to drop out quickly when the key is removed, rather than
+// allowing the wrapper to pop up it's own blocking dialog, which the engine doesn't
+// like much.
+PLATFORM_INTERFACE bool Plat_FastVerifyHardwareKey();
+
+//-----------------------------------------------------------------------------
+// Just logs file and line to simple.log
+//-----------------------------------------------------------------------------
+PLATFORM_INTERFACE void* Plat_SimpleLog( const tchar* file, int line );
+
+
+#if defined( _X360 )
+#define Plat_FastMemset XMemSet
+#define Plat_FastMemcpy XMemCpy
+#else
+#define Plat_FastMemset memset
+#define Plat_FastMemcpy memcpy
+#endif
+
+//-----------------------------------------------------------------------------
+// XBOX Components valid in PC compilation space
+//-----------------------------------------------------------------------------
+
+#define XBOX_DVD_SECTORSIZE 2048
+#define XBOX_DVD_ECC_SIZE 32768 // driver reads in quantum ECC blocks
+#define XBOX_HDD_SECTORSIZE 512
+
+// Custom windows messages for Xbox input
+#define WM_XREMOTECOMMAND (WM_USER + 100)
+#define WM_XCONTROLLER_KEY (WM_USER + 101)
+#define WM_SYS_UI (WM_USER + 102)
+#define WM_SYS_SIGNINCHANGED (WM_USER + 103)
+#define WM_SYS_STORAGEDEVICESCHANGED (WM_USER + 104)
+#define WM_SYS_PROFILESETTINGCHANGED (WM_USER + 105)
+#define WM_SYS_MUTELISTCHANGED (WM_USER + 106)
+#define WM_SYS_INPUTDEVICESCHANGED (WM_USER + 107)
+#define WM_SYS_INPUTDEVICECONFIGCHANGED (WM_USER + 108)
+#define WM_LIVE_CONNECTIONCHANGED (WM_USER + 109)
+#define WM_LIVE_INVITE_ACCEPTED (WM_USER + 110)
+#define WM_LIVE_LINK_STATE_CHANGED (WM_USER + 111)
+#define WM_LIVE_CONTENT_INSTALLED (WM_USER + 112)
+#define WM_LIVE_MEMBERSHIP_PURCHASED (WM_USER + 113)
+#define WM_LIVE_VOICECHAT_AWAY (WM_USER + 114)
+#define WM_LIVE_PRESENCE_CHANGED (WM_USER + 115)
+#define WM_FRIENDS_PRESENCE_CHANGED (WM_USER + 116)
+#define WM_FRIENDS_FRIEND_ADDED (WM_USER + 117)
+#define WM_FRIENDS_FRIEND_REMOVED (WM_USER + 118)
+#define WM_CUSTOM_GAMEBANNERPRESSED (WM_USER + 119)
+#define WM_CUSTOM_ACTIONPRESSED (WM_USER + 120)
+#define WM_XMP_STATECHANGED (WM_USER + 121)
+#define WM_XMP_PLAYBACKBEHAVIORCHANGED (WM_USER + 122)
+#define WM_XMP_PLAYBACKCONTROLLERCHANGED (WM_USER + 123)
+#define WM_SYS_SHUTDOWNREQUEST (WM_USER + 124)
+
+#if defined( _PS3 )
+#define PLATFORM_EXT ".ps3"
+#elif defined( PLATFORM_X360 )
+#define PLATFORM_EXT ".360"
+#else
+#define PLATFORM_EXT ""
+#endif
+
+inline const char *GetPlatformExt( void )
+{
+ return PLATFORM_EXT;
+}
+
+// flat view, 6 hw threads
+#define XBOX_PROCESSOR_0 ( 1<<0 )
+#define XBOX_PROCESSOR_1 ( 1<<1 )
+#define XBOX_PROCESSOR_2 ( 1<<2 )
+#define XBOX_PROCESSOR_3 ( 1<<3 )
+#define XBOX_PROCESSOR_4 ( 1<<4 )
+#define XBOX_PROCESSOR_5 ( 1<<5 )
+
+// core view, 3 cores with 2 hw threads each
+#define XBOX_CORE_0_HWTHREAD_0 XBOX_PROCESSOR_0
+#define XBOX_CORE_0_HWTHREAD_1 XBOX_PROCESSOR_1
+#define XBOX_CORE_1_HWTHREAD_0 XBOX_PROCESSOR_2
+#define XBOX_CORE_1_HWTHREAD_1 XBOX_PROCESSOR_3
+#define XBOX_CORE_2_HWTHREAD_0 XBOX_PROCESSOR_4
+#define XBOX_CORE_2_HWTHREAD_1 XBOX_PROCESSOR_5
+
+//-----------------------------------------------------------------------------
+// Include additional dependant header components.
+//-----------------------------------------------------------------------------
+#if defined( PLATFORM_X360 )
+#include "xbox/xbox_core.h"
+#elif defined( PLATFORM_PS3 )
+#include "ps3/ps3_core.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// Methods to invoke the constructor, copy constructor, and destructor
+//-----------------------------------------------------------------------------
+
+template <class T>
+inline T* Construct( T* pMemory )
+{
+ return ::new( pMemory ) T;
+}
+
+template <class T, typename ARG1>
+inline T* Construct( T* pMemory, ARG1 a1 )
+{
+ return ::new( pMemory ) T( a1 );
+}
+
+template <class T, typename ARG1, typename ARG2>
+inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2 )
+{
+ return ::new( pMemory ) T( a1, a2 );
+}
+
+template <class T, typename ARG1, typename ARG2, typename ARG3>
+inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3 )
+{
+ return ::new( pMemory ) T( a1, a2, a3 );
+}
+
+template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4>
+inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4 )
+{
+ return ::new( pMemory ) T( a1, a2, a3, a4 );
+}
+
+template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4, typename ARG5>
+inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4, ARG5 a5 )
+{
+ return ::new( pMemory ) T( a1, a2, a3, a4, a5 );
+}
+
+template <class T>
+inline T* CopyConstruct( T* pMemory, T const& src )
+{
+ return ::new( pMemory ) T(src);
+}
+
+template <class T>
+inline void Destruct( T* pMemory )
+{
+ pMemory->~T();
+
+#ifdef _DEBUG
+ memset( pMemory, 0xDD, sizeof(T) );
+#endif
+}
+
+
+//
+// GET_OUTER()
+//
+// A platform-independent way for a contained class to get a pointer to its
+// owner. If you know a class is exclusively used in the context of some
+// "outer" class, this is a much more space efficient way to get at the outer
+// class than having the inner class store a pointer to it.
+//
+// class COuter
+// {
+// class CInner // Note: this does not need to be a nested class to work
+// {
+// void PrintAddressOfOuter()
+// {
+// printf( "Outer is at 0x%x\n", GET_OUTER( COuter, m_Inner ) );
+// }
+// };
+//
+// CInner m_Inner;
+// friend class CInner;
+// };
+
+#define GET_OUTER( OuterType, OuterMember ) \
+ ( ( OuterType * ) ( (uint8 *)this - offsetof( OuterType, OuterMember ) ) )
+
+
+/* TEMPLATE_FUNCTION_TABLE()
+
+ (Note added to platform.h so platforms that correctly support templated
+ functions can handle portions as templated functions rather than wrapped
+ functions)
+
+ Helps automate the process of creating an array of function
+ templates that are all specialized by a single integer.
+ This sort of thing is often useful in optimization work.
+
+ For example, using TEMPLATE_FUNCTION_TABLE, this:
+
+ TEMPLATE_FUNCTION_TABLE(int, Function, ( int blah, int blah ), 10)
+ {
+ return argument * argument;
+ }
+
+ is equivilent to the following:
+
+ (NOTE: the function has to be wrapped in a class due to code
+ generation bugs involved with directly specializing a function
+ based on a constant.)
+
+ template<int argument>
+ class FunctionWrapper
+ {
+ public:
+ int Function( int blah, int blah )
+ {
+ return argument*argument;
+ }
+ }
+
+ typedef int (*FunctionType)( int blah, int blah );
+
+ class FunctionName
+ {
+ public:
+ enum { count = 10 };
+ FunctionType functions[10];
+ };
+
+ FunctionType FunctionName::functions[] =
+ {
+ FunctionWrapper<0>::Function,
+ FunctionWrapper<1>::Function,
+ FunctionWrapper<2>::Function,
+ FunctionWrapper<3>::Function,
+ FunctionWrapper<4>::Function,
+ FunctionWrapper<5>::Function,
+ FunctionWrapper<6>::Function,
+ FunctionWrapper<7>::Function,
+ FunctionWrapper<8>::Function,
+ FunctionWrapper<9>::Function
+ };
+*/
+
+PLATFORM_INTERFACE bool vtune( bool resume );
+
+
+#define TEMPLATE_FUNCTION_TABLE(RETURN_TYPE, NAME, ARGS, COUNT) \
+ \
+typedef RETURN_TYPE (FASTCALL *__Type_##NAME) ARGS; \
+ \
+template<const int nArgument> \
+struct __Function_##NAME \
+{ \
+ static RETURN_TYPE FASTCALL Run ARGS; \
+}; \
+ \
+template <const int i> \
+struct __MetaLooper_##NAME : __MetaLooper_##NAME<i-1> \
+{ \
+ __Type_##NAME func; \
+ inline __MetaLooper_##NAME() { func = __Function_##NAME<i>::Run; } \
+}; \
+ \
+template<> \
+struct __MetaLooper_##NAME<0> \
+{ \
+ __Type_##NAME func; \
+ inline __MetaLooper_##NAME() { func = __Function_##NAME<0>::Run; } \
+}; \
+ \
+class NAME \
+{ \
+private: \
+ static const __MetaLooper_##NAME<COUNT> m; \
+public: \
+ enum { count = COUNT }; \
+ static const __Type_##NAME* functions; \
+}; \
+const __MetaLooper_##NAME<COUNT> NAME::m; \
+const __Type_##NAME* NAME::functions = (__Type_##NAME*)&m; \
+template<const int nArgument> \
+RETURN_TYPE FASTCALL __Function_##NAME<nArgument>::Run ARGS
+
+
+#define LOOP_INTERCHANGE(BOOLEAN, CODE)\
+ if( (BOOLEAN) )\
+ {\
+ CODE;\
+ } else\
+ {\
+ CODE;\
+ }
+
+
+//-----------------------------------------------------------------------------
+// Dynamic libs support
+//-----------------------------------------------------------------------------
+#if defined( PLATFORM_WINDOWS )
+
+PLATFORM_INTERFACE void *Plat_GetProcAddress( const char *pszModule, const char *pszName );
+
+template <typename FUNCPTR_TYPE>
+class CDynamicFunction
+{
+public:
+ CDynamicFunction( const char *pszModule, const char *pszName, FUNCPTR_TYPE pfnFallback = NULL )
+ {
+ m_pfn = pfnFallback;
+ void *pAddr = Plat_GetProcAddress( pszModule, pszName );
+ if ( pAddr )
+ {
+ m_pfn = (FUNCPTR_TYPE)pAddr;
+ }
+ }
+
+ operator bool() { return m_pfn != NULL; }
+ bool operator !() { return !m_pfn; }
+ operator FUNCPTR_TYPE() { return m_pfn; }
+
+private:
+ FUNCPTR_TYPE m_pfn;
+};
+#endif
+
+
+//-----------------------------------------------------------------------------
+// What OS version are we?
+//-----------------------------------------------------------------------------
+enum PlatOSVersion_t
+{
+ PLAT_OS_VERSION_UNKNOWN = -1,
+
+ // X360-specific versions
+ PLAT_OS_VERSION_XBOX360 = 0,
+
+ // PC-specific OS versions
+ PLAT_OS_VERSION_XP = 5,
+ PLAT_OS_VERSION_VISTA = 6,
+};
+
+PLATFORM_INTERFACE PlatOSVersion_t Plat_GetOSVersion();
+
+
+// Watchdog timer support. Call BeginWatchdogTimer( nn ) to kick the timer off. if you don't call
+// EndWatchdogTimer within nn seconds, the program will kick off an exception. This is for making
+// sure that hung dedicated servers abort (and restart) instead of staying hung. Calling
+// EndWatchdogTimer more than once or when there is no active watchdog is fine. Only does anything
+// under linux right now. It should be possible to implement this functionality in windows via a
+// thread, if desired.
+
+#if defined( POSIX ) && !defined( _PS3 )
+
+PLATFORM_INTERFACE void BeginWatchdogTimer( int nSecs );
+PLATFORM_INTERFACE void EndWatchdogTimer( void );
+PLATFORM_INTERFACE void ResetBaseTime( void ); // reset plat_floattime to 0 for a subprocess
+#else
+FORCEINLINE void BeginWatchdogTimer( int nSecs )
+{
+}
+
+FORCEINLINE void EndWatchdogTimer( void )
+{
+}
+FORCEINLINE void ResetBaseTime( void ) // reset plat_floattime to 0 for a subprocess
+{
+}
+
+#endif
+
+
+#ifdef COMPILER_MSVC
+/*
+FORCEINLINE uint8 RotateBitsLeft8( uint8 nValue, int nRotateBits )
+{
+ return _rotl8( nValue, nRotateBits );
+}
+FORCEINLINE uint16 RotateBitsLeft16( uint16 nValue, int nRotateBits )
+{
+ return _rotl( nValue, nRotateBits );
+}
+FORCEINLINE uint8 RotateBitsRight8( uint8 nValue, int nRotateBits )
+{
+return _rotr8( nValue, nRotateBits );
+}
+FORCEINLINE uint16 RotateBitsRight16( uint16 nValue, int nRotateBits )
+{
+return _rotr16( nValue, nRotateBits );
+}
+*/
+FORCEINLINE uint32 RotateBitsLeft32( uint32 nValue, int nRotateBits )
+{
+ return _rotl( nValue, nRotateBits );
+}
+FORCEINLINE uint64 RotateBitsLeft64( uint64 nValue, int nRotateBits )
+{
+ return _rotl64( nValue, nRotateBits );
+}
+FORCEINLINE uint32 RotateBitsRight32( uint32 nValue, int nRotateBits )
+{
+ return _rotr( nValue, nRotateBits );
+}
+FORCEINLINE uint64 RotateBitsRight64( uint64 nValue, int nRotateBits )
+{
+ return _rotr64( nValue, nRotateBits );
+}
+#else
+// GCC should compile this all into single instruction
+/*
+FORCEINLINE uint8 RotateBitsLeft8( uint8 nValue, int nRotateBits )
+{
+ return ( nValue << nRotateBits ) | ( nValue >> ( ( -nRotateBits ) & 7 ) );
+}
+FORCEINLINE uint16 RotateBitsLeft16( uint16 nValue, int nRotateBits )
+{
+ return ( nValue << nRotateBits ) | ( nValue >> ( ( -nRotateBits ) & 15 ) );
+}
+FORCEINLINE uint8 RotateBitsRight8( uint8 nValue, int nRotateBits )
+{
+ return ( nValue >> nRotateBits ) | ( nValue << ( ( -nRotateBits ) & 7 ) );
+}
+FORCEINLINE uint16 RotateBitsRight16( uint16 nValue, int nRotateBits )
+{
+ return ( nValue >> nRotateBits ) | ( nValue << ( ( -nRotateBits ) & 15 ) );
+}
+*/
+FORCEINLINE uint32 RotateBitsLeft32( uint32 nValue, int nRotateBits )
+{
+ return ( nValue << nRotateBits ) | ( nValue >> ( ( -nRotateBits ) & 31 ) );
+}
+FORCEINLINE uint64 RotateBitsLeft64( uint64 nValue, int nRotateBits )
+{
+ return ( nValue << nRotateBits ) | ( nValue >> ( ( - nRotateBits ) & 63 ) );
+}
+FORCEINLINE uint32 RotateBitsRight32( uint32 nValue, int nRotateBits )
+{
+ return ( nValue >> nRotateBits ) | ( nValue << ( ( -nRotateBits ) & 31 ) );
+}
+FORCEINLINE uint64 RotateBitsRight64( uint64 nValue, int nRotateBits )
+{
+ return ( nValue >> nRotateBits ) | ( nValue << ( ( - nRotateBits ) & 63 ) );
+}
+#endif
+PLATFORM_INTERFACE const char * GetPlatformSpecificFileName(const char * FileName);
+
+#include "tier0/valve_on.h"
+
+#if defined(TIER0_DLL_EXPORT)
+extern "C" int V_tier0_stricmp(const char *s1, const char *s2 );
+#undef stricmp
+#undef strcmpi
+#define stricmp(s1,s2) V_tier0_stricmp( s1, s2 )
+#define strcmpi(s1,s2) V_tier0_stricmp( s1, s2 )
+#else
+int _V_stricmp (const char *s1, const char *s2 );
+int V_strncasecmp (const char *s1, const char *s2, int n);
+
+// A special high-performance case-insensitive compare function that in
+// a single call distinguishes between exactly matching strings,
+// strings equal in case-insensitive way, and not equal strings:
+// returns 0 if strings match exactly
+// returns >0 if strings match in a case-insensitive way, but do not match exactly
+// returns <0 if strings do not match even in a case-insensitive way
+int _V_stricmp_NegativeForUnequal ( const char *s1, const char *s2 );
+
+#undef stricmp
+#undef strcmpi
+#define stricmp(s1,s2) _V_stricmp(s1, s2)
+#define strcmpi(s1,s2) _V_stricmp(s1, s2)
+#undef strnicmp
+#define strnicmp V_strncasecmp
+#endif
+
+#endif /* PLATFORM_H */