コード例 #1
0
ファイル: driver.c プロジェクト: ipoly/RetroArch
void init_drivers(void)
{
   driver.video_data_own = false;
   driver.audio_data_own = false;
   driver.input_data_own = false;
#ifdef HAVE_CAMERA
   driver.camera_data_own = false;
#endif
#ifdef HAVE_LOCATION
   driver.location_data_own = false;
#endif
#ifdef HAVE_OSK
   driver.osk_data_own = false;
#endif
#ifdef HAVE_MENU
   // By default, we want the menu to persist through driver reinits.
   driver.menu_data_own = true;
#endif

   adjust_system_rates();

   g_extern.frame_count = 0;

   init_video_input();

   if (!driver.video_cache_context_ack && g_extern.system.hw_render_callback.context_reset)
      g_extern.system.hw_render_callback.context_reset();
   driver.video_cache_context_ack = false;

   init_audio();

#ifdef HAVE_CAMERA
   // Only initialize camera driver if we're ever going to use it.
   if (g_extern.camera_active)
      init_camera();
#endif

#ifdef HAVE_LOCATION
   // Only initialize location driver if we're ever going to use it.
   if (g_extern.location_active)
      init_location();
#endif

#ifdef HAVE_OSK
   init_osk();
#endif

#ifdef HAVE_MENU
   init_menu();

   if (driver.menu && driver.menu_ctx && driver.menu_ctx->context_reset)
      driver.menu_ctx->context_reset(driver.menu);
#endif

   // Keep non-throttled state as good as possible.
   if (driver.nonblock_state)
      driver_set_nonblock_state(driver.nonblock_state);

   g_extern.system.frame_time_last = 0;
}
コード例 #2
0
ファイル: menu_driver.c プロジェクト: Ced2911/RetroArch
static void menu_driver_toggle(bool latch)
{
   const menu_ctx_driver_t *menu_driver = menu_ctx_driver_get_ptr();
   settings_t                 *settings = config_get_ptr();
   global_t                   *global   = global_get_ptr();
   rarch_system_info_t          *system = rarch_system_info_get_ptr();

   if (menu_driver->toggle)
      menu_driver->toggle(latch);

   if (latch)
      menu_driver_ctl(RARCH_MENU_CTL_SET_ALIVE, NULL);
   else
      menu_driver_ctl(RARCH_MENU_CTL_UNSET_ALIVE, NULL);

   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      menu_entries_set_refresh(false);

      /* Menu should always run with vsync on. */
      event_command(EVENT_CMD_VIDEO_SET_BLOCKING_STATE);
      /* Stop all rumbling before entering the menu. */
      event_command(EVENT_CMD_RUMBLE_STOP);

      if (settings->menu.pause_libretro)
         event_command(EVENT_CMD_AUDIO_STOP);

      /* Override keyboard callback to redirect to menu instead.
       * We'll use this later for something ...
       * FIXME: This should probably be moved to menu_common somehow. */
      if (global)
      {
         global->frontend_key_event = system->key_event;
         system->key_event          = menu_input_key_event;

         runloop_ctl(RUNLOOP_CTL_SET_FRAME_TIME_LAST, NULL);
      }
   }
   else
   {
      if (!runloop_ctl(RUNLOOP_CTL_IS_SHUTDOWN, NULL))
         driver_set_nonblock_state();

      if (settings && settings->menu.pause_libretro)
         event_command(EVENT_CMD_AUDIO_START);

      /* Prevent stray input from going to libretro core */
      input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL);

      /* Restore libretro keyboard callback. */
      if (global)
         system->key_event = global->frontend_key_event;
   }
}
コード例 #3
0
ファイル: runloop.c プロジェクト: mprobinson/RetroArch
/* To avoid continous switching if we hold the button down, we require
 * that the button must go from pressed to unpressed back to pressed 
 * to be able to toggle between then.
 */
