// clock.h #ifndef _PROGRAMCOMMON_WZCLOCK_H_ #define _PROGRAMCOMMON_WZCLOCK_H_ #include "wztypedef.h" #define CFS_MOVE (0x0001) #define CFS_RENDER (0x0002) typedef BOOL (__stdcall *FUNC_QueryPerformance)(LARGE_INTEGER*, int*); typedef unsigned long (__stdcall *FUNC_GetTickCount)(int*); //------------------------------------------------------------------------------ /** @class CClock */ class CClock { public: // »ý¼ºÀÚ/¼Ò¸êÀÚ CClock( void ); ~CClock( void ); // ±âº»ÀûÀÎ °ª ÃøÁ¤ void AutoMeasure( DWORD dwMillisecond = 0 ); // ÇöÀç Æ½ ¾ò±â (´ÜÀ§ : ƽ) LONGLONG GetCustomTick( void ) const; // ÇöÀç ½Ã°£ ¾ò±â (´ÜÀ§ : ¹Ð¸®ÃÊ) DWORD GetTickCount( void ) const; // ÇöÀç ÇÁ·¹ÀÓ ½Ã°£ ¾ò±â (´ÜÀ§ : ¹Ð¸®ÃÊ) DWORD GetCurrentTick( void ) const; // ¹Ð¸®ÃÊ´ç Æ½ ¼ö (´ÜÀ§ : ƽ) LONGLONG GetCustomTickPerMillisecond( void ) const; // ƽÀ» ¹Ð¸®ÃʷΠȯ»ê DWORD CustomTick2Millisecond( LONGLONG llTick ) const; // ¹Ð¸®Ãʸ¦ ƽÀ¸·Î ȯ»ê LONGLONG Millisecond2CustomTick( DWORD dwTick ) const; // ÃÊ´ç ÇÁ·¹ÀÓ ¼³Á¤ BOOL SetFramePerSecond( int iMaxFramePerSecond, BOOL bEnableRenderOnly = FALSE, int iMinFramePerSecond = 10, BOOL bFixedFrame = FALSE ); // ÃÊ´ç ÇÁ·¹ÀÓ ¼ö (ÃÖ´ë ÇÁ·¹ÀÓÀÎ °æ¿ì) int GetFramePerSecond( void ) const; // ´©Àû ÇÁ·¹ÀÓ ¼ö long GetFrameCount( void ) const; // Move, Render ¿©ºÎ (¸Å ÇÁ·¹ÀÓ È£Ãâ) WORD CheckFrameSkipping( DWORD* pdwTick ); // ¸¶Áö¸· Move ½Ã°£ ¾ò±â (´ÜÀ§ : ¹Ð¸®ÃÊ) DWORD GetFrameMoveTick( void ); // ¸¶Áö¸· Render ½Ã°£ ¾ò±â (´ÜÀ§ : ¹Ð¸®ÃÊ) DWORD GetRenderTick( void ); // ¸¶Áö¸· ÇÁ·¹ÀÓ Æ½ Àç¼³Á¤ void Reset( void ); // Æò±Õ ÇÁ·¹ÀÓ ½Ã°£ ¾ò±â DWORD GetAvgFrameTime( void ) const; // Æò±Õ ·»´õ¸µ ½Ã°£ ¾ò±â DWORD GetAvgRenderTime( void ) const; // ¿ÜºÎ º¸¾ÈŸÀÌ¸Ó ÇÔ¼öÆ÷ÀÎÅÍ ¼¼ÆÃ void SetClockFunction(FUNC_QueryPerformance pFuncPerformanceCount, FUNC_QueryPerformance pFuncPerformanceFrequency, FUNC_GetTickCount pFuncGetTickCount); // QueryPerformanceCounter ·¦ÇÎÇÔ¼ö BOOL QueryPerformanceCounterSecure(LARGE_INTEGER* pPerformanceCount) const; // QueryPerformanceFrequency ·¦ÇÎÇÔ¼ö BOOL QueryPerformanceFrequencySecure(LARGE_INTEGER* pPerformanceFrequency) const; // GetTickCount ·¦ÇÎÇÔ¼ö DWORD GetTickCountSecure() const; // ŸÀ̸ÓÇÔ¼ö ¿¡·¯ÄÚµå ¾ò±â int GetErrorCode(); FUNC_QueryPerformance GetFuncPerformanceCount(); FUNC_QueryPerformance GetFuncPerformanceFrequency(); FUNC_GetTickCount GetFuncGetTickCount(); private: // From¿¡¼­ To±îÁöÀÇ Áö³­ ƽ ¾ò±â (To - From) DWORD GetPassTick( DWORD dwTickTo, DWORD dwTickFrom ) const; private: enum { TICK_MAXVALUE = 0xffffffff }; LONGLONG m_llTicksPerMsec; // ¹Ð¸®ÃÊ´ç Æ½ ¼ö (´ÜÀ§ : ƽ) LONGLONG m_llTicksPerFrame_Max; // ÃÖ´ë ÇÁ·¹ÀÓÀ϶§ ÇÁ·¹ÀÓ´ç Æ½ ¼ö (´ÜÀ§ : ƽ) LONGLONG m_llTicksPerFrame_Min; // ÃÖ¼Ò ÇÁ·¹ÀÓÀ϶§ ÇÁ·¹ÀÓ´ç Æ½ ¼ö (´ÜÀ§ : ƽ) int m_iMaxFramePerSec; // ÃÊ´ç ÃÖ´ë ÇÁ·¹ÀÓ ¼ö (Èñ¸Á ÇÁ·¹ÀÓ ¼ö) int m_iMinFramePerSec; // ÃÊ´ç ÃÖ¼Ò ÇÁ·¹ÀÓ ¼ö LONGLONG m_llLatestFrameTick; // ¸¶Áö¸· ÇÁ·¹ÀÓ Æ½ (´ÜÀ§ : ƽ) DWORD m_dwBaseTime; // Base ½Ã°£ (´ÜÀ§ : ¹Ð¸®ÃÊ) DWORD m_dwLatestFrameMoveTime; // ¸¶Áö¸· Move ½Ã°£ (´ÜÀ§ : ¹Ð¸®ÃÊ) DWORD m_dwLatestRenderTime; // ¸¶Áö¸· Render ½Ã°£ (´ÜÀ§ : ¹Ð¸®ÃÊ) long m_lFrameCount; // ´©Àû ÇÁ·¹ÀÓ ¼ö float m_fAvgFrameTime; // Æò±Õ ÇÁ·¹ÀÓ ½Ã°£ (´ÜÀ§ : ¹Ð¸®ÃÊ) float m_fAvgRenderTime; // Æò±Õ ·»´õ¸µ ½Ã°£ (´ÜÀ§ : ¹Ð¸®ÃÊ) FUNC_QueryPerformance m_pQueryPerformanceCounter; FUNC_QueryPerformance m_QueryPerformanceFrequency; FUNC_GetTickCount m_pGetRickCount; static int s_iErrorCode; }; //------------------------------------------------------------------------------ /** ÇöÀç Æ½ ¾ò±â (´ÜÀ§ : ƽ) */ inline LONGLONG CClock::GetCustomTick( void ) const { LARGE_INTEGER liCounter; QueryPerformanceCounterSecure(&liCounter); return ( (UINT64)liCounter.QuadPart ); } //------------------------------------------------------------------------------ /** ÇöÀç Æ½ ¾ò±â (´ÜÀ§ : ¹Ð¸®ÃÊ) */ inline DWORD CClock::GetTickCount( void ) const { return ( (DWORD)( GetCustomTick() / m_llTicksPerMsec ) ); } //------------------------------------------------------------------------------ /** ÇöÀç(¸¶Áö¸·) ÇÁ·¹ÀÓ ½Ã°£ ¾ò±â - ÇÑ ÇÁ·¹ÀÓ³» µ¿ÀÏ (´ÜÀ§ : ¹Ð¸®ÃÊ) */ inline DWORD CClock::GetCurrentTick( void ) const { return ( (DWORD)( m_llLatestFrameTick / m_llTicksPerMsec ) ); } //------------------------------------------------------------------------------ /** ¹Ð¸®ÃÊ´ç Æ½ ¼ö (´ÜÀ§ : ƽ) */ inline LONGLONG CClock::GetCustomTickPerMillisecond( void ) const { return m_llTicksPerMsec; } //------------------------------------------------------------------------------ /** ƽÀ» ¹Ð¸®ÃʷΠȯ»ê (´ÜÀ§ : ¹Ð¸®ÃÊ) */ inline DWORD CClock::CustomTick2Millisecond( LONGLONG llTick ) const { return ( ( DWORD)( llTick / m_llTicksPerMsec ) ); } //------------------------------------------------------------------------------ /** ¹Ð¸®Ãʸ¦ ƽÀ¸·Î ȯ»ê (´ÜÀ§ : ƽ) */ inline LONGLONG CClock::Millisecond2CustomTick( DWORD dwTick ) const { return ( dwTick * m_llTicksPerMsec ); } //------------------------------------------------------------------------------ /** ÃÊ´ç ÃÖ´ë(Èñ¸Á) ÇÁ·¹ÀÓ ¼ö ¾ò±â */ inline int CClock::GetFramePerSecond( void ) const { return m_iMaxFramePerSec; } //------------------------------------------------------------------------------ /** ´©Àû ÇÁ·¹ÀÓ ¼ö ¾ò±â */ inline long CClock::GetFrameCount( void ) const { return m_lFrameCount; } //------------------------------------------------------------------------------ /** From¿¡¼­ To±îÁöÀÇ Áö³­ ƽ ¾ò±â */ inline DWORD CClock::GetPassTick( DWORD dwTickTo, DWORD dwTickFrom ) const { return ( ( dwTickTo < dwTickFrom ) ? TICK_MAXVALUE - ( dwTickFrom - dwTickTo ) : dwTickTo - dwTickFrom ); } //------------------------------------------------------------------------------ /** ¸¶Áö¸· Move ½Ã°£ ¾ò±â (´ÜÀ§ : ¹Ð¸®ÃÊ) */ inline DWORD CClock::GetFrameMoveTick( void ) { return ( m_dwLatestFrameMoveTime - m_dwBaseTime ); } //------------------------------------------------------------------------------ /** ¸¶Áö¸· Render ½Ã°£ ¾ò±â (´ÜÀ§ : ¹Ð¸®ÃÊ) */ inline DWORD CClock::GetRenderTick( void ) { return ( m_dwLatestRenderTime - m_dwBaseTime ); } //------------------------------------------------------------------------------ /** ¸¶Áö¸· ÇÁ·¹ÀÓ Æ½ Àç¼³Á¤ */ inline void CClock::Reset( void ) { m_llLatestFrameTick = GetCustomTick(); } //------------------------------------------------------------------------------ /** */ inline DWORD CClock::GetAvgFrameTime( void ) const { return (DWORD)m_fAvgFrameTime; } //------------------------------------------------------------------------------ /** */ inline DWORD CClock::GetAvgRenderTime( void ) const { return (DWORD)m_fAvgRenderTime; } inline void CClock::SetClockFunction(FUNC_QueryPerformance pFuncPerformanceCount, FUNC_QueryPerformance pFuncPerformanceFrequency, FUNC_GetTickCount pFuncGetTickCount) { m_pQueryPerformanceCounter = pFuncPerformanceCount; m_QueryPerformanceFrequency = pFuncPerformanceFrequency; m_pGetRickCount = pFuncGetTickCount; AutoMeasure(); } //------------------------------------------------------------------------------ /** */ inline BOOL CClock::QueryPerformanceCounterSecure(LARGE_INTEGER *pPerformanceCount) const { if (m_pQueryPerformanceCounter != NULL) { return m_pQueryPerformanceCounter(pPerformanceCount, &s_iErrorCode); } return ::QueryPerformanceCounter(pPerformanceCount); } //------------------------------------------------------------------------------ /** */ inline BOOL CClock::QueryPerformanceFrequencySecure(LARGE_INTEGER *pPerformanceFrequency) const { if (m_QueryPerformanceFrequency != NULL) { return m_QueryPerformanceFrequency(pPerformanceFrequency, &s_iErrorCode); } return ::QueryPerformanceFrequency(pPerformanceFrequency); } //------------------------------------------------------------------------------ /** */ inline DWORD CClock::GetTickCountSecure() const { if (m_pGetRickCount != NULL) { return m_pGetRickCount(&s_iErrorCode); } return ::GetTickCount(); } //------------------------------------------------------------------------------ /** */ inline int CClock::GetErrorCode() { return s_iErrorCode; } //------------------------------------------------------------------------------ /** */ inline FUNC_QueryPerformance CClock::GetFuncPerformanceCount() { return m_pQueryPerformanceCounter; } //------------------------------------------------------------------------------ /** */ inline FUNC_QueryPerformance CClock::GetFuncPerformanceFrequency() { return m_QueryPerformanceFrequency; } //------------------------------------------------------------------------------ /** */ inline FUNC_GetTickCount CClock::GetFuncGetTickCount() { return m_pGetRickCount; } #endif // _PROGRAMCOMMON_WZCLOCK_H_