Archived

This topic is now archived and is closed to further replies.

Moe

Something funny about my timing code...

Recommended Posts

I decided that if I want to make a half decent program, it should run the same on all computers, regardless of processor speed. I started with the basic timing code that I had used in my 4 Elements entry and I added a few features. I understand things for the most part, but for some reason I think I am calculating either my frames per second or my delta value incorrectly. The delta value is the value used to make motion happen at a uniform speed. You take the speed of the object, in units per second, and time it by delta so that it doesn''t matter how many times per second the main loop is called, the objects will always move at a constant speed. Anyway, here is the code: In the header file:
  
//----------------------------------------//

// timer.h - header file for timer class/functions

//

//----------------------------------------//


//ifndef it so it doesn''t get included more than once

#ifndef _TIMER_H_
#define _TIMER_H_

//include the necessary file for the timer

#include <windows.h>
#include <mmsystem.h>		//for timeGetTime and some other windows stuff
#include "enginedef.h"


//the defines for the timer class

const int TIMER_OK		= 0;
const int NOT_YET		= 1;
const int TIMER_BAD		= 2;

//the new and improved timing class

class Timer
{
public:
	//constructor

	Timer();

	//variables

	LONGLONG CurrentTime;	//current time, in microseconds

	LONGLONG PreviousTime;	//time of previous frame, in microseconds

	LONGLONG NextTime;		//twhen the next 1/30th of a second is 

	float TimeScale;		//?

	DWORD TimeCount;	//number of milliseconds to the next 1/30th of a second

	LONGLONG PerformanceFrequency;	//counts per second

	float ElapsedMilliseconds;	//number of elapsed milliseconds since program start

	int ElapsedSeconds;	//the number of seconds its been running

	int ElapsedMinutes;	//number of elapsed minutes

	int ElapsedHours;		//number of elapsed hours

	float Delta;	//time difference between frames - used for time based movement

	int MillisecondCounter;	//number of times 1/30 of a second has passed - used in

							// the one second timer

	float CurrentFps;	//the current frames per second

	float LowestFps;	//the lowest frames per second

	float HighestFps;	//the highest frames per second


	//functions

	int InitializeTimer();		//initializes the timer stuff

	void UpdateTimer();			//updates the timing variables

	int CheckMillisecondTimer();	//checks to see if 1/30th of a second has passed

	int CheckSecondTimer();		//checks to see if 1 second has passed



};

#endif //for _TIMER_H_

  
The functions in the cpp file:
  
//--------------------------------------------------//

// Name: Timer()

// Desc: constructor - gives default values

//--------------------------------------------------//

Timer::Timer()
{
	CurrentFps = 0.0f;
	CurrentTime = 0;
	Delta = 0.0f;
	ElapsedHours = 0;
	ElapsedMilliseconds = 0.0f;
	ElapsedMinutes = 0;
	ElapsedSeconds = 0;
	HighestFps = 0.0f;
	LowestFps = 100.0f;
	MillisecondCounter = 0;
	NextTime = 0;
	PerformanceFrequency = 0;
	PreviousTime = 0;
	TimeCount = 0;
	TimeScale = 0.0f;

}


//--------------------------------------------------//

// Name: InitializeTimer()

// Desc: sets up the timer to start timing

//--------------------------------------------------//

int Timer::InitializeTimer()
{
	//check for a performance counter

	if(QueryPerformanceFrequency((LARGE_INTEGER *)&PerformanceFrequency) != 0)
	{
		//it got the performance frequency, so continue


		//fill in the time count - how many ticks to the next 1/30th of a second

		TimeCount = (long)PerformanceFrequency/30;
		QueryPerformanceCounter((LARGE_INTEGER *)&NextTime);
		TimeScale = (1.0f/(float)PerformanceFrequency);

	} else {
		// it failed

		return TIMER_BAD;
	}

	//save the time of the last frame

	PreviousTime = NextTime;

	//return ok

	return TIMER_OK;


}

//--------------------------------------------------//

// Name: UpdateTimer()

// Desc: updates the timing, what else?

//--------------------------------------------------//

void Timer::UpdateTimer()
{
	//update the current time

	QueryPerformanceCounter((LARGE_INTEGER *)&CurrentTime);

	//calculate the new Delta value

	Delta = (float)((CurrentTime-PreviousTime)*TimeScale);

	//re-calculate the frames per second

	CurrentFps = 1.0f/Delta;

	//see if the current fps is over/under the highest/lowest fps

	if(CurrentFps > HighestFps)
		HighestFps = CurrentFps;

	if(CurrentFps < LowestFps)
		LowestFps = CurrentFps;

	//update the running time variables

	ElapsedMilliseconds += (CurrentTime - PreviousTime)/1000;

	//if more than 1000 milliseconds have passed, its a second

	if(ElapsedMilliseconds >= 1000.0f)
	{
		//add one to the seconds and set the milliseconds back 1000 (because

		// there is 1000 milliseconds in a second)

		ElapsedSeconds += 1;
		ElapsedMilliseconds -= 1000.0f;
	}

	//do a similar thing with the seconds into minutes

	if(ElapsedSeconds >= 60)
	{
		ElapsedMinutes += 1;
		ElapsedSeconds -=60;
	}

	//now update the previous time

	PreviousTime = CurrentTime;

	//update the current time

	QueryPerformanceCounter((LARGE_INTEGER *)&CurrentTime);

}

//--------------------------------------------------//

// Name: CheckMillisecondTimer()

// Desc: checks to see if 1/30th of a second has passed

//--------------------------------------------------//