static void check_fast_forward_button(bool fastforward_pressed,
      bool hold_pressed, bool old_hold_pressed)
{
   if (fastforward_pressed)
      driver.nonblock_state = !driver.nonblock_state;
   else if (old_hold_pressed != hold_pressed)
      driver.nonblock_state = hold_pressed;
   else
      return;

   driver_set_nonblock_state(driver.nonblock_state);
}
コード例 #4
0
ファイル: driver.c プロジェクト: gouchi/RetroArch
static void driver_adjust_system_rates(void)
{
   audio_driver_monitor_adjust_system_rates();
   video_driver_monitor_adjust_system_rates();

   if (!video_driver_get_ptr(false))
      return;

   if (rarch_ctl(RARCH_CTL_IS_NONBLOCK_FORCED, NULL))
      command_event(CMD_EVENT_VIDEO_SET_NONBLOCKING_STATE, NULL);
   else
      driver_set_nonblock_state();
}
コード例 #5
0
ファイル: menu_driver.c プロジェクト: ssangkong/RetroArch
void menu_driver_toggle(bool latch)
{
   driver_t                     *driver = driver_get_ptr();
   const menu_ctx_driver_t *menu_driver = menu_ctx_driver_get_ptr();
   settings_t                 *settings = config_get_ptr();
   global_t                   *global   = global_get_ptr();
   rarch_system_info_t          *system = rarch_system_info_get_ptr();

   if (menu_driver->toggle)
      menu_driver->toggle(latch);

   menu_alive = latch;

   if (menu_alive == true)
   {
      menu_entries_set_refresh(false);

      /* Menu should always run with vsync on. */
      event_command(EVENT_CMD_VIDEO_SET_BLOCKING_STATE);
      /* Stop all rumbling before entering the menu. */
      event_command(EVENT_CMD_RUMBLE_STOP);

      if (settings->menu.pause_libretro)
         event_command(EVENT_CMD_AUDIO_STOP);

      /* Override keyboard callback to redirect to menu instead.
       * We'll use this later for something ...
       * FIXME: This should probably be moved to menu_common somehow. */
      if (global)
      {
         global->frontend_key_event = system->key_event;
         system->key_event          = menu_input_key_event;
         system->frame_time_last    = 0;
      }
   }
   else
   {
      driver_set_nonblock_state(driver->nonblock_state);

      if (settings && settings->menu.pause_libretro)
         event_command(EVENT_CMD_AUDIO_START);

      /* Prevent stray input from going to libretro core */
      driver->flushing_input = true;

      /* Restore libretro keyboard callback. */
      if (global)
         system->key_event = global->frontend_key_event;
   }
}
コード例 #6
0
ファイル: driver.c プロジェクト: isdom/RetroArch
void init_drivers(void)
{
   driver.video_data_own = !driver.video_data;
   driver.audio_data_own = !driver.audio_data;
   driver.input_data_own = !driver.input_data;
#ifdef HAVE_CAMERA
   driver.camera_data_own = !driver.camera_data;
#endif
#ifdef HAVE_LOCATION
   driver.location_data_own = !driver.location_data;
#endif
#ifdef HAVE_OSK
   driver.osk_data_own = !driver.osk_data;
#endif

   adjust_system_rates();

   g_extern.frame_count = 0;
   init_video_input();

   if (!driver.video_cache_context_ack && g_extern.system.hw_render_callback.context_reset)
      g_extern.system.hw_render_callback.context_reset();
   driver.video_cache_context_ack = false;

   init_audio();

#ifdef HAVE_CAMERA
   // Only init camera driver if we're ever going to use it.
   if (g_extern.camera_active)
      init_camera();
#endif

#ifdef HAVE_LOCATION
   // Only init location driver if we're ever going to use it.
   if (g_extern.location_active)
      init_location();
#endif

#ifdef HAVE_OSK
   init_osk();
#endif

   // Keep non-throttled state as good as possible.
   if (driver.nonblock_state)
      driver_set_nonblock_state(driver.nonblock_state);

   g_extern.system.frame_time_last = 0;
}
コード例 #7
0
ファイル: driver.c プロジェクト: felida420/RetroArch
static void driver_adjust_system_rates(void)
{
   global_t *global = global_get_ptr();
   driver_t *driver = driver_get_ptr();

   audio_monitor_adjust_system_rates();
   video_monitor_adjust_system_rates();

   if (!driver->video_data)
      return;

   if (global->system.force_nonblock)
      event_command(EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE);
   else
      driver_set_nonblock_state(driver->nonblock_state);
}
コード例 #8
0
ファイル: runloop.c プロジェクト: notaz/RetroArch
/**
 * check_fast_forward_button:
 * @fastforward_pressed  : is fastforward key pressed?
 * @hold_pressed         : is fastforward key pressed and held?
 * @old_hold_pressed     : was fastforward key pressed and held the last frame?
 *
 * Checks if the fast forward key has been pressed for this frame.
 *
 **/
