4
\$\begingroup\$

I need to be able to find out how many milliseconds since that last update. Is there any way I can find it out with time rather then a thread that counts like I did below?

#include <iostream>
#include<windows.h>
#include<time.h>
#include<process.h>

using namespace std;

int Timer = 0;
int LastTimer = 0;
bool End = false;

void Update(int Ticks)
{

}

void UpdateTimer()
{
    while (true)
    {
        LastTimer = Timer;
        Timer++;
         Sleep(1);
        if (End)
            break;
    }
}

int WINAPI WinMain(HINSTANCE par1, HINSTANCE par2, LPSTR par3, int par4)
{
    _beginthread(UpdateTimer, 0, NULL);
    while(true)
    {
        if (Timer == 1000)
        Timer = 0;
        Update(Timer - LastTimer);
    }
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Not only is your approach less than optimal, as you pointed out already, but it's also incredibly inaccurate. Sleep(1) does not mean "sleep exactly for one millisecond." It means "sleep for about one millisecond" where the accuracy can vary wildly based on the system. See msdn.microsoft.com/en-us/library/windows/desktop/…. The Sleep call in any OS rarely has any practical uses in real-time applications like games (aside from the Sleep(0) use case for yielding the thread, and even then, that's not a common need in games applications). \$\endgroup\$ Dec 15, 2012 at 18:55

5 Answers 5

4
\$\begingroup\$

You should just read the current time from the system; for Windows, use QueryPerformanceCounter or timeGetTime. If you are using some free library for window management (which I highly recommend) like SDL or SFML, they have their own functions. Google 'real time game loop' or 'game loop' for multiple examples of this done right.

BTW, that thread is the most resource-consuming, completely inaccurate way of measuring time that I have seen. Sleep() is very imprecise. You should generally not use threads in a game except for performance reasons, and if you are new to the field you shouldn't use them at all. Even if you need to perform an action every few seconds, don't use a thread with sleep for that, just run it from your main loop.

\$\endgroup\$
1
4
\$\begingroup\$

If your using C++11 it has a new Chrono library that allows you to get the system time in milliseconds so you don't have to rely on functions shipped with a 3rd party library. There is also a Boost version if you need to backport it to a non-C++11 system.

\$\endgroup\$
4
\$\begingroup\$

Your Game loop should look something like this

lastTime =  time();
while (!quit)
{
   currentTime = time();
   deltaTime = currentTime - lastTime;
   lastTime = currentTime;
   UpdateFrame(deltaTime);
}

For a crossplatform way to get the time check out this project https://github.com/rampantpixels/timer_lib

now this is called a variable time step update if your game involves physics check out this link http://gafferongames.com/game-physics/fix-your-timestep/

and also see this question here When should I use a fixed or variable time step?

\$\endgroup\$
0
2
\$\begingroup\$

You want to use the High performance counter on Windows. Here is my Timer class:

class Timer
{
  LARGE_INTEGER startTime ;
  double fFreq ;

public:
  Timer() {
    LARGE_INTEGER freq ;
    QueryPerformanceFrequency( &freq ) ;
    fFreq = (double)freq.QuadPart ;
    reset();
  }

  void reset() {   QueryPerformanceCounter( &startTime ) ;  }

  // Gets the most up to date time.
  double getTime() const {
    LARGE_INTEGER endTime ;
    QueryPerformanceCounter( &endTime ) ;
    return ( endTime.QuadPart - startTime.QuadPart ) / fFreq ; // as double
  }
} ;

Use:

int main()
{
  Timer t ;

  // do some things..
  printf( "time: %f\n", t.getTime() );

  t.reset() ;
  // do some more things
  printf( "time: %f\n", t.getTime() );
}
\$\endgroup\$
1
\$\begingroup\$

I use this in most of my projects:

//define these somewhere
unsigned int currentframe;
double framerate;
double oldtime;
double newtime;
__int64 counter;
__int64 frequency;
double timeperframe;

//framerate management, call this every frame
QueryPerformanceCounter( (LARGE_INTEGER*)&counter );
QueryPerformanceFrequency( (LARGE_INTEGER*)&frequency );
newtime = (double)counter / (double)frequency;
timeperframe = newtime - oldtime;
framerate = 1.0 / timeperframe;
oldtime = newtime;
currentframe++;
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .