Game running too fast after windows moved


#1

While dragging the window or after the window regains a lost focus, the action is running too fast for a moment (ca. 1 second). It’s as if SDL wants to catch up the lost time.
See the video. No movement = while i am dragging the window.
Why this effect and how to get rid of it?


#2

So I had a similar issue with my video player app a while back, in that the video would freeze as you dragged the window etc. because in Windows it goes into some kind of horrible modal loop to process events so it never returns back to your main loop allowing you to update everything and render the next video frame (or update and render the game in your case).

What I did was implement some new functionality whereby SDL would call a user-specified callback function on a timer, but from within the same event loop code inside SDL. Then I moved anything that needs to update constantly into this callback.

I made my callback return a value indicating how long until it should call the callback again, that way I was able to synchronise things as I wished.

Of course I had to implement this across all platforms, and the method varies from platform to platform. I think on Windows I used SetTimer.

So here is my timer fired function:

static UINT_PTR timer = 0;
static UINT timer_interval = 20;

VOID CALLBACK timerFired(In HWND hwnd, In UINT uMsg, In UINT_PTR idEvent, In DWORD dwTime)
{
SDL_UpdateCallback f;
if (f = SDL_GetUpdateCallback()) {
timer_interval = (UINT)f();
}

KillTimer(NULL, timer);
timer = SetTimer(NULL, 1, timer_interval, timerFired);

}

At the bottom of SDL_RegisterApp I set it up for the first time:

if (!(timer = SetTimer(NULL, 1, timer_interval, timerFired))) {
    return SDL_SetError("Couldn't create timer");
}

Then the API to actually set the update callback, defined in SDL.h:

/* The update callback function prototype */
typedef int(*SDL_UpdateCallback)(void);

/**

  • This function sets the update callback
    */
    extern DECLSPEC void SDLCALL SDL_SetUpdateCallback(SDL_UpdateCallback f);

/**

  • This function gets the update callback
    */
    extern DECLSPEC SDL_UpdateCallback SDLCALL SDL_GetUpdateCallback(void);

That’s about the gist of it, for Windows anyway.


#3

Thanks for your reply.


#5

I would guess the issue is with how you handle passing of time and timestepping (i.e. simulation of the game world). When dragging the window you are not drawing any frames, but time still passes. Now in the next frame after the move your game sees that a lot of time has passed since the last frame and simulates all that time that passed.

As the effect is not just showing as a big jump in one frame I’m guessing that maybe you have some kind of simulation that uses fixed timesteps to “spend” the time that has passed in the real world in chuncks, but you have some kind of limit how many steps to do in a frame, so the extra time is flooding to multiple frames following the big jump.

Obviously I’m just guessing here because I don’t know how you handle timestepping.


#6

You are right. I found out that my calculation of framespeed was the reason for the fast running. Has nothing to do with SDL.


#7

Hope I didn’t confuse with my solution - if you don’t mind the animation freezing when dragging then it’s a much easier fix as you have discovered.

I didn’t want my video playback to freeze when dragging hence the more complicated solution.


#8

Not confusing at all. Good to know it’s common behavior when dragging a window.