static void check_fast_forward_button(bool fastforward_pressed,
                                      bool hold_pressed, bool old_hold_pressed)
{
    /* To avoid continous switching if we hold the button down, we require
     * that the button must go from pressed to unpressed back to pressed
     * to be able to toggle between then.
     */
    if (fastforward_pressed)
        driver.nonblock_state = !driver.nonblock_state;
    else if (old_hold_pressed != hold_pressed)
        driver.nonblock_state = hold_pressed;
    else
        return;

    driver_set_nonblock_state(driver.nonblock_state);
}
コード例 #9
0
ファイル: driver.c プロジェクト: brianblakely/RetroArch
static void driver_adjust_system_rates(void)
{
   rarch_system_info_t *system = rarch_system_info_get_ptr();
   driver_t            *driver = driver_get_ptr();

   audio_monitor_adjust_system_rates();
   video_monitor_adjust_system_rates();

   if (!driver->video_data)
      return;

   if (system->force_nonblock)
      event_command(EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE);
   else
      driver_set_nonblock_state(driver->nonblock_state);
}
コード例 #10
0
ファイル: driver.c プロジェクト: dturner/RetroArch
static void adjust_system_rates(void)
{
   g_extern.system.force_nonblock = false;
   const struct retro_system_timing *info = &g_extern.system.av_info.timing;

   if (info->fps <= 0.0 || info->sample_rate <= 0.0)
      return;

   float timing_skew = fabs(1.0f - info->fps / g_settings.video.refresh_rate);
   if (timing_skew > 0.05f) // We don't want to adjust pitch too much. If we have extreme cases, just don't readjust at all.
   {
      RARCH_LOG("Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2f Hz)\n",
            g_settings.video.refresh_rate,
            (float)info->fps);

      // We won't be able to do VSync reliably as game FPS > monitor FPS.
      if (info->fps > g_settings.video.refresh_rate)
      {
         g_extern.system.force_nonblock = true;
         RARCH_LOG("Game FPS > Monitor FPS. Cannot rely on VSync.\n");
      }

      g_extern.audio_data.in_rate = info->sample_rate;
   }
   else
      g_extern.audio_data.in_rate = info->sample_rate *
         (g_settings.video.refresh_rate / info->fps);

   RARCH_LOG("Set audio input rate to: %.2f Hz.\n", g_extern.audio_data.in_rate);

   if (driver.video_data)
   {
      if (g_extern.system.force_nonblock)
         rarch_main_command(RARCH_CMD_VIDEO_SET_NONBLOCKING_STATE);
      else
         driver_set_nonblock_state(driver.nonblock_state);
   }
}
コード例 #11
0
ファイル: frontend.c プロジェクト: MoonlightStudios/RetroArch
int main(int argc, char *argv[])
#endif
{
   frontend_ctx = (frontend_ctx_driver_t*)frontend_ctx_init_first();

   if (frontend_ctx && frontend_ctx->init)
      frontend_ctx->init();

   rarch_main_clear_state();
#ifndef __APPLE__
   rarch_get_environment(argc, argv);
#endif

#if !defined(RARCH_CONSOLE)
#if defined(__APPLE__)
   struct rarch_main_wrap* argdata = (struct rarch_main_wrap*)args;
   int init_ret = rarch_main_init_wrap(argdata);
   apple_free_main_wrap(argdata);

   if (init_ret)
   {
      rarch_main_clear_state();
      dispatch_async_f(dispatch_get_main_queue(), (void*)1, apple_rarch_exited);
      return 0;
   }
#else
   rarch_init_msg_queue();
   int init_ret;
   if ((init_ret = rarch_main_init(argc, argv))) return init_ret;
#endif
#endif

#ifdef HAVE_MENU
   menu_init();

#ifndef __APPLE__
   if (frontend_ctx && frontend_ctx->process_args)
      frontend_ctx->process_args(argc, argv);
#endif

#ifdef RARCH_CONSOLE
   g_extern.lifecycle_mode_state |= 1ULL << MODE_LOAD_GAME;
#else
   g_extern.lifecycle_mode_state |= 1ULL << MODE_GAME;
#endif

#ifndef RARCH_CONSOLE
   // If we started a ROM directly from command line,
   // push it to ROM history.
   if (!g_extern.libretro_dummy)
      menu_rom_history_push_current();
#endif

   for (;;)
   {
      if (g_extern.system.shutdown)
         break;
      else if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME))
      {
         load_menu_game_prepare();

         // If ROM load fails, we exit RetroArch. On console it might make more sense to go back to menu though ...
         if (load_menu_game())
            g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
         else
         {
#if defined(RARCH_CONSOLE) || defined(__QNX__)
            g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU);
#else
            if (frontend_ctx && frontend_ctx->shutdown)
               frontend_ctx->shutdown(true);

            return 1;
#endif
         }

         g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME);
      }
      else if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))
      {
#ifdef RARCH_CONSOLE
         driver.input->poll(NULL);
#endif
         if (driver.video_poke->set_aspect_ratio)
            driver.video_poke->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);

         while ((g_extern.is_paused && !g_extern.is_oneshot) ? rarch_main_idle_iterate() : rarch_main_iterate())
         {
            if (frontend_ctx && frontend_ctx->process_events)
               frontend_ctx->process_events();

            if (!(g_extern.lifecycle_mode_state & (1ULL << MODE_GAME)))
               break;
         }
         g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
      }
      else if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))
      {
         g_extern.lifecycle_mode_state |= 1ULL << MODE_MENU_PREINIT;
         // Menu should always run with vsync on.
         video_set_nonblock_state_func(false);

         if (driver.audio_data)
            audio_stop_func();

         while (!g_extern.system.shutdown && menu_iterate())
         {
            if (frontend_ctx && frontend_ctx->process_events)
               frontend_ctx->process_events();

            if (!(g_extern.lifecycle_mode_state & (1ULL << MODE_MENU)))
               break;
         }

         driver_set_nonblock_state(driver.nonblock_state);

         if (driver.audio_data && !audio_start_func())
         {
            RARCH_ERR("Failed to resume audio driver. Will continue without audio.\n");
            g_extern.audio_active = false;
         }

         g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU);
      }
      else
         break;
   }

   g_extern.system.shutdown = false;
   menu_free();

   if (g_extern.config_save_on_exit && *g_extern.config_path)
      config_save_file(g_extern.config_path);

#ifdef GEKKO
   /* Per-core input config saving */
   config_save_keybinds(g_extern.input_config_path);
#endif

#ifdef RARCH_CONSOLE
   global_uninit_drivers();
