void ScreenManager::draw(DrawingContext& context) { assert(!m_screen_stack.empty()); static Uint32 fps_ticks = SDL_GetTicks(); m_screen_stack.back()->draw(context); m_menu_manager->draw(context); if (m_screen_fade) { m_screen_fade->draw(context); } Console::current()->draw(context); if (g_config->show_fps) { draw_fps(context, m_fps); } if (g_config->show_player_pos) { draw_player_pos(context); } // if a screenshot was requested, pass request on to drawing_context if (m_screenshot_requested) { context.take_screenshot(); m_screenshot_requested = false; } context.do_drawing(); /* Calculate frames per second */ if (g_config->show_fps) { static int frame_count = 0; ++frame_count; if (SDL_GetTicks() - fps_ticks >= 500) { m_fps = (float) frame_count / .5; frame_count = 0; fps_ticks = SDL_GetTicks(); } } }
void MainLoop::run() { DrawingContext context; unsigned int frame_count = 0; unsigned int rand_prints = 0; float fps_fps = 0; Uint32 fps_ticks = SDL_GetTicks(); Uint32 fps_nextframe_ticks = SDL_GetTicks(); Uint32 ticks; bool skipdraw = false; running = true; while(running) { while( (next_screen.get() != NULL || nextpop == true) && (screen_fade.get() == NULL || screen_fade->done())) { if(current_screen.get() != NULL) { current_screen->leave(); } if(nextpop) { if(screen_stack.empty()) { running = false; break; } next_screen.reset(screen_stack.back()); screen_stack.pop_back(); } if(nextpush && current_screen.get() != NULL) { screen_stack.push_back(current_screen.release()); } nextpush = false; nextpop = false; speed = 1.0; if(next_screen.get() != NULL) next_screen->setup(); current_screen.reset(next_screen.release()); screen_fade.reset(NULL); waiting_threads.wakeup(); } if(!running || current_screen.get() == NULL) break; float elapsed_time = 1.0 / LOGICAL_FPS; ticks = SDL_GetTicks(); if(ticks > fps_nextframe_ticks) { if(skipdraw == true) { // already skipped last frame? we have to slow down the game then... skipdraw = false; fps_nextframe_ticks -= (Uint32) (1000.0 / LOGICAL_FPS); } else { // don't draw all frames when we're getting too slow skipdraw = true; } } else { skipdraw = false; while(fps_nextframe_ticks > ticks) { /* just wait */ // If we really have to wait long, then do an imprecise SDL_Delay() Uint32 diff = fps_nextframe_ticks - ticks; if(diff > 10) { SDL_Delay(diff - 2); } ticks = SDL_GetTicks(); } } fps_nextframe_ticks = ticks + (Uint32) (1000.0 / LOGICAL_FPS); if(!skipdraw) { current_screen->draw(context); if(Menu::current() != NULL) Menu::current()->draw(context); if(screen_fade.get() != NULL) screen_fade->draw(context); Console::instance->draw(context); if(config->show_fps) draw_fps(context, fps_fps); context.do_drawing(); /* Calculate frames per second */ if(config->show_fps) { ++frame_count; if(SDL_GetTicks() - fps_ticks >= 500) { fps_fps = (float) frame_count / .5; frame_count = 0; fps_ticks = SDL_GetTicks(); } } } real_time += elapsed_time; elapsed_time *= speed; game_time += elapsed_time; Scripting::update_debugger(); Scripting::TimeScheduler::instance->update(game_time); current_screen->update(elapsed_time); if(screen_fade.get() != NULL) screen_fade->update(elapsed_time); Console::instance->update(elapsed_time); main_controller->update(); SDL_Event event; while(SDL_PollEvent(&event)) { main_controller->process_event(event); if(Menu::current() != NULL) Menu::current()->event(event); if(event.type == SDL_QUIT) quit(); } sound_manager->update(); // insert calls for debug (there are few rand calls otherwise) if (0 && rand_prints++ % 20 == 0) log_info << "== periodic rand() call " << systemRandom.rand() << " at frame " << rand_prints << "==" <<std::endl; } }