示例#1
0
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;
  }
}