const uint32 ticksPerSecond = 1000;
class cTimer
{
private:
bool isClassInit;
uint32 framesPerSecond;
float32 hzPerSecondTicks;
uint64 hzPerSecondRdtsc;
static uint64 rdtscPerMillesecond;
static uint64 rdtscPerSecond;
static bool usePerformanceCounter;
uint64 startTimeKeyRdtsc;
ulong32 startTimeKeyTicks;
uint64 startTimeKeyRdtscFPS;
ulong32 startTimeKeyTicksFPS;
uint64 startTimeKeyFPS;
float32 frameCount;
float32 timeElapsed;
uint64 timeKeyRdtsc;
ulong32 timeKeyTicks;
uint64 timeDifferenceRdtsc;
float32 timeDifferenceTicks;
uint64 timeRdtsc;
ulong32 timeTicks;
public:
cTimer( )
{
isClassInit = false;
}
~cTimer( )
{
}
void TimerInit( uint32 );
const float32& TimerFPS( );
bool TimerAlarm( );
void TimerElapsedTime( ulong32* , uint64* = NULL );
};
_INLINE bool cTimer::TimerAlarm( )
{
if( !isClassInit )
{
//ASSERTPRINT( isClassInit != false );
return false;
}
if( framesPerSecond )
{
if( usePerformanceCounter )
{
TimerElapsedTime( NULL, &timeKeyRdtsc );
timeDifferenceRdtsc = timeKeyRdtsc - startTimeKeyRdtsc;
if( timeDifferenceRdtsc >= hzPerSecondRdtsc )
{
startTimeKeyRdtsc = timeKeyRdtsc;
return true;
}
else
return false;
}
else
{
TimerElapsedTime( &timeKeyTicks );
if( timeKeyTicks < startTimeKeyTicks )
startTimeKeyTicks = 0;
timeDifferenceTicks = (float32)(timeKeyTicks - startTimeKeyTicks);
if( timeDifferenceTicks >= hzPerSecondTicks )
{
startTimeKeyTicks = timeKeyTicks;
return true;
}
else
return false;
}
}
else
return true;
}
_INLINE const float32& cTimer::TimerFPS( )
{
if( !isClassInit )
{
//ASSERTPRINT( isClassInit != false );
return frameCount;
}
if( usePerformanceCounter )
{
TimerElapsedTime( NULL, &timeKeyRdtsc );
timeDifferenceRdtsc = timeKeyRdtsc - startTimeKeyRdtscFPS;
if( timeDifferenceRdtsc == 0 )
{
//ASSERTPRINT( timeDifferenceRdtsc == 0 );
timeDifferenceRdtsc = 1;
}
frameCount = (float32)( rdtscPerSecond / timeDifferenceRdtsc );
startTimeKeyRdtscFPS = timeKeyRdtsc;
}
else
{
TimerElapsedTime( &timeKeyTicks );
if( timeKeyTicks < startTimeKeyTicksFPS )
startTimeKeyTicksFPS = 0;
timeDifferenceTicks = (float32)( timeKeyTicks - startTimeKeyTicksFPS );
if( timeDifferenceTicks < FLOAT32_EPSILON )
{
//ASSERTPRINT( timeDifferenceTicks >= FLOAT32_EPSILON );
timeDifferenceTicks = FLOAT32_EPSILON;
}
frameCount = (float32)ticksPerSecond / timeDifferenceTicks;
startTimeKeyTicksFPS = timeKeyTicks;
}
return frameCount;
}
_INLINE void cTimer::TimerElapsedTime( ulong32* timeTicks, uint64* timeRdtsc )
{
if( !isClassInit )
{
//ASSERTPRINT( isClassInit != false );
return;
}
if( timeRdtsc && usePerformanceCounter )
{
ulong32 dwLow, dwHigh;
__asm
{
rdtsc
mov dwLow, eax
mov dwHigh, edx
}
*timeRdtsc = ( (uint64)dwHigh << 32 ) | (uint64)dwLow;
}
if( timeTicks )
{
timeBeginPeriod( 1 );
*timeTicks = timeGetTime( );
timeEndPeriod( 1 );
}
}
uint64 cTimer::rdtscPerMillesecond = 0;
uint64 cTimer::rdtscPerSecond = 0;
bool cTimer::usePerformanceCounter = false;
void cTimer::TimerInit( uint32 fps )
{
if( isClassInit )
{
//ASSERTPRINT( isClassInit != true );
return;
}
isClassInit = true;
static bool isInit = false;
if( !isInit )
{
__try
{
ulong32 dwLow1, dwHigh1;
ulong32 dwLow2, dwHigh2;
uint64 time;
uint64 time2;
__asm
{
rdtsc
mov dwLow1, eax
mov dwHigh1, edx
}
Sleep( 50 );
__asm
{
rdtsc
mov dwLow2, eax
mov dwHigh2, edx
}
time = ( (unsigned __int64)dwHigh1 << 32 ) | (unsigned __int64)dwLow1;
time2 = ( (unsigned __int64)dwHigh2 << 32 ) | (unsigned __int64)dwLow2;
time2 -= time;
rdtscPerSecond = time2;
__asm
{
rdtsc
mov dwLow1, eax
mov dwHigh1, edx
}
Sleep( 50 );
__asm
{
rdtsc
mov dwLow2, eax
mov dwHigh2, edx
}
time = ( (unsigned __int64)dwHigh1 << 32 ) | (unsigned __int64)dwLow1;
time2 = ( (unsigned __int64)dwHigh2 << 32 ) | (unsigned __int64)dwLow2;
time2 -= time;
rdtscPerSecond += time2;
rdtscPerSecond *= 10;
rdtscPerMillesecond = rdtscPerSecond / (uint64)ticksPerSecond;
usePerformanceCounter = true;
DebugMsg( "Accurate rdtsc Timer Activated" );
LogEntry( "Accurate rdtsc Timer Activated\n\n");
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
usePerformanceCounter = false;
DebugMsg( "TimeGetTime Timer Activated" );
LogEntry( "TimeGetTime Timer Activated\n\n");
}
isInit = true;
}
framesPerSecond = fps;
if( framesPerSecond )
{
hzPerSecondTicks = (float32)ticksPerSecond/(float32)framesPerSecond;
if( usePerformanceCounter )
hzPerSecondRdtsc = rdtscPerSecond / framesPerSecond;
}
TimerElapsedTime( &startTimeKeyTicks, &startTimeKeyRdtsc );
startTimeKeyTicksFPS = startTimeKeyTicks;
startTimeKeyRdtscFPS = startTimeKeyRdtsc;
}
|