Table of Contents

include/AK/Tools/PS4/AkPlatformFuncs.h

Go to the documentation of this file.
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 <AK/SoundEngine/Common/AkTypes.h>
00032 #include <AK/Tools/Common/AkAssert.h>
00033 #include <sce_atomic.h>
00034 #include <sceerror.h>
00035 #include <wchar.h>
00036 #include <string.h>
00037 #include <stdio.h>
00038 #include <time.h>
00039 #include <kernel\eventflag.h>
00040 #include <unistd.h>
00041 #include <sys/time.h>
00042 #include <stdlib.h>
00043 
00044 
00045 //-----------------------------------------------------------------------------
00046 // Platform-specific thread properties definition.
00047 //-----------------------------------------------------------------------------
00048 struct AkThreadProperties
00049 {
00050     int                     nPriority;      ///< Thread priority
00051     SceKernelCpumask        dwAffinityMask; ///< Affinity mask
00052     size_t                  uStackSize;     ///< Thread stack size
00053     int                     uSchedPolicy;   ///< Thread scheduling policy
00054 };
00055 
00056 //-----------------------------------------------------------------------------
00057 // External variables.
00058 //-----------------------------------------------------------------------------
00059 // g_fFreqRatio is used by time helpers to return time values in milliseconds.
00060 // It is declared and updated by the sound engine.
00061 namespace AK
00062 {
00063     extern AkReal32 g_fFreqRatio;
00064 }
00065 
00066 //-----------------------------------------------------------------------------
00067 // Defines for PS4.
00068 //-----------------------------------------------------------------------------
00069 #define AK_DECLARE_THREAD_ROUTINE( FuncName )   void* FuncName(void* lpParameter)
00070 #define AK_THREAD_RETURN( _param_ )             return (_param_);
00071 #define AK_THREAD_ROUTINE_PARAMETER             lpParameter
00072 #define AK_GET_THREAD_ROUTINE_PARAMETER_PTR(type) reinterpret_cast<type*>( AK_THREAD_ROUTINE_PARAMETER )
00073 
00074 #define AK_RETURN_THREAD_OK                     0x00000000
00075 #define AK_RETURN_THREAD_ERROR                  0x00000001
00076 #define AK_DEFAULT_STACK_SIZE                   (128*1024)
00077 #define AK_THREAD_DEFAULT_SCHED_POLICY          SCE_KERNEL_SCHED_FIFO
00078 #define AK_THREAD_PRIORITY_NORMAL               SCE_KERNEL_PRIO_FIFO_DEFAULT
00079 #define AK_THREAD_PRIORITY_ABOVE_NORMAL         SCE_KERNEL_PRIO_FIFO_HIGHEST
00080 #define AK_THREAD_PRIORITY_BELOW_NORMAL         SCE_KERNEL_PRIO_FIFO_LOWEST
00081 
00082 #define AK_THREAD_AFFINITY_ALL                  63 // from binary 111111 setting the 6 available core to true. (ex: 4 << 1)
00083 #define AK_THREAD_AFFINITY_DEFAULT              AK_THREAD_AFFINITY_ALL
00084 
00085 // On PS4 this needs to be called regularly.
00086 #define AK_RELEASE_GPU_OFFLINE_FRAME            sce::Gnm::submitDone();
00087 
00088 // NULL objects
00089 #define AK_NULL_THREAD                          NULL
00090 
00091 #define AK_INFINITE                             (AK_UINT_MAX)
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 #ifndef AK_OPTIMIZED
00100     /// Output a debug message on the console (Ansi string)
00101     AkForceInline void OutputDebugMsg( const char* in_pszMsg )
00102     {
00103         fputs( in_pszMsg, stderr );
00104     }
00105     /// Output a debug message on the console (Unicode string)
00106     AkForceInline void OutputDebugMsg( const wchar_t* in_pszMsg )
00107     {
00108         fputws( in_pszMsg, stderr );
00109     }
00110 #else
00111     inline void OutputDebugMsg( const wchar_t* ){}
00112     inline void OutputDebugMsg( const char* ){}
00113 #endif
00114 
00115 
00116     // Simple automatic event API
00117     // ------------------------------------------------------------------
00118     
00119     /// Platform Independent Helper
00120     AkForceInline void AkClearEvent( AkEvent & out_event )
00121     {       
00122         out_event = NULL;
00123     }
00124 
00125     AkForceInline bool AkIsValidEvent(const AkEvent & in_event)
00126     {
00127         return (in_event != NULL);
00128     }
00129 
00130     AkForceInline AKRESULT AkCreateNamedEvent( AkEvent & out_event, const char* in_szName )
00131     {
00132         // NOTE: AkWaitForEvent uses the SCE_KERNEL_EVF_WAITMODE_CLEAR_PAT flag
00133         // to get the same behavior as an auto-reset Win32 event
00134         int ret = sceKernelCreateEventFlag(
00135             &out_event,
00136             in_szName,
00137             SCE_KERNEL_EVF_ATTR_MULTI,
00138             0 /* not signalled by default */,
00139             NULL /* No optional params */ );
00140 
00141         if( ret == SCE_OK && AkIsValidEvent(out_event))
00142             return AK_Success;
00143 
00144         AkClearEvent( out_event );
00145         return AK_Fail;
00146     }
00147 
00148     /// Platform Independent Helper
00149     AkForceInline AKRESULT AkCreateEvent( AkEvent & out_event )
00150     {
00151         return AkCreateNamedEvent( out_event, "AkEvent" );
00152     }
00153 
00154     /// Platform Independent Helper
00155     AkForceInline void AkDestroyEvent( AkEvent & io_event )
00156     {
00157         sceKernelDeleteEventFlag(io_event);
00158         AkClearEvent( io_event );
00159     }
00160 
00161     /// Platform Independent Helper
00162     AkForceInline void AkWaitForEvent( AkEvent & in_event )
00163     {
00164         AKVERIFY( sceKernelWaitEventFlag(
00165             in_event,
00166             1,
00167             SCE_KERNEL_EVF_WAITMODE_OR | SCE_KERNEL_EVF_WAITMODE_CLEAR_ALL,
00168             SCE_NULL,
00169             SCE_NULL) == 0 );
00170     }
00171 
00172     /// Platform Independent Helper
00173     AkForceInline void AkSignalEvent( const AkEvent & in_event )
00174     {
00175         AKVERIFY( sceKernelSetEventFlag( in_event, 1 ) == 0 );
00176     }
00177 
00178     // Atomic Operations
00179     // ------------------------------------------------------------------
00180 
00181     /// Platform Independent Helper
00182     AkForceInline AkInt32 AkInterlockedIncrement(AkAtomic32 * pValue)
00183     {
00184         return sceAtomicIncrement32( (volatile SceInt32 *) pValue ) + 1;
00185     }
00186 
00187     /// Platform Independent Helper
00188     AkForceInline AkInt32 AkInterlockedDecrement(AkAtomic32 * pValue)
00189     {
00190         return sceAtomicDecrement32( (volatile SceInt32 *) pValue ) - 1;
00191     }
00192 
00193     AkForceInline bool AkInterlockedCompareExchange(volatile AkAtomic64* io_pDest, AkInt64 in_newValue, AkInt64 in_expectedOldVal)
00194     {
00195         return sceAtomicCompareAndSwap64(io_pDest, in_expectedOldVal, in_newValue) == in_expectedOldVal;
00196     }
00197 
00198     AkForceInline bool AkInterlockedCompareExchange(volatile AkAtomic32* io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal)
00199     {
00200         return sceAtomicCompareAndSwap32(io_pDest, in_expectedOldVal, in_newValue) == in_expectedOldVal;
00201     }
00202 
00203     AkForceInline void AkMemoryBarrier()
00204     {
00205         __asm("sfence");
00206     }
00207 
00208     // Threads
00209     // ------------------------------------------------------------------
00210 
00211     /// Platform Independent Helper
00212     AkForceInline bool AkIsValidThread( AkThread * in_pThread )
00213     {
00214         return ( *in_pThread != AK_NULL_THREAD );
00215     }
00216 
00217     /// Platform Independent Helper
00218     AkForceInline void AkClearThread( AkThread * in_pThread )
00219     {
00220         *in_pThread = AK_NULL_THREAD;
00221     }
00222 
00223     /// Platform Independent Helper
00224     AkForceInline void AkCloseThread( AkThread * in_pThread )
00225     {
00226         AKASSERT( in_pThread );
00227         AKASSERT( *in_pThread );
00228 
00229         // #define KILL_THREAD(t) do { void *ret; scePthreadJoin(t,&ret); } while(false)
00230         // AKVERIFY( SCE_OK == sceKernelDeleteThread( *in_pThread ) );
00231         AkClearThread( in_pThread );
00232     }
00233 
00234     #define AkExitThread( _result ) return _result; // ?????
00235 
00236     /// Platform Independent Helper
00237     AkForceInline void AkGetDefaultThreadProperties( AkThreadProperties & out_threadProperties )
00238     {
00239         out_threadProperties.uStackSize     = AK_DEFAULT_STACK_SIZE;
00240         out_threadProperties.uSchedPolicy   = AK_THREAD_DEFAULT_SCHED_POLICY;
00241         out_threadProperties.nPriority      = AK_THREAD_PRIORITY_NORMAL;
00242         out_threadProperties.dwAffinityMask = AK_THREAD_AFFINITY_DEFAULT;
00243     }
00244 
00245     /// Platform Independent Helper
00246     inline void AkCreateThread( 
00247         AkThreadRoutine pStartRoutine,                  // Thread routine.
00248         void * pParams,                                 // Routine params.
00249         const AkThreadProperties & in_threadProperties, // Properties. NULL for default.
00250         AkThread * out_pThread,                         // Returned thread handle.
00251         const char * in_szThreadName )              // Opt thread name.
00252     {
00253         AKASSERT( out_pThread != NULL );
00254         
00255         ScePthreadAttr  attr;
00256         
00257         // Create the attr
00258         AKVERIFY(!scePthreadAttrInit(&attr));
00259         // Set the stack size
00260         AKVERIFY(!scePthreadAttrSetstacksize(&attr,in_threadProperties.uStackSize));
00261         AKVERIFY(!scePthreadAttrSetdetachstate(&attr, SCE_PTHREAD_CREATE_JOINABLE));
00262         AKVERIFY(!scePthreadAttrSetinheritsched(&attr, SCE_PTHREAD_EXPLICIT_SCHED));
00263         AKVERIFY(!scePthreadAttrSetaffinity(&attr,in_threadProperties.dwAffinityMask)); 
00264         
00265         // Try to set the thread policy
00266         int sched_policy = in_threadProperties.uSchedPolicy;
00267         if( scePthreadAttrSetschedpolicy( &attr, sched_policy )  )
00268         {
00269             AKASSERT( !"AKCreateThread invalid sched policy, will automatically set it to FIFO scheduling" );
00270             sched_policy = AK_THREAD_DEFAULT_SCHED_POLICY;
00271             AKVERIFY( !scePthreadAttrSetschedpolicy( &attr, sched_policy ));
00272         }
00273 
00274         int minPriority, maxPriority;
00275         minPriority = SCE_KERNEL_PRIO_FIFO_HIGHEST;
00276         maxPriority = SCE_KERNEL_PRIO_FIFO_LOWEST;
00277         
00278         // Set the thread priority if valid
00279         AKASSERT( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority );
00280         if(  in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority )
00281         {
00282             SceKernelSchedParam schedParam;
00283             AKVERIFY( scePthreadAttrGetschedparam(&attr, &schedParam) == 0 );
00284             schedParam.sched_priority = in_threadProperties.nPriority;
00285             AKVERIFY( scePthreadAttrSetschedparam(&attr, &schedParam) == 0 );
00286         }
00287 
00288         // Create the tread
00289         int threadError = scePthreadCreate(out_pThread, &attr, pStartRoutine, pParams, in_szThreadName);
00290         AKASSERT( threadError == 0 );
00291         AKVERIFY(!scePthreadAttrDestroy(&attr));
00292         
00293         if( threadError != 0 )
00294         {
00295             AkClearThread( out_pThread );
00296             return;
00297         }
00298         
00299         // ::CreateThread() return NULL if it fails.
00300         if ( !*out_pThread )
00301         {
00302             AkClearThread( out_pThread );
00303             return;
00304         }       
00305     }
00306 
00307     /// Platform Independent Helper
00308     AkForceInline void AkWaitForSingleThread( AkThread * in_pThread )
00309     {
00310         AKASSERT( in_pThread );
00311         AKASSERT( *in_pThread );
00312         AKVERIFY(!scePthreadJoin( *in_pThread, NULL ));
00313     }
00314 
00315     inline AkThreadID CurrentThread()
00316     {
00317         return scePthreadSelf();
00318     }
00319 
00320     /// Platform Independent Helper
00321     AkForceInline void AkSleep( AkUInt32 in_ulMilliseconds )
00322     {
00323         usleep( in_ulMilliseconds * 1000 );
00324     }
00325 
00326     // Optimized memory functions
00327     // --------------------------------------------------------------------
00328 
00329     /// Platform Independent Helper
00330     AkForceInline void AkMemCpy( void * pDest, const void * pSrc, AkUInt32 uSize )
00331     {
00332         memcpy( pDest, pSrc, uSize );
00333     }
00334 
00335     /// Platform Independent Helper
00336     AkForceInline void AkMemSet( void * pDest, AkInt32 iVal, AkUInt32 uSize )
00337     {
00338         memset( pDest, iVal, uSize );
00339     }
00340 
00341     // Time functions
00342     // ------------------------------------------------------------------
00343 
00344     /// Platform Independent Helper
00345     AkForceInline void PerformanceCounter( AkInt64 * out_piLastTime )
00346     {
00347         uint64_t uTime = sceKernelGetProcessTimeCounter();
00348         *out_piLastTime = (AkInt64)uTime;
00349     }
00350 
00351     /// Frequency of the PerformanceCounter() (ticks per second)
00352     AkForceInline void PerformanceFrequency( AkInt64 * out_piFreq )
00353     {
00354         *out_piFreq = (AkInt64)sceKernelGetProcessTimeCounterFrequency();
00355     }
00356 
00357     /// Platform Independent Helper
00358     AkForceInline void UpdatePerformanceFrequency()
00359     {
00360         AkInt64 iFreq;
00361         PerformanceFrequency( &iFreq );
00362         AK::g_fFreqRatio = (AkReal32)( iFreq / 1000 );
00363     }
00364 
00365     /// Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio.
00366     AkForceInline AkReal32 Elapsed( const AkInt64 & in_iNow, const AkInt64 & in_iStart )
00367     {
00368         return ( in_iNow - in_iStart ) / AK::g_fFreqRatio;
00369     }
00370 
00371     /// String conversion helper
00372     AkForceInline AkInt32 AkWideCharToChar( const wchar_t*  in_pszUnicodeString,
00373                                             AkUInt32        in_uiOutBufferSize,
00374                                             char*       io_pszAnsiString )
00375     {
00376         AKASSERT( io_pszAnsiString != NULL );
00377 
00378         mbstate_t state;
00379         memset (&state, '\0', sizeof (state));
00380 
00381         return (AkInt32)wcsrtombs(io_pszAnsiString,     // destination
00382                             &in_pszUnicodeString,   // source
00383                             in_uiOutBufferSize,     // destination length
00384                             &state);                // 
00385 
00386     }
00387     
00388     /// String conversion helper
00389     AkForceInline AkInt32 AkCharToWideChar( const char* in_pszAnsiString,
00390                                             AkUInt32            in_uiOutBufferSize,
00391                                             void*           io_pvUnicodeStringBuffer )
00392     {
00393         AKASSERT( io_pvUnicodeStringBuffer != NULL );
00394 
00395         mbstate_t state;
00396         memset (&state, '\0', sizeof (state));
00397 
00398         return (AkInt32)mbsrtowcs((wchar_t*)io_pvUnicodeStringBuffer,   // destination
00399                                     &in_pszAnsiString,                  // source
00400                                     in_uiOutBufferSize,                 // destination length
00401                                     &state);                            // 
00402     }
00403 
00404     AkForceInline AkInt32 AkUtf8ToWideChar( const char* in_pszUtf8String,
00405                                      AkUInt32       in_uiOutBufferSize,
00406                                      void*          io_pvUnicodeStringBuffer )
00407     {
00408         return AkCharToWideChar( in_pszUtf8String, in_uiOutBufferSize, (wchar_t*)io_pvUnicodeStringBuffer );
00409     }
00410 
00411     /// Safe unicode string copy.
00412     AkForceInline void SafeStrCpy( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
00413     {
00414         size_t uSizeCopy = AkMin( in_uDestMaxNumChars - 1, wcslen( in_pSrc ) + 1 );
00415         wcsncpy( in_pDest, in_pSrc, uSizeCopy );
00416         in_pDest[uSizeCopy] = '\0';
00417     }
00418 
00419     /// Safe ansi string copy.
00420     AkForceInline void SafeStrCpy( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
00421     {
00422         size_t uSizeCopy = AkMin( in_uDestMaxNumChars - 1, strlen( in_pSrc ) + 1 );
00423         strncpy( in_pDest, in_pSrc, uSizeCopy );
00424         in_pDest[uSizeCopy] = '\0';
00425     }
00426 
00427     /// Safe unicode string concatenation.
00428     AkForceInline void SafeStrCat( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
00429     {
00430         size_t uAvailableSize = ( in_uDestMaxNumChars - wcslen( in_pDest ) - 1 );
00431         wcsncat( in_pDest, in_pSrc, AkMin( uAvailableSize, wcslen( in_pSrc ) ) );
00432     }
00433 
00434     /// Safe ansi string concatenation.
00435     AkForceInline void SafeStrCat( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
00436     {
00437         size_t uAvailableSize = ( in_uDestMaxNumChars - strlen( in_pDest ) - 1 );
00438         strncat( in_pDest, in_pSrc, AkMin( uAvailableSize, strlen( in_pSrc ) ) );
00439     }
00440 
00441     /// Stack allocations.
00442     #define AkAlloca( _size_ ) alloca( _size_ ) 
00443 
00444     
00445 
00446     /// Converts a wchar_t string to an AkOSChar string.
00447     /// \remark On some platforms the AkOSChar string simply points to the same string,
00448     /// on others a new buffer is allocated on the stack using AkAlloca. This means
00449     /// you must make sure that:
00450     /// - The source string stays valid and unmodified for as long as you need the
00451     ///   AkOSChar string (for cases where they point to the same string)
00452     /// - The AkOSChar string is used within this scope only -- for example, do NOT
00453     ///   return that string from a function (for cases where it is allocated on the stack)
00454     #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) \
00455            _oscharstring_ = (AkOSChar*)AkAlloca( (1 + wcslen( _wstring_ )) * sizeof(AkOSChar) ); \
00456            AKPLATFORM::AkWideCharToChar( _wstring_ , (AkUInt32)(1 + wcslen( _wstring_ )), (AkOSChar*)( _oscharstring_ ) )
00457 
00458 
00459     /// Converts a char string to an AkOSChar string.
00460     /// \remark On some platforms the AkOSChar string simply points to the same string,
00461     /// on others a new buffer is allocated on the stack using AkAlloca. This means
00462     /// you must make sure that:
00463     /// - The source string stays valid and unmodified for as long as you need the
00464     ///   AkOSChar string (for cases where they point to the same string)
00465     /// - The AkOSChar string is used within this scope only -- for example, do NOT
00466     ///   return that string from a function (for cases where it is allocated on the stack)
00467     #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _astring_ )
00468 
00469     /// Converts a AkOSChar string into wide char string.
00470     /// \remark On some platforms the AkOSChar string simply points to the same string,
00471     /// on others a new buffer is allocated on the stack using AkAlloca. This means
00472     /// you must make sure that:
00473     /// - The source string stays valid and unmodified for as long as you need the
00474     ///   AkOSChar string (for cases where they point to the same string)
00475     /// - The AkOSChar string is used within this scope only -- for example, do NOT
00476     ///   return that string from a function (for cases where it is allocated on the stack)
00477     #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) \
00478         _wstring_ = (wchar_t*)AkAlloca((1+strlen(_osstring_)) * sizeof(wchar_t)); \
00479         AKPLATFORM::AkCharToWideChar( _osstring_, (AkUInt32)(1 + strlen(_osstring_ )), _wstring_ )
00480 
00481     /// Converts a AkOSChar string into char string.
00482     /// \remark On some platforms the AkOSChar string simply points to the same string,
00483     /// on others a new buffer is allocated on the stack using AkAlloca. This means
00484     /// you must make sure that:
00485     /// - The source string stays valid and unmodified for as long as you need the
00486     ///   AkOSChar string (for cases where they point to the same string)
00487     /// - The AkOSChar string is used within this scope only -- for example, do NOT
00488     ///   return that string from a function (for cases where it is allocated on the stack)
00489     #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) _astring_ = (char*)_osstring_
00490 
00491     /// Get the length, in characters, of a NULL-terminated AkUtf16 string
00492     /// \return The length, in characters, of the specified string (excluding terminating NULL)
00493     AkForceInline size_t AkUtf16StrLen( const AkUtf16* in_pStr )
00494     {
00495         return ( wcslen( in_pStr ) );
00496     }
00497 
00498     /// Get the length, in characters, of a NULL-terminated AkOSChar string
00499     /// \return The length, in characters, of the specified string (excluding terminating NULL)
00500     AkForceInline size_t OsStrLen( const AkOSChar* in_pszString )
00501     {
00502         return ( strlen( in_pszString ) );
00503     }
00504 
00505     /// AkOSChar version of sprintf().
00506     #define AK_OSPRINTF snprintf
00507 
00508     /// Compare two NULL-terminated AkOSChar strings
00509     /// \return
00510     /// - < 0 if in_pszString1 < in_pszString2
00511     /// -    0 if the two strings are identical
00512     /// - > 0 if in_pszString1 > in_pszString2
00513     /// \remark The comparison is case-sensitive
00514     AkForceInline int OsStrCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2 )
00515     {
00516         return ( strcmp( in_pszString1,  in_pszString2 ) );
00517     }
00518     
00519     #define AK_UTF16_TO_WCHAR(  in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::SafeStrCpy(     in_pdDest, in_pSrc, in_MaxSize )
00520     #define AK_WCHAR_TO_UTF16(  in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::SafeStrCpy(     in_pdDest, in_pSrc, in_MaxSize )
00521     #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
00522     #define AK_UTF16_TO_CHAR(   in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
00523     #define AK_CHAR_TO_UTF16(   in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )      
00524     #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )  
00525 
00526     // Use with AkOSChar.
00527     #define AK_PATH_SEPARATOR   ("/")
00528 
00529 }
00530 
00531 #ifdef AK_ENABLE_INSTRUMENT
00532 
00533 #include <perf.h>
00534 #include <sdk_version.h>
00535 #if SCE_ORBIS_SDK_VERSION >= 0x04500000
00536     #include <razorcpu.h>
00537     #ifndef SCE_RAZOR_MARKER_DISABLE_HUD
00538         #define SCE_RAZOR_MARKER_DISABLE_HUD 0
00539     #endif
00540 #endif
00541 
00542 class AkInstrumentScope
00543 {
00544 public:
00545     inline AkInstrumentScope( const char *in_pszZoneName ) 
00546     {
00547         sceRazorCpuPushMarkerStatic( in_pszZoneName, 0, SCE_RAZOR_MARKER_DISABLE_HUD );
00548     }
00549 
00550     inline ~AkInstrumentScope()
00551     {
00552         sceRazorCpuPopMarker();
00553     }
00554 };
00555 
00556 #define AK_INSTRUMENT_BEGIN( _zone_name_ ) sceRazorCpuPushMarkerStatic( text, 0, SCE_RAZOR_MARKER_DISABLE_HUD )
00557 #define AK_INSTRUMENT_BEGIN_C( _color_, _zone_name_ ) sceRazorCpuPushMarkerStatic( text, _color_, SCE_RAZOR_MARKER_DISABLE_HUD )
00558 #define AK_INSTRUMENT_END( _zone_name_ ) sceRazorCpuPopMarker()
00559 #define AK_INSTRUMENT_SCOPE( _zone_name_ ) AkInstrumentScope akInstrumentScope_##__LINE__(_zone_name_)
00560 
00561 #define AK_INSTRUMENT_IDLE_BEGIN( _zone_name_ )
00562 #define AK_INSTRUMENT_IDLE_END( _zone_name_ )
00563 #define AK_INSTRUMENT_IDLE_SCOPE( _zone_name_ )
00564 
00565 #define AK_INSTRUMENT_STALL_BEGIN( _zone_name_ )
00566 #define AK_INSTRUMENT_STALL_END( _zone_name_ )
00567 #define AK_INSTRUMENT_STALL_SCOPE( _zone_name_ )
00568 
00569 #define AK_INSTRUMENT_THREAD_START( _thread_name_ )
00570 
00571 #endif // AK_ENABLE_INSTRUMENT
00572 
00573 #endif  // _AK_PLATFORM_FUNCS_H_