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;
}
   |