0

I'm using SDL 1.2 and VS2008 for a smaller game-like application. I have recently (after getting some ideas from other posts on SO which i cannot find now, so sorry if you feel i should have linked your question for reference) re-written my game-loop to not use Sleep or SDL_Delay for timing. Instead i call my game logics with a known frequency and calculate distances and locations based on actual time step.

When doing this i was expecting the FPS to be limited by SDL_Flip to the framerate of the screen (vsynch?) but i ended up with roughly 300 FPS on my machine, which runs Windows 7. What could be the cause of this? Can you run the entire game loop (including SDL_Flip) multiple times in between monitor vsynchs? Is the behavior perhaps different on different machines or is SDL_Flip never supposed to synchronize to vsynch? I don't see any flickering or other effects of out of synch screen updating i would expect.

Here is my game loop for reference:

void GraphicsFramework::run()
{
    Uint32 last_input_check = 0;
    Uint32 last_logics_check = 0;

    while(true)
    {
        Uint32 now = SDL_GetTicks();

        if(now - last_input_check > 10) // Every 10 millisecond
        {
            if(!processEvents())
            {
                return;
            }
            last_input_check = now;
        }

        if(now - last_logics_check > 20) // Every 20 milliseconds
        {
            handleGameLogics();
            last_logics_check = now;
        }

        draw();                          // No FPS limitation
        m_Window.flipSurface();          // Calls SDL_Flip(surface)
        m_ActualFrameTime = SDL_GetTicks() - now;
    }
}

Edit: Fixed FPS with busy waiting would look like this. Replace

        m_ActualFrameTime = SDL_GetTicks() - now;

with

        do
        {
            m_ActualFrameTime = SDL_GetTicks() - now;
        } while ((Uint32)(1000/m_ActualFrameTime) > getDesiredFPS());

This gives a way more stable result than using SDL_Delay or Sleep, for which you get a somewhat variable FPS, at least on my machine. Both of course breaks the timing of processEvents() in the example.

Also adding the SDL_Delay variant for completeness:

        Sint32 timeToSleep = (Uint32)(1000/getDesiredFPS()) - m_ActualFrameTime;
        if(timeToSleep > 0)
        {
            SDL_Delay((Uint32)timeToSleep);
        }
genpfault
  • 51,148
  • 11
  • 85
  • 139
Martin G
  • 17,357
  • 9
  • 82
  • 98

1 Answers1

1

SDL_Flip simply pushes what you have on the surface to the screen. It has nothing to do with the fps. And no you shouldnt use SDL_Flip multiple times on the same loop, you should do it after you have updated your surface and are ready to show it on the screen.

To manage fps SDL_Delay (that simply calls sleep) is your best bet i think.

jofra
  • 617
  • 6
  • 13
  • SDL_Delay makes Windows switch out your process and there is no gurantee for when it will be switched back, making it not so great for controlling FPS. What i meant by doing SDL_Flip multiple times was that the game loop will run multiple times between monitor vsynch. I'll clarify in the question. – Martin G May 03 '14 at 12:06
  • Yes, that's life in a modern multitasking operating system. And guess what -- if you *don't* yield back your time-slice, at some point the OS will *still* come in and grab control away from your process, with no guarantee of when it will return. Because that's life in a modern *preemptive* multitasking OS, which is most of them nowadays. – William McBrine May 03 '14 at 12:29
  • 1
    take a look here http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624%28v=vs.85%29.aspx. You should use this funtion so the sleep time is acurate (as much as possible). Look for timing issues here in stackoverflow, there are alot of good answers ;) (btw if you dont see any flickering then it is just fine in my opinion. There are games that have vsync as an option so you can turn it on/off. So it should not be a problem. You just might want to slow it down, so that you dont use as much cpu and can control basic phycics that dont depend on deltaTime) – jofra May 03 '14 at 20:40
  • jofra, how can you possibly make this claim. `SDL_Flip()` should _wait_ for VSYNC and _waiting_ should affect fps. – user1095108 Jan 04 '15 at 22:48
  • "SDL_Flip() swaps screen buffers" from the wiki. It simply swaps the buffers, and has nothing to do with vsync i'm pretty sure. – jofra Jan 05 '15 at 23:37