#endif
#else
   while ((g_extern.is_paused && !g_extern.is_oneshot) ? rarch_main_idle_iterate() : rarch_main_iterate());
#endif

   rarch_main_deinit();
   rarch_deinit_msg_queue();

#ifdef PERF_TEST
   rarch_perf_log();
#endif

#if defined(HAVE_LOGGER)
   logger_shutdown();
#elif defined(HAVE_FILE_LOGGER)
   if (g_extern.log_file)
      fclose(g_extern.log_file);
   g_extern.log_file = NULL;
#endif

   if (frontend_ctx && frontend_ctx->deinit)
      frontend_ctx->deinit();

   if (g_extern.lifecycle_mode_state & (1ULL << MODE_EXITSPAWN) && frontend_ctx
         && frontend_ctx->exitspawn)
      frontend_ctx->exitspawn();

   rarch_main_clear_state();

   if (frontend_ctx && frontend_ctx->shutdown)
      frontend_ctx->shutdown(false);

   return 0;
}
コード例 #12
0
ファイル: retroarch.c プロジェクト: PCGeekBrain/RetroArch
void rarch_main_set_state(unsigned cmd)
{
   driver_t *driver     = driver_get_ptr();
   global_t *global     = global_get_ptr();
   settings_t *settings = config_get_ptr();

   switch (cmd)
   {
      case RARCH_ACTION_STATE_MENU_RUNNING:
#ifdef HAVE_MENU
         {
            menu_handle_t *menu = menu_driver_get_ptr();
            if (!menu)
               return;

            menu_driver_toggle(true);

            /* Menu should always run with vsync on. */
            event_command(EVENT_CMD_VIDEO_SET_BLOCKING_STATE);
            /* Stop all rumbling before entering the menu. */
            event_command(EVENT_CMD_RUMBLE_STOP);

            if (settings->menu.pause_libretro)
               event_command(EVENT_CMD_AUDIO_STOP);

            /* Override keyboard callback to redirect to menu instead.
             * We'll use this later for something ...
             * FIXME: This should probably be moved to menu_common somehow. */
            if (global)
            {
               global->frontend_key_event = global->system.key_event;
               global->system.key_event   = menu_input_key_event;
               global->system.frame_time_last = 0;
            }

            menu_set_refresh();
            menu_driver_set_alive();
         }
#endif
         break;
      case RARCH_ACTION_STATE_LOAD_CONTENT:
#ifdef HAVE_MENU
         /* If content loading fails, we go back to menu. */
         if (!menu_load_content())
            rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING);
#endif
         if (driver->frontend_ctx && driver->frontend_ctx->content_loaded)
            driver->frontend_ctx->content_loaded();
         break;
      case RARCH_ACTION_STATE_MENU_RUNNING_FINISHED:
#ifdef HAVE_MENU
         menu_setting_apply_deferred();

         menu_driver_toggle(false);
         menu_driver_unset_alive();

         driver_set_nonblock_state(driver->nonblock_state);

         if (settings && settings->menu.pause_libretro)
            event_command(EVENT_CMD_AUDIO_START);

         /* Prevent stray input from going to libretro core */
         driver->flushing_input = true;

         /* Restore libretro keyboard callback. */
         if (global)
            global->system.key_event = global->frontend_key_event;
#endif
         video_driver_set_texture_enable(false, false);
         break;
      case RARCH_ACTION_STATE_QUIT:
	     if (global)
            global->system.shutdown = true;
         rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
         break;
      case RARCH_ACTION_STATE_FORCE_QUIT:
         if (global)
            global->lifecycle_state = 0;
         rarch_main_set_state(RARCH_ACTION_STATE_QUIT);
         break;
      case RARCH_ACTION_STATE_NONE:
      default:
         break;
   }
}
コード例 #13
0
ファイル: driver.c プロジェクト: felida420/RetroArch
/**
 * init_drivers:
 * @flags              : Bitmask of drivers to initialize.
 *
 * Initializes drivers.
 * @flags determines which drivers get initialized.
 **/
void init_drivers(int flags)
{
   driver_t *driver = driver_get_ptr();
   global_t *global = global_get_ptr();

   if (flags & DRIVER_VIDEO)
      driver->video_data_own = false;
   if (flags & DRIVER_AUDIO)
      driver->audio_data_own = false;
   if (flags & DRIVER_INPUT)
      driver->input_data_own = false;
   if (flags & DRIVER_CAMERA)
      driver->camera_data_own = false;
   if (flags & DRIVER_LOCATION)
      driver->location_data_own = false;

#ifdef HAVE_MENU
   /* By default, we want the menu to persist through driver reinits. */
   driver->menu_data_own = true;
#endif

   if (flags & (DRIVER_VIDEO | DRIVER_AUDIO))
      driver_adjust_system_rates();

   if (flags & DRIVER_VIDEO)
   {
      init_video();

      if (!driver->video_cache_context_ack
            && global->system.hw_render_callback.context_reset)
         global->system.hw_render_callback.context_reset();
      driver->video_cache_context_ack = false;

      global->system.frame_time_last = 0;
   }

   if (flags & DRIVER_AUDIO)
      init_audio();

   /* Only initialize camera driver if we're ever going to use it. */
   if ((flags & DRIVER_CAMERA) && driver->camera_active)
      init_camera();

   /* Only initialize location driver if we're ever going to use it. */
   if ((flags & DRIVER_LOCATION) && driver->location_active)
      init_location();

#ifdef HAVE_MENU
   menu_update_libretro_info();

   if (flags & DRIVER_MENU)
   {
      init_menu();
      menu_driver_context_reset();
   }
#endif

   if (flags & (DRIVER_VIDEO | DRIVER_AUDIO))
   {
      /* Keep non-throttled state as good as possible. */
      if (driver->nonblock_state)
         driver_set_nonblock_state(driver->nonblock_state);
   }
}
コード例 #14
0
ファイル: netplay_sync.c プロジェクト: Alcaro/RetroArch
/**
 * netplay_sync_post_frame
 * @netplay              : pointer to netplay object
 *
 * Post-frame for Netplay synchronization.
 * We check if we have new input and replay from recorded input.
 */
