Advertisement

Proper game loop in SDL?

Started by July 27, 2010 03:46 PM
3 comments, last by Purebe 14 years, 3 months ago
Hi, so, I'm trying to determine what the proper game-loop should look like in SDL, I currently use something like this - but I can't seem to find any resources on whether or not I'm doing it properly:

int main(int argc, char* args[]){	// Initialize the game	InitGame();	// Load the game resources	LoadGame();	// Game Loop	while ( gamedata.game_loop )    // This is a bool set to true until exit	{		// At the start of a frame we want to start our FPS timer		timer_reg_fps.StartTimer();		// Grab the latest event in the event-queue		SDL_PollEvent(&gamedata.sdl_event);		// Update the game each frame		UpdateGame();    // This runs game-logic		// Render the game each frame		RenderGame();    // Effectively this calls an SDL_Flip() to update the screen		// Regulate the FPS - keeps the FPS around 60		if ( gamedata.vsync )		{			// Check if we need to sleep			if ( timer_reg_fps.GetTicks() < (1000 / gamedata.vsync_fps) )			{				// Sleep				SDL_Delay( ( 1000 / gamedata.vsync_fps ) - timer_reg_fps.GetTicks() );			}		}		// At the end of a frame we want to reset our frame timer		timer_reg_fps.StopTimer();		// Now reset it		timer_reg_fps.ResetTimer();	}	// Unload resources	UnloadGame();	// Exit program	return 0;}


At the start of UpdateGame() function I call an ClearScreen() command that effectively does SDL_FillRect() on the screen that will be SDL_Flipp()'d each frame in RenderGame(), then I redraw the entire scene.

Unfortunately I don't know how to make this a clear and concise question, so I apologize for that - but my game tends to jitter a bit as I move along (it's a side-scroller very much like Mario) and I'm not sure if I'm doing something blatantly wrong here or if it's just to be expected when using SDL. (It's not a very noticeable jitter, I probably only notice it because I'm the one writing the game.)
A couple of observations. First, the artifacts you're seeing could be due to tearing (even though you're using a variable named 'vsync', what you're doing there will not, in general, sync your rendering to the monitor refresh).

Also, you're handling events incorrectly, which could also cause behavior that might be perceived as 'jitter'.

You're polling for one event each update, but there could be any number of events in the queue. As such, pending events may get backed up, causing a noticeable delay in responsiveness. (This will probably be most noticeable when moving the mouse.)

The canonical SDL event processing loop looks like this:
while (SDL_PollEvent(&event)) {    // Process event...}
Note that since you're relying on a single global 'event' variable for each update, fixing this will probably require making some revisions to your program structure.
Advertisement
Hm..that is the structure I saw in the documentation however when I use that structure I have the problem of nothing happening unless an event is triggered. So I have to keep moving the mouse around or pressing keys to send events so each frame is rendered, because it waits on SDL_PollEvent() to find an event before doing anything.

I haven't seen any information on that at all while looking through the documentation, so I'm not really sure what to do in that case.
PollEvent() should not block. There is some other issue in your code if that is the case.

As for the jitter, I suspect your frame limiting code might be at fault. SDL_Delay() isn't exact, it will sleep for at least X milliseconds, but due to the way operating systems work you will tend to find it will sleep some multiple of 10 milliseconds, and you do not have control over that multiple. This means that for 60 FPS, you are aiming for 16.6 milliseconds per frame. A single call to SDL_Delay() will eat up 10, or 20 milliseconds.

You can frame-limit without using a delay by using a fixed timestep. In the past I've used a hybrid approach, which ensures that I've at least 10 milliseconds of sleep time before using SDL_Delay(). This reduces CPU usage, but it does mean that you'll get a slightly less dependable frame rate if there are some active background processes.
Thanks for the replies. After reading them and doing a bit of testing I believe you two are right, the jitter is being caused by the FPS not being stable. When I have my, botched, version of v-sync on, even though I'm running a steady ~62FPS it still doesn't give each frame the same amount of time, which causes the speed ups and slow downs as objects move across the screen.

This became very apparent when I let the frames run unlimited and it would fluctuate between 700 and 850 FPS. Thanks for the link to fix my timestep, looks like that's what I need to do.

PS: I got SDL_PollEvent() to work properly by removing my event handling code from my UpdateGame() function, and writing a HandleEvent() function that is now looking like this:

while ( gamedata.game_loop ){    // Poll for all events    while ( SDL_PollEvent(&gamedata.sdl_event) )    {        HandleEvents();    }    UpdateGame(); // Run game logic    // ..}


Makes sense when I think about it now, but dunno guess it just didn't before - either way thanks for the help!

This topic is closed to new replies.

Advertisement