DevMaster.net Forums
[[ Home | Forums | 3D Engines Database | Wiki | Articles/Tutorials | Game Dev Jobs | IRC Chat Network | Contact Us ]]

Go Back   DevMaster.net Forums > Site Discussions > Code & Snapshot Discussion
User Name
Password
Register FAQ Members List Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
Old 05-07-2004, 08:54 PM   #1
zenogais
New Member
 
Join Date: May 2004
Posts: 17
Default

The following code is for a cross platform accurate timer. This timer also has the ability to calculate FPS if you so desire. For windows you can use either SDL_GetTicks() for a timer or QueryPerformanceCounter(), this of course requires SDL to be used.

Timer.h

Code:
#ifndef TIMERS_H #define TIMERS_H #if defined(_MSC_VER) || defined(_BORLANDC_) #define u64 __int64 #define WINDOWS #elif defined(__LINUX__) || defined(__MACOSX__) #define u64 unsigned long long #define LINUX #elif defined(__MINGW32__) #define u64 unsigned long long #define WINDOWS #endif class CTimer { public: CTimer(); CTimer(unsigned int type); CTimer(CTimer& oldTimer); ~CTimer() { } void SetTimerType(unsigned int newType); unsigned int GetTimerType(); void SetUpdateInterval(float newInterval); float GetUpdateInterval(); void Reset(); float GetFPS(); float GetTime(); private: void InitTimer(); float timeAtStart, lastUpdate, updateInterval, fps; u64 ticksPerSecond; unsigned int timerType, frames; }; enum Timers { Z_TIMER_SDL, //Uses SDL_GetTicks() for time Z_TIMER_QPC, //Uses QueryPerformanceCounter() for time (Windows Only) }; #endif

Timer.cpp

Code:
#include "Timers.h" #include <SDL.h> #ifdef WINDOWS #include <windows.h> #endif CTimer::CTimer() : timerType(Z_TIMER_SDL) { //We Default To SDL Timers, Then Reset Timers Reset(); } CTimer::CTimer(unsigned int type) { #if defined (LINUX) timerType = Z_TIMER_SDL; #elif defined (WINDOWS) timerType = type; #endif Reset(); } CTimer::CTimer(CTimer& oldTimer) { //Copy Old Data Into This Class timerType = oldTimer.timerType; timeAtStart = oldTimer.timeAtStart; ticksPerSecond = oldTimer.ticksPerSecond; //Do Timer Initialization InitTimer(); timeAtStart = GetTime(); } void CTimer::SetTimerType(unsigned int newType) { #if defined (WINDOWS) if(newType != Z_TIMER_SDL || newType != Z_TIMER_QPC) newType = Z_TIMER_SDL; timerType = newType; #elif defined (LINUX) timerType = Z_TIMER_SDL; #endif //Initialize The Timer InitTimer(); } unsigned int CTimer::GetTimerType() { return (timerType); } void CTimer::SetUpdateInterval(float newInterval) { updateInterval = newInterval; } float CTimer::GetUpdateInterval() { return updateInterval; } float CTimer::GetFPS() { frames++; float currentUpdate = GetTime(); if(currentUpdate - lastUpdate > updateInterval) { fps = frames / (currentUpdate - lastUpdate); lastUpdate = currentUpdate; frames = 0; } return (fps); } void CTimer::Reset() { timeAtStart = 0; ticksPerSecond = 0; frames = 0; lastUpdate = 0; fps = 0; updateInterval = 0.5; InitTimer(); timeAtStart = GetTime(); } void CTimer::InitTimer() { #if defined (WINDOWS) if(timerType == Z_TIMER_QPC) { //We Only Need To Do Initialization For the QPC Timer //We Need To Know How Often The Clock Is Updated if( !QueryPerformanceFrequency((LARGE_INTEGER*)&ticksPerSecond)) ticksPerSecond = 1000; } #endif } float CTimer::GetTime() { if(timerType == Z_TIMER_SDL) { return ((float)SDL_GetTicks()/1000.0f); } #if defined (WINDOWS) else if(timerType == Z_TIMER_QPC) { u64 ticks; float time; //This is the number of clock ticks since the start if( !QueryPerformanceCounter((LARGE_INTEGER*)&ticks)) ticks = (u64)timeGetTime(); //Divide by frequency to get time in seconds time = (float)(u64)ticks / (float)(u64)ticksPerSecond; //Calculate Actual Time time -= timeAtStart; return (time); } #endif return (0.0f); }

