Search code examples
c++frame-rate

Limiting Update Rate in C++. Why does this code update once a second not 60 times a second?


I am making a small game with C++ OpenGL. update() is normally called once every time the program runs through the code. I am trying to limit this to 60 times per second (I want the game to update at the same speed on different speed computers).

The code included below runs a timer and should call update() once the timer is >= than 0.0166666666666667 (60 times per second). However the statement if((seconds - lastTime) >= 0.0166666666666667) seems only to be tripped once per second. Does anyone know why?

Thanks in advance for your help.

//Global Timer variables
double secondsS;
double lastTime;
time_t timer;
struct tm y2k;
double seconds;

void init()
{
    glClearColor(0,0,0,0.0);                        // Sets the clear colour to white.
                                                    // glClear(GL_COLOR_BUFFER_BIT) in the display function

    //Init viewport
    viewportX = 0;
    viewportY = 0;

    initShips();

    //Time
    lastTime = 0;
    time_t timerS;
    struct tm y2k;
    y2k.tm_hour = 0;   y2k.tm_min = 0; y2k.tm_sec = 0;
    y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;
    time(&timerS);  /* get current time; same as: timer = time(NULL)  */
    secondsS = difftime(timerS,mktime(&y2k));
    printf ("%.f seconds since January 1, 2000 in the current timezone \n", secondsS);

    loadTextures();
    ShowCursor(true);

    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

}

void timeKeeper()
{
    y2k.tm_hour = 0;   y2k.tm_min = 0; y2k.tm_sec = 0;
    y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;

    time(&timer);  /* get current time; same as: timer = time(NULL)  */

    seconds = difftime(timer,mktime(&y2k));
    seconds -= secondsS; 

    //Run 60 times a second. This limits updates to a constant standard.
    if((seconds - lastTime) >= 0.0166666666666667)
    {
        lastTime = seconds;

        update();

        //printf ("%.f seconds since beginning program \n", seconds);
    }
}

timeKeeper() is called in int WINAPI WinMain, while the program is !done

EDIT:

Thanks to those who helped, you pointed me on the right track. As mentioned in the answer below <ctime> does not have ms accuracy. I have therefore implemented the following code that has the correct accuracy:

double GetSystemTimeSample()
{
    FILETIME ft1, ft2;
    // assume little endian and that ULONGLONG has same alignment as FILETIME
    ULONGLONG &t1 = *reinterpret_cast<ULONGLONG*>(&ft1),
              &t2 = *reinterpret_cast<ULONGLONG*>(&ft2);

    GetSystemTimeAsFileTime(&ft1);
    do
    {
        GetSystemTimeAsFileTime(&ft2);
    } while (t1 == t2);

    return (t2 - t1) / 10000.0;
}//GetSystemTimeSample

void timeKeeper()
{
    thisTime += GetSystemTimeSample();
    cout << thisTime << endl;

    //Run 60 times a second. This limits updates to a constant standard.
    if(thisTime >= 16.666666666666699825) //Compare to a value in milliseconds
    {
        thisTime = seconds;

        update();
    }
}

Solution

  • http://www.cplusplus.com/reference/ctime/difftime/

    Calculates the difference in seconds between beginning and end
    

    So, you get a value in seconds. So, even if your value is double, you will get an integer.

    So, you only get a difference between a value and the previous one when that difference is at least of 1 second.