diff options
Diffstat (limited to 'external/vpc/tier0/platform.cpp')
| -rw-r--r-- | external/vpc/tier0/platform.cpp | 559 |
1 files changed, 559 insertions, 0 deletions
diff --git a/external/vpc/tier0/platform.cpp b/external/vpc/tier0/platform.cpp new file mode 100644 index 0000000..15cb1f6 --- /dev/null +++ b/external/vpc/tier0/platform.cpp @@ -0,0 +1,559 @@ +//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "pch_tier0.h" +#include <time.h> + +#if defined(_WIN32) && !defined(_X360) +#define WINDOWS_LEAN_AND_MEAN +#define _WIN32_WINNT 0x0403 +#include <windows.h> +#endif +#include <errno.h> +#include <assert.h> +#include "tier0/platform.h" +#if defined( _X360 ) +#include "xbox/xbox_console.h" +#endif +#include "tier0/threadtools.h" + +#include "tier0/memalloc.h" + +#if defined( _PS3 ) +#include <cell/fios/fios_common.h> +#include <cell/fios/fios_memory.h> +#include <cell/fios/fios_configuration.h> +#include <sys/process.h> + +#if !defined(_CERT) +#include "sn/LibSN.h" +#endif + +/* +#include <sys/types.h> +#include <sys/process.h> +#include <sys/prx.h> + +#include <sysutil/sysutil_syscache.h> + +#include <cell/sysmodule.h> +*/ +#include <cell/fios/fios_time.h> +#endif // _PS3 + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef _WIN32 +static LARGE_INTEGER g_PerformanceFrequency; +static LARGE_INTEGER g_MSPerformanceFrequency; +static LARGE_INTEGER g_ClockStart; +static bool s_bTimeInitted; +#endif + +// Benchmark mode uses this heavy-handed method +static bool g_bBenchmarkMode = false; +#ifdef _WIN32 +static double g_FakeBenchmarkTime = 0; +static double g_FakeBenchmarkTimeInc = 1.0 / 66.0; +#endif + +static CThreadFastMutex g_LocalTimeMutex; + + +#ifdef _WIN32 +static void InitTime() +{ + if( !s_bTimeInitted ) + { + s_bTimeInitted = true; + QueryPerformanceFrequency(&g_PerformanceFrequency); + g_MSPerformanceFrequency.QuadPart = g_PerformanceFrequency.QuadPart / 1000; + QueryPerformanceCounter(&g_ClockStart); + } +} +#endif + +bool Plat_IsInBenchmarkMode() +{ + return g_bBenchmarkMode; +} + +void Plat_SetBenchmarkMode( bool bBenchmark ) +{ + g_bBenchmarkMode = bBenchmark; +} + +#ifdef _PS3 +cell::fios::abstime_t g_fiosLaunchTime = 0; +#endif + + +double Plat_FloatTime() +{ +#ifdef _WIN32 + if (! s_bTimeInitted ) + InitTime(); + if ( g_bBenchmarkMode ) + { + g_FakeBenchmarkTime += g_FakeBenchmarkTimeInc; + return g_FakeBenchmarkTime; + } + + LARGE_INTEGER CurrentTime; + + QueryPerformanceCounter( &CurrentTime ); + + double fRawSeconds = (double)( CurrentTime.QuadPart - g_ClockStart.QuadPart ) / (double)(g_PerformanceFrequency.QuadPart); + + return fRawSeconds; +#else + return cell::fios::FIOSAbstimeToMicroseconds( cell::fios::FIOSGetCurrentTime() - g_fiosLaunchTime ) * 1e-6; +#endif +} + + +uint32 Plat_MSTime() +{ +#ifdef _WIN32 + if (! s_bTimeInitted ) + InitTime(); + if ( g_bBenchmarkMode ) + { + g_FakeBenchmarkTime += g_FakeBenchmarkTimeInc; + return (uint32)(g_FakeBenchmarkTime * 1000.0); + } + + LARGE_INTEGER CurrentTime; + + QueryPerformanceCounter( &CurrentTime ); + + return (uint32) ( ( CurrentTime.QuadPart - g_ClockStart.QuadPart ) / g_MSPerformanceFrequency.QuadPart); +#elif defined(_PS3) + return (uint32) cell::fios::FIOSAbstimeToMilliseconds( cell::fios::FIOSGetCurrentTime() - g_fiosLaunchTime ); +#else + #error +#endif +} + +uint64 Timer_GetTimeUS() +{ +#ifdef _PS3 + return cell::fios::FIOSAbstimeToMicroseconds( cell::fios::FIOSGetCurrentTime() - g_fiosLaunchTime ); +#else + return uint64( Plat_FloatTime() * 1000000 ); +#endif +} + +uint64 Plat_GetClockStart() +{ +#if defined( _WIN32 ) + if ( !s_bTimeInitted ) + InitTime(); + + return g_ClockStart.QuadPart; +#elif defined( _PS3 ) + return g_fiosLaunchTime; +#else + return 0; +#endif +} + +void Plat_GetLocalTime( struct tm *pNow ) +{ + // We just provide a wrapper on this function so we can protect access to time() everywhere. + time_t ltime; + time( <ime ); + + Plat_ConvertToLocalTime( ltime, pNow ); +} + +void Plat_ConvertToLocalTime( uint64 nTime, struct tm *pNow ) +{ + // Since localtime() returns a global, we need to protect against multiple threads stomping it. + g_LocalTimeMutex.Lock(); + + time_t ltime = (time_t)nTime; + tm *pTime = localtime( <ime ); + if ( pTime ) + *pNow = *pTime; + else + memset( pNow, 0, sizeof( *pNow ) ); + + g_LocalTimeMutex.Unlock(); +} + +void Plat_GetTimeString( struct tm *pTime, char *pOut, int nMaxBytes ) +{ + g_LocalTimeMutex.Lock(); + + char *pStr = asctime( pTime ); + strncpy( pOut, pStr, nMaxBytes ); + pOut[nMaxBytes-1] = 0; + + g_LocalTimeMutex.Unlock(); +} + + +void Plat_gmtime( uint64 nTime, struct tm *pTime ) +{ + time_t tmtTime = nTime; +#ifdef _PS3 + struct tm * tmp = gmtime( &tmtTime ); + * pTime = * tmp; +#else + gmtime_s( pTime, &tmtTime ); +#endif +} + +time_t Plat_timegm( struct tm *timeptr ) +{ +#ifndef _GAMECONSOLE + return _mkgmtime( timeptr ); +#else + int *pnCrashHereBecauseConsolesDontSupportMkGmTime = 0; + *pnCrashHereBecauseConsolesDontSupportMkGmTime = 0; + return 0; +#endif +} + +void Plat_GetModuleFilename( char *pOut, int nMaxBytes ) +{ +#ifdef PLATFORM_WINDOWS_PC + GetModuleFileName( NULL, pOut, nMaxBytes ); + if ( GetLastError() != ERROR_SUCCESS ) + Error( "Plat_GetModuleFilename: The buffer given is too small (%d bytes).", nMaxBytes ); +#elif PLATFORM_X360 + pOut[0] = 0x00; // return null string on Xbox 360 +#else + // We shouldn't need this on POSIX. + Assert( false ); + pOut[0] = 0x00; // Null the returned string in release builds +#endif +} + +void Plat_ExitProcess( int nCode ) +{ +#if defined( _WIN32 ) && !defined( _X360 ) + // We don't want global destructors in our process OR in any DLL to get executed. + // _exit() avoids calling global destructors in our module, but not in other DLLs. + TerminateProcess( GetCurrentProcess(), nCode ); +#elif defined(_PS3) + // We do not use this path to exit on PS3 (naturally), rather we want a clear crash: + int *x = NULL; *x = 1; +#else + _exit( nCode ); +#endif +} + +void GetCurrentDate( int *pDay, int *pMonth, int *pYear ) +{ + struct tm long_time; + Plat_GetLocalTime( &long_time ); + + *pDay = long_time.tm_mday; + *pMonth = long_time.tm_mon + 1; + *pYear = long_time.tm_year + 1900; +} + +// Wraps the thread-safe versions of asctime. buf must be at least 26 bytes +char *Plat_asctime( const struct tm *tm, char *buf, size_t bufsize ) +{ +#ifdef _PS3 + snprintf( buf, bufsize, "%s", asctime(tm) ); + return buf; +#else + if ( EINVAL == asctime_s( buf, bufsize, tm ) ) + return NULL; + else + return buf; +#endif +} + + +// Wraps the thread-safe versions of ctime. buf must be at least 26 bytes +char *Plat_ctime( const time_t *timep, char *buf, size_t bufsize ) +{ +#ifdef _PS3 + snprintf( buf, bufsize, "%s", ctime( timep ) ); + return buf; +#else + if ( EINVAL == ctime_s( buf, bufsize, timep ) ) + return NULL; + else + return buf; +#endif +} + + +// Wraps the thread-safe versions of gmtime +struct tm *Plat_gmtime( const time_t *timep, struct tm *result ) +{ +#ifdef _PS3 + *result = *gmtime( timep ); + return result; +#else + if ( EINVAL == gmtime_s( result, timep ) ) + return NULL; + else + return result; +#endif +} + + +// Wraps the thread-safe versions of localtime +struct tm *Plat_localtime( const time_t *timep, struct tm *result ) +{ +#ifdef _PS3 + *result = *localtime( timep ); + return result; +#else + if ( EINVAL == localtime_s( result, timep ) ) + return NULL; + else + return result; +#endif +} + +bool vtune( bool resume ) +{ +#if IS_WINDOWS_PC + static bool bInitialized = false; + static void (__cdecl *VTResume)(void) = NULL; + static void (__cdecl *VTPause) (void) = NULL; + + // Grab the Pause and Resume function pointers from the VTune DLL the first time through: + if( !bInitialized ) + { + bInitialized = true; + + HINSTANCE pVTuneDLL = LoadLibrary( "vtuneapi.dll" ); + + if( pVTuneDLL ) + { + VTResume = (void(__cdecl *)())GetProcAddress( pVTuneDLL, "VTResume" ); + VTPause = (void(__cdecl *)())GetProcAddress( pVTuneDLL, "VTPause" ); + } + } + + // Call the appropriate function, as indicated by the argument: + if( resume && VTResume ) + { + VTResume(); + return true; + + } + else if( !resume && VTPause ) + { + VTPause(); + return true; + } +#endif + return false; +} + +bool Plat_IsInDebugSession() +{ +#if defined( _X360 ) + return (XBX_IsDebuggerPresent() != 0); +#elif defined( _WIN32 ) + return (IsDebuggerPresent() != 0); +#elif defined( _PS3 ) && !defined(_CERT) + return snIsDebuggerPresent(); +#else + return false; +#endif +} + +void Plat_DebugString( const char * psz ) +{ +#ifdef _CERT + return; // do nothing! +#endif + +#if defined( _X360 ) + XBX_OutputDebugString( psz ); +#elif defined( _WIN32 ) + ::OutputDebugStringA( psz ); +#elif defined(_PS3) + printf("%s",psz); +#else + // do nothing? +#endif +} + + +#if defined( PLATFORM_WINDOWS_PC ) +void Plat_MessageBox( const char *pTitle, const char *pMessage ) +{ + MessageBox( NULL, pMessage, pTitle, MB_OK ); +} +#endif + +PlatOSVersion_t Plat_GetOSVersion() +{ +#ifdef PLATFORM_WINDOWS_PC + OSVERSIONINFO info; + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if ( GetVersionEx( &info ) ) + return (PlatOSVersion_t)info.dwMajorVersion; + return PLAT_OS_VERSION_UNKNOWN; +#elif defined( PLATFORM_X360 ) + return PLAT_OS_VERSION_XBOX360; +#else + return PLAT_OS_VERSION_UNKNOWN; +#endif +} + +#if defined( PLATFORM_PS3 ) +//copied from platform_posix.cpp +static char g_CmdLine[ 2048 ] = ""; +PLATFORM_INTERFACE void Plat_SetCommandLine( const char *cmdLine ) +{ + strncpy( g_CmdLine, cmdLine, sizeof(g_CmdLine) ); + g_CmdLine[ sizeof(g_CmdLine) -1 ] = 0; +} +#endif + +PLATFORM_INTERFACE const tchar *Plat_GetCommandLine() +{ +#if defined( _PS3 ) +#pragma message("Plat_GetCommandLine() not implemented on PS3") // **** + return g_CmdLine; +#elif defined( TCHAR_IS_WCHAR ) + return GetCommandLineW(); +#else + return GetCommandLine(); +#endif +} + +PLATFORM_INTERFACE const char *Plat_GetCommandLineA() +{ +#if defined( _PS3 ) +#pragma message("Plat_GetCommandLineA() not implemented on PS3") // **** + return g_CmdLine; +#else + return GetCommandLineA(); +#endif +} + + +//----------------------------------------------------------------------------- +// Dynamically load a function +//----------------------------------------------------------------------------- +#ifdef PLATFORM_WINDOWS + +void *Plat_GetProcAddress( const char *pszModule, const char *pszName ) +{ + HMODULE hModule = ::LoadLibrary( pszModule ); + return ( hModule ) ? ::GetProcAddress( hModule, pszName ) : NULL; +} + +#endif + + + +// -------------------------------------------------------------------------------------------------- // +// Memory stuff. +// +// DEPRECATED. Still here to support binary back compatability of tier0.dll +// +// -------------------------------------------------------------------------------------------------- // +#ifndef _X360 +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) + +typedef void (*Plat_AllocErrorFn)( unsigned long size ); + +void Plat_DefaultAllocErrorFn( unsigned long size ) +{ +} + +Plat_AllocErrorFn g_AllocError = Plat_DefaultAllocErrorFn; +#endif + +#if !defined( _X360 ) && !defined( _PS3 ) + + +CRITICAL_SECTION g_AllocCS; +class CAllocCSInit +{ +public: + CAllocCSInit() + { + InitializeCriticalSection( &g_AllocCS ); + } +} g_AllocCSInit; + + +PLATFORM_INTERFACE void* Plat_Alloc( unsigned long size ) +{ + EnterCriticalSection( &g_AllocCS ); +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) + void *pRet = MemAlloc_Alloc( size ); +#else + void *pRet = malloc( size ); +#endif + LeaveCriticalSection( &g_AllocCS ); + if ( pRet ) + { + return pRet; + } + else + { +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) + g_AllocError( size ); +#endif + return 0; + } +} + + +PLATFORM_INTERFACE void* Plat_Realloc( void *ptr, unsigned long size ) +{ + EnterCriticalSection( &g_AllocCS ); +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) + void *pRet = g_pMemAlloc->Realloc( ptr, size ); +#else + void *pRet = realloc( ptr, size ); +#endif + LeaveCriticalSection( &g_AllocCS ); + if ( pRet ) + { + return pRet; + } + else + { +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) + g_AllocError( size ); +#endif + return 0; + } +} + + +PLATFORM_INTERFACE void Plat_Free( void *ptr ) +{ + EnterCriticalSection( &g_AllocCS ); +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) + g_pMemAlloc->Free( ptr ); +#else + free( ptr ); +#endif + LeaveCriticalSection( &g_AllocCS ); +} + +#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE) +PLATFORM_INTERFACE void Plat_SetAllocErrorFn( Plat_AllocErrorFn fn ) +{ + g_AllocError = fn; +} +#endif + +#endif + + +#endif
\ No newline at end of file |