int Timer::CheckMillisecondTimer()
{
	//check to see if 1/30th of a second has passed since the last time

	if(CurrentTime >= NextTime)
	{
		//save the frame time

		PreviousTime = CurrentTime;

		//set the next time for the timer to fire

		NextTime = CurrentTime + TimeCount;

		//increment the one second counter to say that 1/30th of a second has passed

		MillisecondCounter++;

		return TIMER_OK;
	} else {

		//1/30th of a second has not passed yet

		return TIMER_BAD;
	}


	//return ok

	return TIMER_OK;	
}

//--------------------------------------------------//

// Name: CheckSecondTimer()

// Desc: checks to see if a one second interval has been reached

//--------------------------------------------------//

int Timer::CheckSecondTimer()
{
	//check to see if it has fired 30 times.  If it has, do the right return 

	//thing.  Counter is static, so it won''t be set to 0 every time the function

	//is called

	if(MillisecondCounter >= 30)
	{
		MillisecondCounter = 0;
		return TIMER_OK;
	} else 
		return NOT_YET;

	//return ok

	return TIMER_OK;

}
  
Do my calculations for Delta seem correct? Also, what else should I add do this to make it a better timing class? Moe''s site

Share this post


Link to post
Share on other sites
Well, can''t say what''s wrong ''cause I haven''t looked at it. But I''ll give you my timer class which works fine for me, although I''m sure there are some errors or something somewhere. But at least you can compare the two.


  
#ifndef CTIMER_H_
#define CTIMER_H_

#include <windows.h>
#include <stdio.h>
class CTimer
{
// high resolution timer

protected:
LARGE_INTEGER timerFrequency;
LARGE_INTEGER startCount;
LARGE_INTEGER endCount;

float timeAtGameStart;
LARGE_INTEGER ticksPerSecond;

float lastGameTime;

public:
CTimer(void);
~CTimer(void);

float GetGameTime();
bool InitGameTime();
float GetDeltaTime();
float GetAverageDeltaTime();

float GetFPS();
char *GetFPSChar();
};

#endif



  
#include "CTimer.h"

//-----------------------------------------------------

// CTimer::CTimer()

//-----------------------------------------------------

// Constructor...

//-----------------------------------------------------

CTimer::CTimer()
{
//InitGameTime();

}

//-----------------------------------------------------

// void CTimer::InitGameTime()

//-----------------------------------------------------

// Initiates gametime and sets fps variables..

//-----------------------------------------------------

bool CTimer::InitGameTime()
{

if (!QueryPerformanceFrequency(&ticksPerSecond))
return false;

timeAtGameStart = 0;
timeAtGameStart = GetGameTime();

if (!timeAtGameStart)
return false;

return true;
}

//-----------------------------------------------------

// float CTimer::GetGameTime()

//-----------------------------------------------------

// returns game time,

// substracts time at game start to get a

// more precise value

//-----------------------------------------------------

float CTimer::GetGameTime()
{
LARGE_INTEGER ticks;
float time;

QueryPerformanceCounter(&ticks);

time = (float)ticks.QuadPart/(float)ticksPerSecond.QuadPart;

time -= timeAtGameStart;

return time;
}

//-----------------------------------------------------

// float CTimer::GetDeltaTime()

//---------------------------------------------------------

// Returns delta time, time since last call to GetDeltaTime

//---------------------------------------------------------

float CTimer::GetDeltaTime()
{
float dt = GetGameTime() - lastGameTime;

// Increment with dt instead of calling

// GetGameTime() to avoid loosing time

lastGameTime += dt;

return dt;
}

//----------------------------------------------------

// float CTimer::GetAverageDeltaTime()

//----------------------------------------------------

// Returns delta time, averaged over 10 frames

//----------------------------------------------------

float CTimer::GetAverageDeltaTime()
{
float dt = GetGameTime() - lastGameTime;

lastGameTime += dt;

static int index = 0;
static float timeDeltas[10] = {0.0f};
float averageTimeDelta = 0.0f;

if(index < 10)
{
timeDeltas[index] = dt;
++index;
}
else
index = 0;

for(int i = 0; i < 10; i++)
{
averageTimeDelta += timeDeltas[i];
}

averageTimeDelta *= 0.1f;

return averageTimeDelta;
}


//-----------------------------------------------------

// float CTimer::GetFPS()

//-----------------------------------------------------

// Returns fps

//-----------------------------------------------------

float CTimer::GetFPS()
{
static float fps = 0.0;
static float fpsHold = 0.0;
static float lastFPSTime = 0.0;
float currentFPSTime = GetGameTime();

++fps;

if(currentFPSTime - lastFPSTime > 1.0)
{
lastFPSTime = currentFPSTime;
fpsHold = fps;

fps = 0.0;
}

return fpsHold;
}

//-----------------------------------------------------

// Returns fps in a string

//-----------------------------------------------------

char *CTimer::GetFPSChar()
{
static float fps = 0.0;
static float lastFPSTime = 0.0;
static char text[10] = {0};
float currentFPSTime = GetGameTime();

++fps;

if(currentFPSTime - lastFPSTime > 1.0)
{
lastFPSTime = currentFPSTime;

sprintf(text, "%d", (int)fps);

fps = 0.0;
}

return text;
}

//-----------------------------------------------------

// CTimer::~CTimer()

//-----------------------------------------------------

// Destructor

//-----------------------------------------------------

CTimer::~CTimer()
{
}


If anyone want to comment this so I could improve it, I would be more than happy. Good luck!

My site, My work, My thrashcan.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
couldnt you do something like this in ur main loop

while(quit == 0)
{
if(been 1 sec)
{
game code
}
}

but im not sure how to do timing myself so maybe its best u just ignoor me

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.