void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
{
   uint32_t lo_frame_count, hi_frame_count;

   /* Unless we're stalling, we've just finished running a frame */
   if (!stalled)
   {
      netplay->run_ptr = NEXT_PTR(netplay->run_ptr);
      netplay->run_frame_count++;
   }

   /* We've finished an input frame even if we're stalling */
   if ((!stalled || netplay->stall == NETPLAY_STALL_INPUT_LATENCY) &&
       netplay->self_frame_count < netplay->run_frame_count + netplay->input_latency_frames)
   {
      netplay->self_ptr = NEXT_PTR(netplay->self_ptr);
      netplay->self_frame_count++;
   }

   /* Only relevant if we're connected and not in a desynching operation */
   if ((netplay->is_server && !netplay->connected_players) ||
       (netplay->self_mode < NETPLAY_CONNECTION_CONNECTED) ||
       (netplay->desync))
   {
      netplay->other_frame_count = netplay->self_frame_count;
      netplay->other_ptr = netplay->self_ptr;
      /* FIXME: Duplication */
      if (netplay->catch_up)
      {
         netplay->catch_up = false;
         input_driver_unset_nonblock_state();
         driver_set_nonblock_state();
      }
      return;
   }

   /* Reset if it was requested */
   if (netplay->force_reset)
   {
      core_reset();
      netplay->force_reset = false;
   }

#ifndef DEBUG_NONDETERMINISTIC_CORES
   if (!netplay->force_rewind)
   {
      /* Skip ahead if we predicted correctly.
       * Skip until our simulation failed. */
      while (netplay->other_frame_count < netplay->unread_frame_count &&
             netplay->other_frame_count < netplay->run_frame_count)
      {
         struct delta_frame *ptr = &netplay->buffer[netplay->other_ptr];
         size_t i;

         for (i = 0; i < MAX_USERS; i++)
         {
            if (memcmp(ptr->simulated_input_state[i], ptr->real_input_state[i],
                     sizeof(ptr->real_input_state[i])) != 0
                  && !ptr->used_real[i])
               break;
         }
         if (i != MAX_USERS) break;
         netplay_handle_frame_hash(netplay, ptr);
         netplay->other_ptr = NEXT_PTR(netplay->other_ptr);
         netplay->other_frame_count++;
      }
   }
#endif

   /* Now replay the real input if we've gotten ahead of it */
   if (netplay->force_rewind ||
       (netplay->other_frame_count < netplay->unread_frame_count &&
        netplay->other_frame_count < netplay->run_frame_count))
   {
      retro_ctx_serialize_info_t serial_info;

      /* Replay frames. */
      netplay->is_replay = true;
      netplay->replay_ptr = netplay->other_ptr;
      netplay->replay_frame_count = netplay->other_frame_count;

      if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
         /* Make sure we're initialized before we start loading things */
         netplay_wait_and_init_serialization(netplay);

      serial_info.data       = NULL;
      serial_info.data_const = netplay->buffer[netplay->replay_ptr].state;
      serial_info.size       = netplay->state_size;

      if (!core_unserialize(&serial_info))
      {
         RARCH_ERR("Netplay savestate loading failed: Prepare for desync!\n");
      }

      while (netplay->replay_frame_count < netplay->run_frame_count)
      {
         retro_time_t start, tm;

         struct delta_frame *ptr = &netplay->buffer[netplay->replay_ptr];
         serial_info.data       = ptr->state;
         serial_info.size       = netplay->state_size;
         serial_info.data_const = NULL;

         start = cpu_features_get_time_usec();

         /* Remember the current state */
         memset(serial_info.data, 0, serial_info.size);
         core_serialize(&serial_info);
         if (netplay->replay_frame_count < netplay->unread_frame_count)
            netplay_handle_frame_hash(netplay, ptr);

         /* Re-simulate this frame's input */
         netplay_simulate_input(netplay, netplay->replay_ptr, true);

         autosave_lock();
         core_run();
         autosave_unlock();
         netplay->replay_ptr = NEXT_PTR(netplay->replay_ptr);
         netplay->replay_frame_count++;

#ifdef DEBUG_NONDETERMINISTIC_CORES
         if (ptr->have_remote && netplay_delta_frame_ready(netplay, &netplay->buffer[netplay->replay_ptr], netplay->replay_frame_count))
         {
            RARCH_LOG("PRE  %u: %X\n", netplay->replay_frame_count-1, netplay_delta_frame_crc(netplay, ptr));
            if (netplay->is_server)
               RARCH_LOG("INP  %X %X\n", ptr->real_input_state[0], ptr->self_state[0]);
            else
               RARCH_LOG("INP  %X %X\n", ptr->self_state[0], ptr->real_input_state[0]);
            ptr = &netplay->buffer[netplay->replay_ptr];
            serial_info.data = ptr->state;
            memset(serial_info.data, 0, serial_info.size);
            core_serialize(&serial_info);
            RARCH_LOG("POST %u: %X\n", netplay->replay_frame_count-1, netplay_delta_frame_crc(netplay, ptr));
         }
#endif

         /* Get our time window */
         tm = cpu_features_get_time_usec() - start;
         netplay->frame_run_time_sum -= netplay->frame_run_time[netplay->frame_run_time_ptr];
         netplay->frame_run_time[netplay->frame_run_time_ptr] = tm;
         netplay->frame_run_time_sum += tm;
         netplay->frame_run_time_ptr++;
         if (netplay->frame_run_time_ptr >= NETPLAY_FRAME_RUN_TIME_WINDOW)
            netplay->frame_run_time_ptr = 0;
      }

      /* Average our time */
      netplay->frame_run_time_avg = netplay->frame_run_time_sum / NETPLAY_FRAME_RUN_TIME_WINDOW;

      if (netplay->unread_frame_count < netplay->run_frame_count)
      {
         netplay->other_ptr = netplay->unread_ptr;
         netplay->other_frame_count = netplay->unread_frame_count;
      }
      else
      {
         netplay->other_ptr = netplay->run_ptr;
         netplay->other_frame_count = netplay->run_frame_count;
      }
      netplay->is_replay = false;
      netplay->force_rewind = false;
   }

   if (netplay->is_server)
   {
      uint32_t player;

      lo_frame_count = hi_frame_count = netplay->unread_frame_count;

      /* Look for players that are ahead of us */
      for (player = 0; player < MAX_USERS; player++)
      {
         if (!(netplay->connected_players & (1<<player))) continue;
         if (netplay->read_frame_count[player] > hi_frame_count)
            hi_frame_count = netplay->read_frame_count[player];
      }
   }
   else
   {
      lo_frame_count = hi_frame_count = netplay->server_frame_count;
   }

   /* If we're behind, try to catch up */
   if (netplay->catch_up)
   {
      /* Are we caught up? */
      if (netplay->self_frame_count + 1 >= lo_frame_count)
      {
         netplay->catch_up = false;
         input_driver_unset_nonblock_state();
         driver_set_nonblock_state();
      }

   }
   else if (!stalled)
   {
      if (netplay->self_frame_count + 3 < lo_frame_count)
      {
         retro_time_t cur_time = cpu_features_get_time_usec();
         uint32_t cur_behind = lo_frame_count - netplay->self_frame_count;

         /* We're behind, but we'll only try to catch up if we're actually
          * falling behind, i.e. if we're more behind after some time */
         if (netplay->catch_up_time == 0)
         {
            /* Record our current time to check for catch-up later */
            netplay->catch_up_time = cur_time;
            netplay->catch_up_behind = cur_behind;

         }
         else if (cur_time - netplay->catch_up_time > CATCH_UP_CHECK_TIME_USEC)
         {
            /* Time to check how far behind we are */
            if (netplay->catch_up_behind <= cur_behind)
            {
               /* We're definitely falling behind! */
               netplay->catch_up = true;
               netplay->catch_up_time = 0;
               input_driver_set_nonblock_state();
               driver_set_nonblock_state();
            }
            else
            {
               /* Check again in another period */
               netplay->catch_up_time = cur_time;
               netplay->catch_up_behind = cur_behind;
            }
         }

      }
      else if (netplay->self_frame_count + 3 < hi_frame_count)
      {
         size_t i;
         netplay->catch_up_time = 0;

         /* We're falling behind some clients but not others, so request that
          * clients ahead of us stall */
         for (i = 0; i < netplay->connections_size; i++)
         {
            struct netplay_connection *connection = &netplay->connections[i];
            int player;
            if (!connection->active ||
                connection->mode != NETPLAY_CONNECTION_PLAYING)
               continue;
            player = connection->player;

            /* Are they ahead? */
            if (netplay->self_frame_count + 3 < netplay->read_frame_count[player])
            {
               /* Tell them to stall */
               if (connection->stall_frame + NETPLAY_MAX_REQ_STALL_FREQUENCY <
                     netplay->self_frame_count)
               {
                  connection->stall_frame = netplay->self_frame_count;
                  netplay_cmd_stall(netplay, connection,
                     netplay->read_frame_count[player] -
                     netplay->self_frame_count + 1);
               }
            }
         }
      }
      else
         netplay->catch_up_time = 0;
   }
   else
      netplay->catch_up_time =  0;
}
コード例 #15
0
ファイル: frontend_android.c プロジェクト: AampApps/RetroArch
static void *android_app_entry(void *data)
{
   struct android_app* android_app = (struct android_app*)data;

   android_app->config = AConfiguration_new();
   AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);

   print_cur_config(android_app);

   ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
   ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, NULL);
   android_app->looper = looper;

   pthread_mutex_lock(&android_app->mutex);
   android_app->running = 1;
   pthread_cond_broadcast(&android_app->cond);
   pthread_mutex_unlock(&android_app->mutex);

   memset(&g_android, 0, sizeof(g_android));
   g_android = android_app;

   RARCH_LOG("Native Activity started.\n");
   rarch_main_clear_state();

   while (!android_app->window)
   {
      if (!android_run_events(android_app))
         goto exit;
   }

   rarch_init_msg_queue();

   if (!android_app_start_main(android_app))
   {
      g_settings.input.overlay[0] = 0;
      // threaded video doesn't work right for just displaying one frame
      g_settings.video.threaded = false;
      init_drivers();
      driver.video_poke->set_aspect_ratio(driver.video_data, ASPECT_RATIO_SQUARE);
      rarch_render_cached_frame();
      sleep(2);
      goto exit;
   }

   if (!g_extern.libretro_dummy)
      menu_rom_history_push_current();

   for (;;)
   {
      if (g_extern.system.shutdown)
         break;
      else if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME))
      {
         load_menu_game_prepare();

         // If ROM load fails, we exit RetroArch. On console it might make more sense to go back to menu though ...
         if (load_menu_game())
            g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
         else
         {
#ifdef RARCH_CONSOLE
            g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU);
#else
            return NULL;
#endif
         }

         g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME);
      }
      else if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))
      {
         driver.input->poll(NULL);

         if (driver.video_poke->set_aspect_ratio)
            driver.video_poke->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);

         // Main loop
         while (rarch_main_iterate());

         g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
      }
      else if(g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))
      {
         g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_PREINIT);

         // Menu should always run with vsync on
         video_set_nonblock_state_func(false);

         if (driver.audio_data)
            audio_stop_func();

         while((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ?
               android_run_events(android_app) : menu_iterate());

         driver_set_nonblock_state(driver.nonblock_state);

         if (driver.audio_data && !audio_start_func())
         {
            RARCH_ERR("Failed to resume audio driver. Will continue without audio.\n");
            g_extern.audio_active = false;
         }

         g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU);
      }
      else
         break;
   }