Hope you enjoy, I look forward to any questions or comments.
zenogais is offline   Reply With Quote
Old 05-07-2004, 09:02 PM   #2
Dia Kharrat
DevMaster Staff
 
Join Date: Jan 2003
Posts: 1,201
Default

Nice piece of code. One comment: since you're already doing a check on platform used, you might as well use the appropriate timer function in each platform in order to remove the dependency on SDL. It's not a big issue though
Dia Kharrat is offline   Reply With Quote
Old 05-08-2004, 02:23 AM   #3
baldurk
DevMaster Staff
 
baldurk's Avatar
 
Join Date: Jan 2003
Location: Mars
Posts: 1,141
Default

maybe I'm missing something, but why not just use SDL on both platforms? that removes a lot of the ugly preprocessor code.
___________________________________________
baldurk
He who knows not and knows that he knows not is ignorant. Teach him.
He who knows not and knows not that he knows not is a fool. Shun him.
baldurk is offline   Reply With Quote
Old 05-08-2004, 03:03 AM   #4
anubis
DevMaster Staff
 
anubis's Avatar
 
Join Date: Apr 2003
Location: Germany
Posts: 2,328
Default

using accurate and QPC in one sentence is kind of... well you know
___________________________________________
If Prolog is the answer, what is the question ?
anubis is offline   Reply With Quote
Old 08-25-2004, 01:41 AM   #5
fyhuang
Member
 
Join Date: Apr 2004
Posts: 48
Default

What about a counter that doesn't use SDL? What does SDL do to time on Linux, etc.?
___________________________________________
- FYHuang
&quot;Do, or do not. There is no 'try'.&quot; - Yoda
&quot;Shoot Pixels not People&quot; - Drakonite

[<a href='http://www.hytetech.com/altitude/forums/' target='_blank'>Altitude Forums</a>][<a href='http://www.hytetech.com/altitude/' target='_blank'>Altitude Technologies</a>]
fyhuang is offline   Reply With Quote
Old 08-25-2004, 06:28 AM   #6
baldurk
DevMaster Staff
 
baldurk's Avatar
 
Join Date: Jan 2003
Location: Mars
Posts: 1,141
Default

Quote:
Originally Posted by fyhuang
What about a counter that doesn't use SDL? What does SDL do to time on Linux, etc.?
[snapback]9549[/snapback]

gettimeofday() I'd imagine. As close to microsecond accuracy as a processor clock will allow.
___________________________________________
baldurk
He who knows not and knows that he knows not is ignorant. Teach him.
He who knows not and knows not that he knows not is a fool. Shun him.
baldurk is offline   Reply With Quote
Old 01-01-2005, 04:25 AM   #7
Chris
New Member
 
Join Date: Sep 2004
Location: Heidelberg, Old Europe
Posts: 23
Default

I hope you know that QueryPerformanceCounter is FAR from accurate ?
It's one of the most unpredictable functions you could have used. I strongly recommend changing that code to use timeGetTime ().

timeGetTime () guarantees a 1ms resolution on XP/2000 and 5ms on 98/ME/NT.

QueryPerformanceCounter () went as bad as using the 18.2 Hz AT timer on one of my machines. On my current Athlon XP 3000+ it has a resolution of approximately 3.5 MHz (according to QueryPerformanceFrequency) and I heard of a P4 2.2 GHz user who reported something like 1.17 GHz over at flipcode. Strange numbers, those, and he reported other strange effects, too.
Chris is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Forum Jump


All times are GMT -7. The time now is 10:39 PM.


Powered by vBulletin
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.