#ifndef PLATFORM_H #define PLATFORM_H #if defined( _WIN32 ) && defined( _MSC_VER ) && ( _MSC_VER >= 1400 ) #pragma intrinsic(__rdtsc) #endif #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) //C++17 specific #define SDK_HAS_CPP17 1 #define V_CONSTEXPR constexpr #else #define V_CONSTEXPR #endif #define TIER0_DLL_EXPORT #ifdef _MSC_VER #define COMPILER_MSVC 1 // !TODO: Set in CMake! #endif // _MSC_VER #ifdef __clang__ #define COMPILER_CLANG 1 // !TODO: Set in CMake! #endif // __clang__ //----------------------------------------------------------------------------- // 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 #define COMPILER_MSVC64 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) // Adding IsPlatformOpenGL() to help fix a bunch of code that was using IsPosix() to infer if the DX->GL translation layer was being used. #if defined( DX_TO_GL_ABSTRACTION ) #define IsPlatformOpenGL() true #else #define IsPlatformOpenGL() false #endif #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 //----------------------------------------------------------------------------- // 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 #ifdef COMPILER_CLANG #define CLANG 1 #define POSIX_MATH 1 #endif #if defined( _WIN32 ) #define _WINDOWS 1 #endif #ifdef PLATFORM_WINDOWS_PC #define IS_WINDOWS_PC 1 #endif #if _MSC_VER >= 1800 #define VECTORCALL __vectorcall #else #define VECTORCALL #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 #if defined( _SGI_SOURCE ) || defined( PLATFORM_X360 ) || defined( _PS3 ) #define PLAT_BIG_ENDIAN 1 #else #define PLAT_LITTLE_ENDIAN 1 #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 #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 #define ALIGN_N( _align_ ) #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) #define ALIGN_N_POST( _align_ ) DECL_ALIGN( _align_ ) #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 ALIGN_N( _align_ ) DECL_ALIGN( _align_ ) #define ALIGN4_POST #define ALIGN8_POST #define ALIGN16_POST #define ALIGN32_POST #define ALIGN128_POST #define ALIGN_N_POST( _align_ ) #endif // !!! NOTE: if you get a compile error here, you are using VALIGNOF on an abstract type :NOTE !!! #define VALIGNOF_PORTABLE( type ) ( sizeof( AlignOf_t ) - sizeof( type ) ) #if defined( COMPILER_GCC ) || defined( COMPILER_MSVC ) #define VALIGNOF( type ) __alignof( type ) #define VALIGNOF_TEMPLATE_SAFE( type ) VALIGNOF_PORTABLE( type ) #else #error "PORT: Code only tested with MSVC! Must validate with new compiler, and use built-in keyword if available." #endif // Use ValidateAlignment to sanity-check alignment usage when allocating arrays of an aligned type #define ALIGN_ASSERT( pred ) { COMPILE_TIME_ASSERT( pred ); } template< class T, int ALIGN > inline void ValidateAlignmentExplicit(void) { // Alignment must be a power of two ALIGN_ASSERT((ALIGN & (ALIGN - 1)) == 0); // Alignment must not imply gaps in the array (which the CUtlMemory pattern does not allow for) ALIGN_ASSERT(ALIGN <= sizeof(T)); // Alignment must be a multiple of the size of the object type, or elements will *NOT* be aligned! ALIGN_ASSERT((sizeof(T) % ALIGN) == 0); // Alignment should be a multiple of the base alignment of T // ALIGN_ASSERT((ALIGN % VALIGNOF(T)) == 0); } template< class T > inline void ValidateAlignment(void) { ValidateAlignmentExplicit(); } // Portable alternative to __alignof template struct AlignOf_t { AlignOf_t() {} AlignOf_t& operator=(const AlignOf_t&) { return *this; } byte b; T t; }; template < size_t NUM, class T, int ALIGN > struct AlignedByteArrayExplicit_t {}; template < size_t NUM, class T > struct AlignedByteArray_t : public AlignedByteArrayExplicit_t< NUM, T, VALIGNOF_TEMPLATE_SAFE(T) > {}; //----------------------------------------------------------------------------- // Macro to assist in asserting constant invariants during compilation // This implementation of compile time assert has zero cost (so it can safely be // included in release builds) and can be used at file scope or function scope. #ifdef __GNUC__ #define COMPILE_TIME_ASSERT( pred ) typedef int UNIQUE_ID[ (pred) ? 1 : -1 ] #else #if _MSC_VER >= 1600 // If available use static_assert instead of weird language tricks. This // leads to much more readable messages when compile time assert constraints // are violated. #define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred ) #else // Due to gcc bugs this can in rare cases (some template functions) cause redeclaration // errors when used multiple times in one scope. Fix by adding extra scoping. #define COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1]; #endif #endif // ASSERT_INVARIANT used to be needed in order to allow COMPILE_TIME_ASSERTs at global // scope. However the new COMPILE_TIME_ASSERT macro supports that by default. #define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred ) // 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 #if defined( _MSC_VER ) #define OVERRIDE override // warning C4481: nonstandard extension used: override specifier 'override' #pragma warning(disable : 4481) #elif defined( __clang__ ) #define OVERRIDE override // warning: 'override' keyword is a C++11 extension [-Wc++11-extensions] // Disabling this warning is less intrusive than enabling C++11 extensions #pragma GCC diagnostic ignored "-Wc++11-extensions" #else #define OVERRIDE #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(); #define MAX_FILEPATH 512 // Defines MAX_PATH #ifndef MAX_PATH #define MAX_PATH 260 #endif #ifdef _DEBUG #define LEAKTRACK #endif //----------------------------------------------------------------------------- // Time stamp counter //----------------------------------------------------------------------------- inline uint64_t Plat_Rdtsc() { #if defined( _X360 ) return (uint64)__mftb32(); #elif defined( _WIN64 ) return (uint64_t)__rdtsc(); #elif defined( _WIN32 ) #if defined( _MSC_VER ) && ( _MSC_VER >= 1400 ) return (uint64_t)__rdtsc(); #else __asm rdtsc; __asm ret; #endif #elif defined( __i386__ ) uint64 val; __asm__ __volatile__("rdtsc" : "=A" (val)); return val; #elif defined( __x86_64__ ) uint32 lo, hi; __asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi)); return (((uint64)hi) << 32) | lo; #else #error #endif } double Plat_FloatTime(); uint64_t Plat_MSTime(); const char* Plat_GetProcessUpTime(); void Plat_GetProcessUpTime(char* szBuf, size_t nSize); //----------------------------------------------------------------------------- // Silences a number of warnings on 360 compiles //----------------------------------------------------------------------------- inline uint64 CastPtrToUint64(const void* p) { return (uint64)((uintptr_t)p); } inline int64 CastPtrToInt64(const void* p) { return (int64)((uintptr_t)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 stackalloc_aligned( _size, _align ) (void*)( ( ((uintp)alloca( ALIGN_VALUE( ( _size ) + (_align ), ( _align ) ) )) + ( _align ) ) & ~_align ) // We should probably always just align to 16 bytes, stackalloc just causes too many problems without this behavior. Source2 does it already. // #define stackalloc( _size ) stackalloc_aligned( _size, 16 ) #define stackfree( _p ) 0 // two-argument ( type, #elements) stackalloc #define StackAlloc( typ, nelements ) ( ( typ * ) stackalloc_aligned( ( nelements ) * sizeof(typ), 16 ) ) #define NO_MALLOC_OVERRIDE //----------------------------------------------------------------------------- // 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 #define FORCENOINLINE __declspec(noinline) // 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 instantiation, 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 unnecessary / stupid code // in certain situations. Several compilers other than MSVC also have an equivalent // 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 initialized 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 ) || defined( PLATFORM_64BITS ) #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 #if !defined( _PS3 ) && !defined( LINUX ) && !defined( PLATFORM_64BITS ) #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)) #if defined(__clang__) // [will] - clang is very strict about restrict, and we have a bunch of core functions that use the keyword which have issues with it. // This seemed to be a cleaner solution for now so we don't have to fill core code with tons of #ifdefs. #define RESTRICT #else #define RESTRICT __restrict__ #endif #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 //----------------------------------------------------------------------------- // 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 //----------------------------------------------------------------------------- // C++11 helpers //----------------------------------------------------------------------------- #define VALVE_CPP11 1 #if VALVE_CPP11 template struct C11RemoveReference { typedef T Type; }; template struct C11RemoveReference { typedef T Type; }; template struct C11RemoveReference { typedef T Type; }; template inline typename C11RemoveReference::Type&& Move(T&& obj) { return static_cast::Type&&>(obj); } template inline T&& Forward(typename C11RemoveReference::Type& obj) { return static_cast(obj); } template inline T&& Forward(typename C11RemoveReference::Type&& obj) { return static_cast(obj); } #endif //----------------------------------------------------------------------------- // Methods to invoke the constructor, copy constructor, and destructor //----------------------------------------------------------------------------- template inline T* Construct(T* pMemory) { return ::new(pMemory) T; } template inline T* Construct(T* pMemory, ARG1 a1) { return ::new(pMemory) T(a1); } template inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2) { return ::new(pMemory) T(a1, a2); } template inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3) { return ::new(pMemory) T(a1, a2, a3); } template inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4) { return ::new(pMemory) T(a1, a2, a3, a4); } template 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 inline T* CopyConstruct(T* pMemory, T const& src) { return ::new(pMemory) T(src); } template inline T* MoveConstruct(T* pMemory, T&& src) { return ::new(pMemory) T(Move(src)); } // [will] - Fixing a clang compile: unable to create a pseudo-destructor (aka a destructor that does nothing) for float __attribute__((__vector_size__(16))) // Fixed by specializing the Destroy function to not call destructor for that type. #if defined( __clang__ ) || defined (LINUX) template inline void Destruct(T* pMemory); template <> inline void Destruct(float __attribute__((__vector_size__(16)))* pMemory); #endif // __clang__ template inline void Destruct(T* pMemory) { pMemory->~T(); #ifdef _DEBUG memset(pMemory, 0xDD, sizeof(T)); #endif } // [will] - Fixing a clang compile: unable to create a pseudo-destructor (aka a destructor that does nothing) for float __attribute__((__vector_size__(16))) // Fixed by specializing the Destroy function to not call destructor for that type. #if defined( __clang__ ) || defined (LINUX) template <> inline void Destruct(float __attribute__((__vector_size__(16)))* pMemory) { #ifdef _DEBUG memset(pMemory, 0xDD, sizeof(float __attribute__((__vector_size__(16))))); #endif } #endif // __clang__ //----------------------------------------------------------------------------- // Processor Information: //----------------------------------------------------------------------------- struct CPUInformation { int m_Size; // Size of this structure, for forward compatibility. uint8_t m_nLogicalProcessors; // Number op logical processors. uint8_t m_nPhysicalProcessors; // Number of physical processors bool m_bRDTSC : 1, // Is RDTSC supported? m_bCMOV : 1, // Is CMOV supported? m_bFCMOV : 1, // Is FCMOV supported? m_bPOPCNT : 1, // Is POPCNT 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? bool m_bSSE3 : 1, m_bSSSE3 : 1, m_bSSE4a : 1, m_bSSE41 : 1, m_bSSE42 : 1, m_bAVX : 1; // Is AVX supported? int64_t m_Speed; // In cycles per second. // Any member below doesn't exist in the game engine! char* m_szProcessorID; // Processor vendor Identification. char* m_szProcessorBrand; // Processor brand string, if available uint32_t m_nModel; uint32_t m_nFeatures[3]; uint32_t m_nL1CacheSizeKb; uint32_t m_nL1CacheDesc; uint32_t m_nL2CacheSizeKb; uint32_t m_nL2CacheDesc; uint32_t m_nL3CacheSizeKb; uint32_t m_nL3CacheDesc; CPUInformation() : m_Size(0) { m_Size = 0; m_nLogicalProcessors = 0; m_nPhysicalProcessors = 0; m_bRDTSC = false; m_bCMOV = false; m_bCMOV = false; m_bFCMOV = false; m_bSSE = false; m_bSSE2 = false; m_b3DNow = false; m_bMMX = false; m_bHT = false; m_Speed = 0i64; m_szProcessorID = nullptr; m_szProcessorBrand = nullptr; m_nModel = 0; m_nFeatures[0] = 0; m_nFeatures[1] = 0; m_nFeatures[2] = 0; m_nL1CacheSizeKb = 0; m_nL1CacheDesc = 0; m_nL2CacheSizeKb = 0; m_nL2CacheDesc = 0; m_nL3CacheSizeKb = 0; m_nL3CacheDesc = 0; } }; #endif /* PLATFORM_H */