Ejemplo n.º 1
0
/**
 * \brief The main function.
 *
 * The main loop is executed here.
 */
void MainLoop::run() {

  // Main loop.
  uint32_t last_frame_date = System::get_real_time();
  uint32_t lag = 0;  // Lose time of the simulation to catch up.
  uint32_t time_dropped = 0;  // Time that won't be caught up.

  // The main loop basically repeats
  // check_input(), update(), draw() and sleep().
  // Each call to update() makes the simulated time advance one fixed step.
  while (!is_exiting()) {

    // Measure the time of the last iteration.
    uint32_t now = System::get_real_time() - time_dropped;
    uint32_t last_frame_duration = now - last_frame_date;
    last_frame_date = now;
    lag += last_frame_duration;
    // At this point, lag represents how much late the simulated time with
    // compared to the real time.
 
    if (lag >= 200) {
      // Huge lag: don't try to catch up.
      // Maybe we have just made a one-time heavy operation like loading a
      // big file, or the process was just unsuspended.
      // Let's fake the real time instead.
      time_dropped += lag - System::timestep;
      lag = System::timestep;
      last_frame_date = System::get_real_time() - time_dropped;
    }

    // 1. Detect and handle input events.
    check_input();

    // 2. Update the world once, or several times (skipping some draws)
    // to catch up if the system is slow.
    int num_updates = 0;
    while (lag >= System::timestep
        && num_updates < 10  // To draw sometimes anyway on very slow systems.
        && !is_exiting()) {
      update();
      lag -= System::timestep;
      ++num_updates;
    }

    // 3. Redraw the screen.
    if (num_updates > 0) {
      draw();
    }

    // 4. Sleep if we have time, to save CPU and GPU cycles.
    last_frame_duration = (System::get_real_time() - time_dropped) - last_frame_date;
    if (last_frame_duration < System::timestep) {
      System::sleep(System::timestep - last_frame_duration);
    }
  }
}
Ejemplo n.º 2
0
/**
 * \brief The main function.
 *
 * The main loop is executed here.
 */
void MainLoop::run() {

  // Main loop.
  uint32_t last_frame_date = System::get_real_time();
  uint32_t lag = 0;  // Lose time of the simulation.

  // The main loop basically repeats
  // check_input(), update(), draw() and sleep().
  // Each call to update() makes the simulated time advance one fixed step.
  while (!is_exiting()) {

    // Measure the time of the last iteration without the check_input() phase.
    // Some check_input() calls are much slower than other, for example when
    // they involve loading a map. However, these long check_input() calls do
    // not mean that the system is slow and that we should skip drawings,
    // unlike long updates and long drawings.
    // That is is why to compute the lag, we ignore the time spent in
    // check_input().
    uint32_t current_frame_date = System::get_real_time();
    uint32_t last_frame_duration = current_frame_date - last_frame_date;

    // 1. Detect and handle input events.
    check_input();

    last_frame_date = System::get_real_time();
    lag += last_frame_duration;
    // At this point, lag represents how much late the simulated time with
    // compared to the real time.

    // 2. Update the world once, or several times (skipping some draws)
    // if the system is slow.
    int num_updates = 0;
    while (lag >= System::timestep
        && num_updates < 10  // To draw sometimes anyway on very slow systems.
        && !is_exiting()) {
      update();
      lag -= System::timestep;
      ++num_updates;
    }

    // 3. Redraw the screen.
    draw();

    // 4. Sleep if we have time, to save CPU cycles.
    if (System::get_real_time() - last_frame_date < System::timestep) {
      System::sleep(1);
    }
  }
}
Ejemplo n.º 3
0
/**
 * \brief Enables accepting standard input lines as Lua commands.
 */
void MainLoop::initialize_lua_console() {

  // Watch stdin in a separate thread.
  stdin_thread = std::thread([this]() {

    std::string line;
    while (!is_exiting()) {

      if (std::getline(std::cin, line)) {

        while (!line.empty() && std::isspace(line.at(line.size() - 1))) {
          line.erase(line.size() - 1);
        }

        if (!line.empty()) {
          push_lua_command(line);
        }
      }
    }
  });
  stdin_thread.detach();
}
Ejemplo n.º 4
0
/**
 * @brief The main function.
 *
 * The main loop is executed here.
 * The input events are forwarded to the current screen.
 * The current screen is redrawn when necessary.
 */
void Solarus::main_loop() {

  // main loop
  InputEvent *event;
  uint32_t now;
  uint32_t next_frame_date = System::now();
  uint32_t frame_interval = 25; // time interval between to displays
  int delay;
  bool just_displayed = false; // to detect when the FPS number needs to be decreased

  while (!is_exiting()) {

    // handle the input events
    event = InputEvent::get_event();
    if (event != NULL) {
      notify_event(*event);
      delete event;
    }

    // update the current screen
    update();

    // go to another screen?
    if (current_screen->is_screen_finished()) {
      Screen *next_screen = current_screen->get_next_screen();
      delete current_screen;

      if (next_screen != NULL) {
        current_screen = next_screen;
      }
      else {
        current_screen = new LanguageScreen(*this);
      }
    }
    else {

      now = System::now();
      delay = next_frame_date - now;
      // delay is the time remaining before the next display

      if (delay <= 0) { // it's time to display

        // see if the FPS number is too high
        if (just_displayed && frame_interval <= 30) {
          frame_interval += 5; // display the screen less often
          //std::cout << "\rFPS: " << (1000 / frame_interval) << std::flush;
        }

        next_frame_date = now + frame_interval;
        just_displayed = true;
        display();
      }
      else {
        just_displayed = false;

        // if we have time, let's sleep to avoid using all the processor
        System::sleep(1);

        if (delay >= 15) {
          // if we have much time, increase the FPS number
          frame_interval--;
          //std::cout << "\rFPS: " << (1000 / frame_interval) << std::flush;
        }
      }
    }
  }
}