[SDL] framerate counter

Jason Hoffoss jhoffoss at smartshop.com
Wed Apr 4 12:46:11 PDT 2001


On Wednesday 04 April 2001 05:53, you wrote:
> Hi there!
>
> I've tried to make a framerate counter as wel as a framerate limiter (so
> the game doesn't run faster than say, 50fps), but i've failed in doing so.
> I was wondering if anyone has already done this before, and would care to
> share the source of it with me.

I wanted to do exactly the same thing for a game I wrote under linux.  Below 
is the class (struct) I wrote to handle doing it.  It works pretty well.  It 
generally gets pretty close to the target framerate, though never exactly on 
it really.  In linux, with only ~10ms granularity in timing, and shifting CPU 
loads due to other processes, I figure it's nearly impossible to get exactly 
at the target framerate.  Also, my frameload varies depending on what gets 
drawn on the screen, but this compensates for that pretty well too.  This 
should also be very portable.

To use it, declare one instance of Delay, and then call the exec() method 
once a frame.  Enjoy.

int peak_update_areas = 0;
SDL_Rect update_areas[MAX_UPDATE_AREAS];
 
#define INITIAL_DELAY 0xdffff
#define MAX_DELAY_ENTRIES 15
#define TARGET_FRAMERATE 60.0f
 
Uint32 ticks = 0;
int frames = 0;
 
struct Delay {
    int delay;
    int last_frames;
    Uint32 last_ticks;
    int num_delay_entries;
    int delay_entry_index;
    int delay_entries[MAX_DELAY_ENTRIES];
 
    Delay()
    {
        reset();
    }
 
    void reset()
    {
        delay = INITIAL_DELAY;
        last_frames = frames = 0;
        last_ticks = 0;
        num_delay_entries = -1;
        delay_entry_index = 0;
    }

    void exec()
    {
        int i = delay;
 
        while (i--);
 
        frames++;
        ticks = SDL_GetTicks();
        if (ticks != last_ticks) {
            int dt, df;
            float f, fps = 0.0f;
 
            dt = ticks - last_ticks;
            df = frames - last_frames;
            last_ticks = ticks;
            last_frames = frames;
 
            // skip first entry, as it will only be partial
            if (num_delay_entries < 0) {
                num_delay_entries = 0;
                return;
            }
 
            fps = (float) df * 1000.0f / (float) dt;
            if ((delay == 0) && (fps > 60.0f))
                delay = INITIAL_DELAY;
 
            f = (float) delay * fps / TARGET_FRAMERATE;
 
            // record a new delay entry
            delay_entries[delay_entry_index] = (int) ((f < 0) ? 0 : f);
 
            if (++delay_entry_index == MAX_DELAY_ENTRIES)
                delay_entry_index = 0;
 
            if (num_delay_entries < MAX_DELAY_ENTRIES)
                num_delay_entries++;

            // calculate delay as average of delay entries
            delay = 0;
            for (i=0; i<num_delay_entries; i++)
                delay += delay_entries[i];
 
            delay /= num_delay_entries;
        }
    }
};



More information about the SDL mailing list