exit:
   android_app->activityState = APP_CMD_DEAD;
   RARCH_LOG("Deinitializing RetroArch...\n");

   menu_free();

   if (g_extern.config_save_on_exit && *g_extern.config_path)
      config_save_file(g_extern.config_path);

   if (g_extern.main_is_init)
      rarch_main_deinit();

   rarch_deinit_msg_queue();
#ifdef PERF_TEST
   rarch_perf_log();
#endif
   rarch_main_clear_state();

   RARCH_LOG("android_app_destroy!");
   if (android_app->inputQueue != NULL)
      AInputQueue_detachLooper(android_app->inputQueue);
   AConfiguration_delete(android_app->config);

   // exit() here is nasty.
   // pthread_exit(NULL) or return NULL; causes hanging ...
   // Should probably called ANativeActivity_finsih(), but it's bugged, it will hang our app.
   exit(0);
}
コード例 #16
0
ファイル: driver.c プロジェクト: gouchi/RetroArch
/**
 * drivers_init:
 * @flags              : Bitmask of drivers to initialize.
 *
 * Initializes drivers.
 * @flags determines which drivers get initialized.
 **/
void drivers_init(int flags)
{
   bool video_is_threaded = false;

   if (flags & DRIVER_VIDEO_MASK)
      video_driver_unset_own_driver();
   if (flags & DRIVER_AUDIO_MASK)
      audio_driver_unset_own_driver();
   if (flags & DRIVER_INPUT_MASK)
      input_driver_unset_own_driver();
   if (flags & DRIVER_CAMERA_MASK)
      camera_driver_ctl(RARCH_CAMERA_CTL_UNSET_OWN_DRIVER, NULL);
   if (flags & DRIVER_LOCATION_MASK)
      location_driver_ctl(RARCH_LOCATION_CTL_UNSET_OWN_DRIVER, NULL);
   if (flags & DRIVER_WIFI_MASK)
      wifi_driver_ctl(RARCH_WIFI_CTL_UNSET_OWN_DRIVER, NULL);

#ifdef HAVE_MENU
   /* By default, we want the menu to persist through driver reinits. */
   menu_driver_ctl(RARCH_MENU_CTL_SET_OWN_DRIVER, NULL);
#endif

   if (flags & (DRIVER_VIDEO_MASK | DRIVER_AUDIO_MASK))
      driver_adjust_system_rates();

   if (flags & DRIVER_VIDEO_MASK)
   {
      struct retro_hw_render_callback *hwr =
         video_driver_get_hw_context();

      video_driver_monitor_reset();
      video_driver_init(&video_is_threaded);

      if (!video_driver_is_video_cache_context_ack()
            && hwr->context_reset)
         hwr->context_reset();
      video_driver_unset_video_cache_context_ack();

      rarch_ctl(RARCH_CTL_SET_FRAME_TIME_LAST, NULL);
   }

   if (flags & DRIVER_AUDIO_MASK)
   {
      audio_driver_init();
      audio_driver_new_devices_list();
   }

   /* Only initialize camera driver if we're ever going to use it. */
   if ((flags & DRIVER_CAMERA_MASK) && camera_driver_ctl(RARCH_CAMERA_CTL_IS_ACTIVE, NULL))
      camera_driver_ctl(RARCH_CAMERA_CTL_INIT, NULL);

   /* Only initialize location driver if we're ever going to use it. */
   if ((flags & DRIVER_LOCATION_MASK) && location_driver_ctl(RARCH_LOCATION_CTL_IS_ACTIVE, NULL))
      init_location();

   core_info_init_current_core();

#ifdef HAVE_MENU
   if (flags & DRIVER_VIDEO_MASK)
   {
      if (flags & DRIVER_MENU_MASK)
         menu_driver_init(video_is_threaded);
   }
#endif

   if (flags & (DRIVER_VIDEO_MASK | DRIVER_AUDIO_MASK))
   {
      /* Keep non-throttled state as good as possible. */
      if (input_driver_is_nonblock_state())
         driver_set_nonblock_state();
   }

   if (flags & DRIVER_LED_MASK)
   {
      led_driver_init();
   }

   if (flags & DRIVER_MIDI_MASK)
      midi_driver_init();
}
コード例 #17
0
ファイル: driver.c プロジェクト: Skylark13/RetroArch
bool driver_ctl(enum driver_ctl_state state, void *data)
{
   switch (state)
   {
      case RARCH_DRIVER_CTL_DEINIT:
         video_driver_destroy();
         audio_driver_destroy();
         input_driver_destroy();
#ifdef HAVE_MENU
         menu_driver_ctl(RARCH_MENU_CTL_DESTROY, NULL);
#endif
         location_driver_ctl(RARCH_LOCATION_CTL_DESTROY, NULL);
         camera_driver_ctl(RARCH_CAMERA_CTL_DESTROY, NULL);
         core_uninit_libretro_callbacks();
         break;
      case RARCH_DRIVER_CTL_UNINIT:
         {
            int *flags = (int*)data;
            if (!flags)
               return false;
            uninit_drivers(*flags);
         }
         break;
      case RARCH_DRIVER_CTL_UNINIT_ALL:
         {
            int flags = DRIVERS_CMD_ALL;
            return driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags);
         }
      case RARCH_DRIVER_CTL_INIT:
         {
            int *flags = (int*)data;
            if (!flags)
               return false;
            init_drivers(*flags);
         }
         break;
      case RARCH_DRIVER_CTL_INIT_ALL:
         {
            int flags = DRIVERS_CMD_ALL;
            return driver_ctl(RARCH_DRIVER_CTL_INIT, &flags);
         }
      case RARCH_DRIVER_CTL_INIT_PRE:
         audio_driver_find_driver();
         video_driver_find_driver();
         input_driver_find_driver();
         camera_driver_ctl(RARCH_CAMERA_CTL_FIND_DRIVER, NULL);
         find_location_driver();
#ifdef HAVE_MENU
         menu_driver_ctl(RARCH_MENU_CTL_FIND_DRIVER, NULL);
#endif
         break;
      case RARCH_DRIVER_CTL_SET_REFRESH_RATE:
         {
            float *hz = (float*)data;
            video_monitor_set_refresh_rate(*hz);
            audio_driver_monitor_set_rate();
            driver_adjust_system_rates();
         }
         break;
      case RARCH_DRIVER_CTL_SET_NONBLOCK_STATE:
         driver_set_nonblock_state();
         break;
      case RARCH_DRIVER_CTL_UPDATE_SYSTEM_AV_INFO:
         {
            const struct retro_system_av_info **info = (const struct retro_system_av_info**)data;
            if (info)
               return driver_update_system_av_info(*info);
         }
         return false;
      case RARCH_DRIVER_CTL_FIND_FIRST:
         {
            driver_ctx_info_t *drv = (driver_ctx_info_t*)data;
            if (!drv)
               return false;
            return driver_find_first(drv->label, drv->s, drv->len);
         }
      case RARCH_DRIVER_CTL_FIND_PREV:
         {
            driver_ctx_info_t *drv = (driver_ctx_info_t*)data;
            if (!drv)
               return false;
            return driver_find_prev(drv->label, drv->s, drv->len);
         }
      case RARCH_DRIVER_CTL_FIND_NEXT:
         {
            driver_ctx_info_t *drv = (driver_ctx_info_t*)data;
            if (!drv)
               return false;
            return driver_find_next(drv->label, drv->s, drv->len);
         }
      case RARCH_DRIVER_CTL_FIND_INDEX:
         {
            driver_ctx_info_t *drv = (driver_ctx_info_t*)data;
            if (!drv)
               return false;
            drv->len = driver_find_index(drv->label, drv->s);
         }
         break;
      case RARCH_DRIVER_CTL_NONE:
      default:
         break;
   }

   return true;
}