Wwise SDK 2017.1.9
_win32_2_ak_platform_funcs_8h_source
版本
menu_open
link
目标平台:
include/AK/Tools/Win32/AkPlatformFuncs.h
浏览该文件的文档。00001 /******************************************************************************* 00002 The content of this file includes portions of the AUDIOKINETIC Wwise Technology 00003 released in source code form as part of the SDK installer package. 00004 00005 Commercial License Usage 00006 00007 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology 00008 may use this file in accordance with the end user license agreement provided 00009 with the software or, alternatively, in accordance with the terms contained in a 00010 written agreement between you and Audiokinetic Inc. 00011 00012 Apache License Usage 00013 00014 Alternatively, this file may be used under the Apache License, Version 2.0 (the 00015 "Apache License"); you may not use this file except in compliance with the 00016 Apache License. You may obtain a copy of the Apache License at 00017 http://www.apache.org/licenses/LICENSE-2.0. 00018 00019 Unless required by applicable law or agreed to in writing, software distributed 00020 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 00021 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for 00022 the specific language governing permissions and limitations under the License. 00023 00024 Version: <VERSION> Build: <BUILDNUMBER> 00025 Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc. 00026 *******************************************************************************/ 00027 00028 #ifndef _AK_PLATFORM_FUNCS_H_ 00029 #define _AK_PLATFORM_FUNCS_H_ 00030 00031 #include "malloc.h" 00032 #include <AK/Tools/Common/AkAssert.h> 00033 #include <AK/SoundEngine/Common/AkTypes.h> 00034 #include <windows.h> 00035 //#define AK_ENABLE_PERF_RECORDING 00036 #if defined(AK_ENABLE_PERF_RECORDING) 00037 #include <stdio.h> 00038 #endif 00039 00040 #if defined(_WIN64) 00041 // on 64 bit, removes warning C4985: 'ceil': attributes not present on previous declaration. 00042 // see http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=294649 00043 #include <math.h> 00044 #endif // _WIN64 00045 #include <intrin.h> 00046 00047 //----------------------------------------------------------------------------- 00048 // Platform-specific thread properties definition. 00049 //----------------------------------------------------------------------------- 00050 struct AkThreadProperties 00051 { 00052 int nPriority; ///< Thread priority 00053 #ifdef AK_WIN_UNIVERSAL_APP 00054 PROCESSOR_NUMBER processorNumber;///< Ideal processor (passed to SetThreadIdealProcessorEx) 00055 #else 00056 AkUInt32 dwAffinityMask; ///< Affinity mask 00057 #endif 00058 AkUInt32 uStackSize; ///< Thread stack size. 00059 }; 00060 00061 //----------------------------------------------------------------------------- 00062 // External variables. 00063 //----------------------------------------------------------------------------- 00064 // g_fFreqRatio is used by time helpers to return time values in milliseconds. 00065 // It is declared and updated by the sound engine. 00066 namespace AK 00067 { 00068 extern AkReal32 g_fFreqRatio; 00069 } 00070 00071 //----------------------------------------------------------------------------- 00072 // Defines for Win32. 00073 //----------------------------------------------------------------------------- 00074 #define AK_DECLARE_THREAD_ROUTINE( FuncName ) DWORD WINAPI FuncName(LPVOID lpParameter) 00075 #define AK_THREAD_RETURN( _param_ ) return (_param_); 00076 #define AK_THREAD_ROUTINE_PARAMETER lpParameter 00077 #define AK_GET_THREAD_ROUTINE_PARAMETER_PTR(type) reinterpret_cast<type*>( AK_THREAD_ROUTINE_PARAMETER ) 00078 #define AK_RETURN_THREAD_OK 0x00000000 00079 #define AK_RETURN_THREAD_ERROR 0x00000001 00080 #if defined AK_CPU_X86_64 00081 #define AK_DEFAULT_STACK_SIZE (65536) 00082 #else 00083 #define AK_DEFAULT_STACK_SIZE (32768) 00084 #endif 00085 #define AK_THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL 00086 #define AK_THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_ABOVE_NORMAL 00087 00088 // NULL objects 00089 #define AK_NULL_THREAD NULL 00090 00091 #define AK_INFINITE INFINITE 00092 00093 #define AkMax(x1, x2) (((x1) > (x2))? (x1): (x2)) 00094 #define AkMin(x1, x2) (((x1) < (x2))? (x1): (x2)) 00095 #define AkClamp(x, min, max) ((x) < (min)) ? (min) : (((x) > (max) ? (max) : (x))) 00096 00097 namespace AKPLATFORM 00098 { 00099 // Simple automatic event API 00100 // ------------------------------------------------------------------ 00101 00102 /// Platform Independent Helper 00103 inline void AkClearEvent( AkEvent & out_event ) 00104 { 00105 out_event = NULL; 00106 } 00107 00108 /// Platform Independent Helper 00109 inline AKRESULT AkCreateEvent( AkEvent & out_event ) 00110 { 00111 #ifdef AK_USE_UWP_API 00112 out_event = CreateEventEx(nullptr, nullptr, 0, STANDARD_RIGHTS_ALL|EVENT_MODIFY_STATE); 00113 #else 00114 out_event = ::CreateEvent( NULL, // No security attributes 00115 false, // Reset type: automatic 00116 false, // Initial signaled state: not signaled 00117 NULL // No name 00118 ); 00119 #endif 00120 return ( out_event ) ? AK_Success : AK_Fail; 00121 } 00122 00123 /// Platform Independent Helper 00124 inline void AkDestroyEvent( AkEvent & io_event ) 00125 { 00126 if ( io_event ) 00127 ::CloseHandle( io_event ); 00128 io_event = NULL; 00129 } 00130 00131 /// Platform Independent Helper 00132 inline void AkWaitForEvent( AkEvent & in_event ) 00133 { 00134 #ifdef AK_USE_UWP_API 00135 #ifdef AK_ENABLE_ASSERTS 00136 DWORD dwWaitResult = 00137 #endif // AK_ENABLE_ASSERTS 00138 ::WaitForSingleObjectEx( in_event, INFINITE, FALSE ); 00139 AKASSERT( dwWaitResult == WAIT_OBJECT_0 ); 00140 #else 00141 AKVERIFY( ::WaitForSingleObject( in_event, INFINITE ) == WAIT_OBJECT_0 ); 00142 #endif 00143 } 00144 00145 /// Platform Independent Helper 00146 inline void AkSignalEvent( const AkEvent & in_event ) 00147 { 00148 AKVERIFY( ::SetEvent( in_event ) ); 00149 } 00150 00151 00152 // Atomic Operations 00153 // ------------------------------------------------------------------ 00154 00155 /// Platform Independent Helper 00156 inline AkInt32 AkInterlockedIncrement(AkAtomic32 * pValue) 00157 { 00158 return InterlockedIncrement( pValue ); 00159 } 00160 00161 /// Platform Independent Helper 00162 inline AkInt32 AkInterlockedDecrement(AkAtomic32 * pValue) 00163 { 00164 return InterlockedDecrement( pValue ); 00165 } 00166 00167 #ifdef AK_CPU_X86_64 00168 inline bool AkInterlockedCompareExchange( volatile AkAtomic64* io_pDest, AkInt64 in_newValue, AkInt64 in_expectedOldVal ) 00169 { 00170 return _InterlockedCompareExchange64(io_pDest, in_newValue, in_expectedOldVal) == in_expectedOldVal; 00171 } 00172 #endif 00173 00174 inline bool AkInterlockedCompareExchange(volatile AkAtomic32* io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal) 00175 { 00176 return InterlockedCompareExchange(io_pDest, in_newValue, in_expectedOldVal) == in_expectedOldVal; 00177 } 00178 00179 #if defined AK_CPU_X86 || defined AK_CPU_ARM 00180 inline bool AkInterlockedCompareExchange(volatile AkAtomicPtr* io_pDest, AkIntPtr in_newValue, AkIntPtr in_expectedOldVal) 00181 { 00182 return InterlockedCompareExchange((volatile LONG_PTR*)io_pDest, (LONG_PTR)in_newValue, (LONG_PTR)in_expectedOldVal) == in_expectedOldVal; 00183 } 00184 #endif 00185 00186 //Ensure that all write operations are complete. Necessary only on platforms that don't garentee the order of writes. 00187 inline void AkMemoryBarrier() 00188 { 00189 _ReadWriteBarrier(); 00190 } 00191 00192 // Threads 00193 // ------------------------------------------------------------------ 00194 00195 /// Platform Independent Helper 00196 inline bool AkIsValidThread( AkThread * in_pThread ) 00197 { 00198 return (*in_pThread != AK_NULL_THREAD); 00199 } 00200 00201 /// Platform Independent Helper 00202 inline void AkClearThread( AkThread * in_pThread ) 00203 { 00204 *in_pThread = AK_NULL_THREAD; 00205 } 00206 00207 /// Platform Independent Helper 00208 inline void AkCloseThread( AkThread * in_pThread ) 00209 { 00210 AKASSERT( in_pThread ); 00211 AKASSERT( *in_pThread ); 00212 AKVERIFY( ::CloseHandle( *in_pThread ) ); 00213 AkClearThread( in_pThread ); 00214 } 00215 00216 #define AkExitThread( _result ) return _result; 00217 00218 /// Platform Independent Helper 00219 inline void AkGetDefaultThreadProperties( AkThreadProperties & out_threadProperties ) 00220 { 00221 out_threadProperties.nPriority = AK_THREAD_PRIORITY_NORMAL; 00222 out_threadProperties.uStackSize= AK_DEFAULT_STACK_SIZE; 00223 #ifdef AK_WIN_UNIVERSAL_APP 00224 out_threadProperties.processorNumber.Group = 0; 00225 out_threadProperties.processorNumber.Number = MAXIMUM_PROCESSORS; 00226 out_threadProperties.processorNumber.Reserved = 0; 00227 #else 00228 out_threadProperties.dwAffinityMask = 0; 00229 #endif 00230 } 00231 00232 /// Set the name of a thread: see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx 00233 inline void AkSetThreadName( DWORD in_dwThreadID, LPCSTR in_szThreadName ) 00234 { 00235 const DWORD MS_VC_EXCEPTION=0x406D1388; 00236 00237 #pragma pack(push,8) 00238 typedef struct tagTHREADNAME_INFO 00239 { 00240 DWORD dwType; 00241 LPCSTR szName; 00242 DWORD dwThreadID; 00243 DWORD dwFlags; 00244 } THREADNAME_INFO; 00245 #pragma pack(pop) 00246 00247 THREADNAME_INFO info; 00248 info.dwType = 0x1000; 00249 info.szName = in_szThreadName; 00250 info.dwThreadID = in_dwThreadID; 00251 info.dwFlags = 0; 00252 00253 __try 00254 { 00255 RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); 00256 } 00257 #pragma warning(suppress: 6312 6322) 00258 __except(EXCEPTION_CONTINUE_EXECUTION) 00259 { 00260 } 00261 } 00262 00263 /// Platform Independent Helper 00264 inline void AkCreateThread( 00265 AkThreadRoutine pStartRoutine, // Thread routine. 00266 void * pParams, // Routine params. 00267 const AkThreadProperties & in_threadProperties, // Properties. NULL for default. 00268 AkThread * out_pThread, // Returned thread handle. 00269 const char * in_szThreadName ) // Opt thread name. 00270 { 00271 AKASSERT( out_pThread != NULL ); 00272 AKASSERT( (in_threadProperties.nPriority >= THREAD_PRIORITY_LOWEST && in_threadProperties.nPriority <= THREAD_PRIORITY_HIGHEST) 00273 || ( in_threadProperties.nPriority == THREAD_PRIORITY_TIME_CRITICAL ) ); 00274 00275 DWORD dwThreadID; 00276 *out_pThread = ::CreateThread( NULL, // No security attributes 00277 in_threadProperties.uStackSize, // StackSize (0 uses system default) 00278 pStartRoutine, // Thread start routine 00279 pParams, // Thread function parameter 00280 0, // Creation flags: create running 00281 &dwThreadID ); 00282 00283 // ::CreateThread() return NULL if it fails. 00284 if ( !*out_pThread ) 00285 { 00286 AkClearThread( out_pThread ); 00287 return; 00288 } 00289 00290 // Set thread name. 00291 AkSetThreadName( dwThreadID, in_szThreadName ); 00292 00293 // Set properties. 00294 if ( !::SetThreadPriority( *out_pThread, in_threadProperties.nPriority ) ) 00295 { 00296 AKASSERT( !"Failed setting thread priority" ); 00297 AkCloseThread( out_pThread ); 00298 return; 00299 } 00300 #ifdef AK_WIN_UNIVERSAL_APP 00301 if ( in_threadProperties.processorNumber.Number != MAXIMUM_PROCESSORS) 00302 { 00303 if ( !SetThreadIdealProcessorEx( *out_pThread, const_cast<PPROCESSOR_NUMBER>(&in_threadProperties.processorNumber), NULL) ) 00304 { 00305 AKASSERT( !"Failed setting thread ideal processor" ); 00306 AkCloseThread( out_pThread ); 00307 } 00308 } 00309 #else 00310 if (in_threadProperties.dwAffinityMask) 00311 { 00312 if (!::SetThreadAffinityMask(*out_pThread, in_threadProperties.dwAffinityMask)) 00313 { 00314 AKASSERT(!"Failed setting thread affinity mask"); 00315 AkCloseThread(out_pThread); 00316 } 00317 } 00318 #endif 00319 } 00320 00321 /// Platform Independent Helper 00322 inline void AkWaitForSingleThread( AkThread * in_pThread ) 00323 { 00324 AKASSERT( in_pThread ); 00325 AKASSERT( *in_pThread ); 00326 #ifdef AK_USE_UWP_API 00327 ::WaitForSingleObjectEx( *in_pThread, INFINITE, FALSE ); 00328 #else 00329 ::WaitForSingleObject( *in_pThread, INFINITE ); 00330 #endif 00331 } 00332 00333 /// Returns the calling thread's ID. 00334 inline AkThreadID CurrentThread() 00335 { 00336 return ::GetCurrentThreadId(); 00337 } 00338 00339 /// Platform Independent Helper 00340 inline void AkSleep( AkUInt32 in_ulMilliseconds ) 00341 { 00342 ::Sleep( in_ulMilliseconds ); 00343 } 00344 00345 // Optimized memory functions 00346 // -------------------------------------------------------------------- 00347 00348 /// Platform Independent Helper 00349 inline void AkMemCpy( void * pDest, const void * pSrc, AkUInt32 uSize ) 00350 { 00351 memcpy( pDest, pSrc, uSize ); 00352 } 00353 00354 /// Platform Independent Helper 00355 inline void AkMemSet( void * pDest, AkInt32 iVal, AkUInt32 uSize ) 00356 { 00357 memset( pDest, iVal, uSize ); 00358 } 00359 00360 // Time functions 00361 // ------------------------------------------------------------------ 00362 00363 /// Platform Independent Helper 00364 inline void PerformanceCounter( AkInt64 * out_piLastTime ) 00365 { 00366 ::QueryPerformanceCounter( (LARGE_INTEGER*)out_piLastTime ); 00367 } 00368 00369 /// Platform Independent Helper 00370 inline void PerformanceFrequency( AkInt64 * out_piFreq ) 00371 { 00372 ::QueryPerformanceFrequency( (LARGE_INTEGER*)out_piFreq ); 00373 } 00374 00375 /// Platform Independent Helper 00376 inline void UpdatePerformanceFrequency() 00377 { 00378 AkInt64 iFreq; 00379 PerformanceFrequency( &iFreq ); 00380 AK::g_fFreqRatio = (AkReal32)( iFreq / 1000 ); 00381 } 00382 00383 /// Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio. 00384 inline AkReal32 Elapsed( const AkInt64 & in_iNow, const AkInt64 & in_iStart ) 00385 { 00386 return ( in_iNow - in_iStart ) / AK::g_fFreqRatio; 00387 } 00388 00389 /// String conversion helper 00390 inline AkInt32 AkWideCharToChar( const wchar_t* in_pszUnicodeString, 00391 AkUInt32 in_uiOutBufferSize, 00392 char* io_pszAnsiString ) 00393 { 00394 int iWritten = ::WideCharToMultiByte(CP_ACP, // code page 00395 0, // performance and mapping flags 00396 in_pszUnicodeString, // wide-character string 00397 (int)AkMin( ( (AkUInt32)wcslen( in_pszUnicodeString )), in_uiOutBufferSize-1 ), // number of chars in string : -1 = NULL terminated string. 00398 io_pszAnsiString, // buffer for new string 00399 in_uiOutBufferSize, // size of buffer 00400 NULL, // default for unmappable chars 00401 NULL); // set when default char used 00402 io_pszAnsiString[iWritten] = 0; 00403 return iWritten; 00404 } 00405 00406 /// String conversion helper 00407 inline AkInt32 AkCharToWideChar( const char* in_pszAnsiString, 00408 AkUInt32 in_uiOutBufferSize, 00409 void* io_pvUnicodeStringBuffer ) 00410 { 00411 return ::MultiByteToWideChar( CP_ACP, // code page 00412 0, // performance and mapping flags 00413 in_pszAnsiString, // wide-character string 00414 -1, // number of chars in string : -1 = NULL terminated string. 00415 (wchar_t*)io_pvUnicodeStringBuffer, // buffer for new string 00416 in_uiOutBufferSize); // size of buffer 00417 } 00418 00419 /// String conversion helper 00420 inline AkInt32 AkUtf8ToWideChar( const char* in_pszUtf8String, 00421 AkUInt32 in_uiOutBufferSize, 00422 void* io_pvUnicodeStringBuffer ) 00423 { 00424 return ::MultiByteToWideChar( CP_UTF8, // code page 00425 0, // performance and mapping flags 00426 in_pszUtf8String, // wide-character string 00427 -1, // number of chars in string : -1 = NULL terminated string. 00428 (wchar_t*)io_pvUnicodeStringBuffer, // buffer for new string 00429 in_uiOutBufferSize); // size of buffer 00430 } 00431 00432 /// Safe unicode string copy. 00433 inline void SafeStrCpy( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars ) 00434 { 00435 size_t iSizeCopy = AkMin( in_uDestMaxNumChars - 1, wcslen( in_pSrc ) + 1 ); 00436 wcsncpy_s( in_pDest, in_uDestMaxNumChars, in_pSrc, iSizeCopy ); 00437 in_pDest[iSizeCopy] = '\0'; 00438 } 00439 00440 /// Safe string copy. 00441 inline void SafeStrCpy( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars ) 00442 { 00443 size_t iSizeCopy = AkMin( in_uDestMaxNumChars - 1, strlen( in_pSrc ) + 1 ); 00444 strncpy_s( in_pDest, in_uDestMaxNumChars, in_pSrc, iSizeCopy ); 00445 in_pDest[iSizeCopy] = '\0'; 00446 } 00447 00448 /// Safe unicode string concatenation. 00449 inline void SafeStrCat( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars ) 00450 { 00451 int iAvailableSize = (int)( in_uDestMaxNumChars - wcslen( in_pDest ) - 1 ); 00452 wcsncat_s( in_pDest, in_uDestMaxNumChars, in_pSrc, AkMin( iAvailableSize, (int)wcslen( in_pSrc ) ) ); 00453 } 00454 00455 /// Safe string concatenation. 00456 inline void SafeStrCat( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars ) 00457 { 00458 int iAvailableSize = (int)( in_uDestMaxNumChars - strlen( in_pDest ) - 1 ); 00459 strncat_s( in_pDest, in_uDestMaxNumChars, in_pSrc, AkMin( iAvailableSize, (int)strlen( in_pSrc ) ) ); 00460 } 00461 00462 /// Stack allocations. 00463 #define AkAlloca( _size_ ) _alloca( _size_ ) 00464 00465 /// Output a debug message on the console 00466 #if ! ( defined(AK_USE_UWP_API) || defined(AK_OPTIMIZED) ) 00467 inline void OutputDebugMsg( const wchar_t* in_pszMsg ) 00468 { 00469 OutputDebugStringW( in_pszMsg ); 00470 } 00471 00472 /// Output a debug message on the console 00473 inline void OutputDebugMsg( const char* in_pszMsg ) 00474 { 00475 OutputDebugStringA( in_pszMsg ); 00476 } 00477 #else 00478 inline void OutputDebugMsg( const wchar_t* ){} 00479 inline void OutputDebugMsg( const char* ){} 00480 #endif 00481 00482 /// Converts a wchar_t string to an AkOSChar string. 00483 /// \remark On some platforms the AkOSChar string simply points to the same string, 00484 /// on others a new buffer is allocated on the stack using AkAlloca. This means 00485 /// you must make sure that: 00486 /// - The source string stays valid and unmodified for as long as you need the 00487 /// AkOSChar string (for cases where they point to the same string) 00488 /// - The AkOSChar string is used within this scope only -- for example, do NOT 00489 /// return that string from a function (for cases where it is allocated on the stack) 00490 #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _wstring_ ) 00491 00492 /// Converts a char string to an AkOSChar string. 00493 /// \remark On some platforms the AkOSChar string simply points to the same string, 00494 /// on others a new buffer is allocated on the stack using AkAlloca. This means 00495 /// you must make sure that: 00496 /// - The source string stays valid and unmodified for as long as you need the 00497 /// AkOSChar string (for cases where they point to the same string) 00498 /// - The AkOSChar string is used within this scope only -- for example, do NOT 00499 /// return that string from a function (for cases where it is allocated on the stack) 00500 #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) \ 00501 _oscharstring_ = (AkOSChar*)AkAlloca( (1 + strlen( _astring_ )) * sizeof(AkOSChar)); \ 00502 AKPLATFORM::AkCharToWideChar( _astring_, (AkUInt32)(1 + strlen(_astring_ )), (AkOSChar*)( _oscharstring_ ) ) 00503 00504 /// Converts a AkOSChar string into wide char string. 00505 /// \remark On some platforms the AkOSChar string simply points to the same string, 00506 /// on others a new buffer is allocated on the stack using AkAlloca. This means 00507 /// you must make sure that: 00508 /// - The source string stays valid and unmodified for as long as you need the 00509 /// AkOSChar string (for cases where they point to the same string) 00510 /// - The AkOSChar string is used within this scope only -- for example, do NOT 00511 /// return that string from a function (for cases where it is allocated on the stack) 00512 #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) _wstring_ = _osstring_ 00513 00514 /// Converts a AkOSChar string into char string. 00515 /// \remark On some platforms the AkOSChar string simply points to the same string, 00516 /// on others a new buffer is allocated on the stack using AkAlloca. This means 00517 /// you must make sure that: 00518 /// - The source string stays valid and unmodified for as long as you need the 00519 /// AkOSChar string (for cases where they point to the same string) 00520 /// - The AkOSChar string is used within this scope only -- for example, do NOT 00521 /// return that string from a function (for cases where it is allocated on the stack) 00522 #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) \ 00523 _astring_ = (char*)AkAlloca( 1 + wcslen( _osstring_ )); \ 00524 AKPLATFORM::AkWideCharToChar( _osstring_, AkUInt32(1 + wcslen( _osstring_ )), _astring_ ); 00525 00526 /// Get the length, in characters, of a NULL-terminated AkUtf16 string 00527 /// \return The length, in characters, of the specified string (excluding terminating NULL) 00528 inline size_t AkUtf16StrLen( const AkUtf16* in_pStr ) 00529 { 00530 return ( wcslen( in_pStr ) ); 00531 } 00532 00533 /// Get the length, in characters, of a NULL-terminated AkOSChar string 00534 /// \return The length, in characters, of the specified string (excluding terminating NULL) 00535 inline size_t OsStrLen( const AkOSChar* in_pszString ) 00536 { 00537 return ( wcslen( in_pszString ) ); 00538 } 00539 00540 /// AkOSChar version of sprintf(). 00541 #define AK_OSPRINTF swprintf_s 00542 00543 /// Compare two NULL-terminated AkOSChar strings 00544 /// \return 00545 /// - < 0 if in_pszString1 < in_pszString2 00546 /// - 0 if the two strings are identical 00547 /// - > 0 if in_pszString1 > in_pszString2 00548 /// \remark The comparison is case-sensitive 00549 inline int OsStrCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2 ) 00550 { 00551 return ( wcscmp( in_pszString1, in_pszString2 ) ); 00552 } 00553 00554 #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize ) 00555 #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize ) 00556 #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize ) 00557 #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest ) 00558 #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest ) 00559 #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize ) 00560 00561 // Use with AkOSChar. 00562 #define AK_PATH_SEPARATOR (L"\\") 00563 00564 #if defined(AK_ENABLE_PERF_RECORDING) 00565 00566 static AkUInt32 g_uAkPerfRecExecCount = 0; 00567 static AkReal32 g_fAkPerfRecExecTime = 0.f; 00568 00569 #define AK_PERF_RECORDING_RESET() \ 00570 AKPLATFORM::g_uAkPerfRecExecCount = 0;\ 00571 AKPLATFORM::g_fAkPerfRecExecTime = 0.f; 00572 00573 #define AK_PERF_RECORDING_START( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ ) \ 00574 AkInt64 iAkPerfRecTimeBefore; \ 00575 if ( (AKPLATFORM::g_uAkPerfRecExecCount >= (__uExecutionCountStart__)) && (AKPLATFORM::g_uAkPerfRecExecCount <= (__uExecutionCountStop__)) ) \ 00576 AKPLATFORM::PerformanceCounter( &iAkPerfRecTimeBefore ); 00577 00578 #define AK_PERF_RECORDING_STOP( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ ) \ 00579 if ( (AKPLATFORM::g_uAkPerfRecExecCount >= (__uExecutionCountStart__)) && (AKPLATFORM::g_uAkPerfRecExecCount <= (__uExecutionCountStop__)) ) \ 00580 { \ 00581 AkInt64 iAkPerfRecTimeAfter; \ 00582 AKPLATFORM::PerformanceCounter( &iAkPerfRecTimeAfter ); \ 00583 AKPLATFORM::g_fAkPerfRecExecTime += AKPLATFORM::Elapsed( iAkPerfRecTimeAfter, iAkPerfRecTimeBefore ); \ 00584 if ( AKPLATFORM::g_uAkPerfRecExecCount == (__uExecutionCountStop__) ) \ 00585 { \ 00586 AkReal32 fAverageExecutionTime = AKPLATFORM::g_fAkPerfRecExecTime/((__uExecutionCountStop__)-(__uExecutionCountStart__)); \ 00587 char str[256]; \ 00588 sprintf_s(str, 256, "%s average execution time: %f\n", __StorageName__, fAverageExecutionTime); \ 00589 AKPLATFORM::OutputDebugMsg( str ); \ 00590 } \ 00591 } \ 00592 AKPLATFORM::g_uAkPerfRecExecCount++; 00593 #endif // AK_ENABLE_PERF_RECORDING 00594 } 00595 00596 #ifdef AK_ENABLE_INSTRUMENT 00597 #ifdef AK_XBOXONE 00598 #include <AK/Tools/XBoxOne/AkInstrument.h> 00599 #endif 00600 #endif 00601 00602 #endif // _AK_PLATFORM_FUNCS_H_