Hi,
I have a problem in my main loop, the the game seems to hang for a second or so after executing a CPU intensive process deep inside the loop.
I'll first show the relevant code:
Console.Print("Main loop...\n");
unsigned int curtime;
unsigned int newtime;
double delta;
double accum = 0.0;
curtime = SDL_GetTicks();
while(!System.exit)
{
// measure time
newtime = SDL_GetTicks();
delta = (double)(newtime-curtime) / 1000;
curtime = newtime;
// inner main loop
if (delta > 0.0) {
accum += delta;
while(accum >= TIMESTEP && !System.exit)
{
System.Input();
System.Integrate(TIMESTEP);
accum -= TIMESTEP;
}
System.fps = 1.0 / (float)delta;
}
// draw
System.Draw();
}
Console.Print("Shutting down...\n");
This code is called in the main() function. The outer loop continuously redraws the screen, the inner loop takes care of all game routines and physics. It is done this way to ensure a fixed time step (we don't interpolate between physics updates, but that's something I may change later). Before the game loop (code not shown), the config files are loaded, display surface/ audio is initialized, the GUI is loaded etc. This works fine. Once the main loop is started, the game sits in idle in the game main menu.
At some point during the runtime of the game, the user loads a level. This occurs inside the inner loop, System.Input() to be exact, as the action is triggered by a button click. The load-level routine is then started.
The 'load level' function does this each time a level resource (e.g. texture or model) has been loaded from file:
ComputeProgress(); // computes progress, how far the level has been loaded
System.Input(); // user can cancel process by pressing ESC
System.Draw(); // redraw screen to show progress bar updates
Once the level is fully loaded, the 'load level' routine is exited, we return to the inner main loop. We expect the loading screen to disappear and the first frame of the 3d world will be drawn.
What I then observe is the following:
1) the first frame of the game is drawn instantly when the progress bar hits 100% (so far so good)
2) after the first frame is drawn (System::Draw, called in outer loop) the game 'hangs' for a few seconds (longer load time seems to cause longer hang)
3) after the second frame there seems to be a second shorter hang, but I'm not entirely sure
4) then the game continues to run smoothly from the 3rd frame on, no noticeable hangs
During the hangs, the game is responsive to input, this means that System::Input() is being called. That indicates that during the 'hang', the inner main loop is called for large number of iterations, and the screen never gets redrawn until it exits the inner loop.
I *think* the hang happens because the timer is thrown off by the very large time difference that occurs inside System::Input (the 'load level' routine typically takes 30 seconds or so before SDL_GetTicks is called again).
The second hang, *i guess*, could be triggered by the first 'hang'. For the same reason, long time elapsed since last SDL_GetTicks, though shorter than the first.
As you can tell from the source, the timer code is isolated from the rest of the code, so it cannot be influenced outside the main() function.
But I can't wrap my head around the problem, I can't seem to reconstruct what exactly happens.
Do you have any idea?
Thanks. :)