Problems with framerate

Was working on the Windows port of my game and somebody reported to me
that the invincibility theme would cut early (~16 seconds instead of
20 like it should). Since sound seems fine, only explanation I can
find for this is that the framerate limit is not working properly and
it’s going too fast (I could understand if it was going too slow, but
not too fast…).

Before I go insane trying to figure out what’s going on, does anybody
know if there’s anything stupid in these functions?

static uint64_t last_stamp;

void reset_framerate(void) {
last_stamp = SDL_GetPerformanceCounter();
}

unsigned get_num_frames(void) {
uint64_t frame_time = SDL_GetPerformanceFrequency() / 60;

uint64_t num_frames = SDL_GetPerformanceCounter() - last_stamp;
num_frames /= frame_time;
last_stamp += num_frames * frame_time;

if (num_frames > 6)
num_frames = 6;

return (unsigned) num_frames;
}

At some point I was wondering if the issue was that the high
performance timer was not working giving me just 1ms precision, but
even in that case the drift would be 0.8 seconds, not over 3 seconds,
so either I must be missing something. I wondered if this was running
on a laptop and power management was getting in the way, but:

On which system does the timing screw up?
win7 ultimate x64, athlon II x4 3ghz, 8GB RAM
radeon 5670 1GB

Is this a SDL bug, a bug in my code or am I overlooking something else?

If you are basing your timing off of a hard frame-rate limit that
might be causing issues. An entire frame could be off by like
16.6667ms (at 60fps) (1.9 frames could have passed which would be
measured as 1). You should really be passing a true time delta into
your update functions.On Thu, Oct 3, 2013 at 8:15 AM, Sik the hedgehog <sik.the.hedgehog at gmail.com> wrote:

Was working on the Windows port of my game and somebody reported to me
that the invincibility theme would cut early (~16 seconds instead of
20 like it should). Since sound seems fine, only explanation I can
find for this is that the framerate limit is not working properly and
it’s going too fast (I could understand if it was going too slow, but
not too fast…).

Before I go insane trying to figure out what’s going on, does anybody
know if there’s anything stupid in these functions?

static uint64_t last_stamp;

void reset_framerate(void) {
last_stamp = SDL_GetPerformanceCounter();
}

unsigned get_num_frames(void) {
uint64_t frame_time = SDL_GetPerformanceFrequency() / 60;

uint64_t num_frames = SDL_GetPerformanceCounter() - last_stamp;
num_frames /= frame_time;
last_stamp += num_frames * frame_time;

if (num_frames > 6)
num_frames = 6;

return (unsigned) num_frames;
}

At some point I was wondering if the issue was that the high
performance timer was not working giving me just 1ms precision, but
even in that case the drift would be 0.8 seconds, not over 3 seconds,
so either I must be missing something. I wondered if this was running
on a laptop and power management was getting in the way, but:

On which system does the timing screw up?
win7 ultimate x64, athlon II x4 3ghz, 8GB RAM
radeon 5670 1GB

Is this a SDL bug, a bug in my code or am I overlooking something else?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

There is also something odd about:

num_frames /= frame_time;
last_stamp += num_frames * frame_time;On Thu, Oct 3, 2013 at 11:58 AM, Andre D <@Andre_D> wrote:

If you are basing your timing off of a hard frame-rate limit that
might be causing issues. An entire frame could be off by like
16.6667ms (at 60fps) (1.9 frames could have passed which would be
measured as 1). You should really be passing a true time delta into
your update functions.

On Thu, Oct 3, 2013 at 8:15 AM, Sik the hedgehog <sik.the.hedgehog at gmail.com> wrote:

Was working on the Windows port of my game and somebody reported to me
that the invincibility theme would cut early (~16 seconds instead of
20 like it should). Since sound seems fine, only explanation I can
find for this is that the framerate limit is not working properly and
it’s going too fast (I could understand if it was going too slow, but
not too fast…).

Before I go insane trying to figure out what’s going on, does anybody
know if there’s anything stupid in these functions?

static uint64_t last_stamp;

void reset_framerate(void) {
last_stamp = SDL_GetPerformanceCounter();
}

unsigned get_num_frames(void) {
uint64_t frame_time = SDL_GetPerformanceFrequency() / 60;

uint64_t num_frames = SDL_GetPerformanceCounter() - last_stamp;
num_frames /= frame_time;
last_stamp += num_frames * frame_time;

if (num_frames > 6)
num_frames = 6;

return (unsigned) num_frames;
}

At some point I was wondering if the issue was that the high
performance timer was not working giving me just 1ms precision, but
even in that case the drift would be 0.8 seconds, not over 3 seconds,
so either I must be missing something. I wondered if this was running
on a laptop and power management was getting in the way, but:

On which system does the timing screw up?
win7 ultimate x64, athlon II x4 3ghz, 8GB RAM
radeon 5670 1GB

Is this a SDL bug, a bug in my code or am I overlooking something else?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

2013/10/3, Andre D :

If you are basing your timing off of a hard frame-rate limit that
might be causing issues. An entire frame could be off by like
16.6667ms (at 60fps) (1.9 frames could have passed which would be
measured as 1).

That’d be when frameskip kicks in (eventually the drift would make it
return 2 frames). The problem here isn’t that though, that’d make it
go too slow, the problem is that it’s going too fast, which should
never happen under any circumstances

You should really be passing a true time delta into
your update functions.

That in itself brings a whole myriad of issues (especially regarding
stuff like physics, and don’t get me started if you try to record
replays without spending tons of memory).

There is also something odd about:

num_frames /= frame_time;
last_stamp += num_frames * frame_time;

You’re missing the previous line:

uint64_t num_frames = SDL_GetPerformanceCounter() - last_stamp;

The check is done against the timestamp of the previous frame. If the
function got called too fast, then the division will make num_frames
0. And if the amount of ellapsed frames is not whole, then num_frames
will get truncated in that division too, making sure last_stamp
actually gets the timestamp the last frame should be and not the
current one (otherwise it’d drift towards too slow).