Ejemplo n.º 1
0
static void limit_frame_time(void)
{
   retro_time_t current = rarch_get_time_usec();
   retro_time_t target  = 0, to_sleep_ms = 0;
   double effective_fps = g_extern.system.av_info.timing.fps 
      * g_settings.fastforward_ratio;
   double mft_f = 1000000.0f / effective_fps;

   g_extern.frame_limit.minimum_frame_time = (retro_time_t) roundf(mft_f);

   target = g_extern.frame_limit.last_frame_time + 
      g_extern.frame_limit.minimum_frame_time;
   to_sleep_ms = (target - current) / 1000;

   if (to_sleep_ms > 0)
   {
      rarch_sleep((unsigned int)to_sleep_ms);

      /* Combat jitter a bit. */
      g_extern.frame_limit.last_frame_time += 
         g_extern.frame_limit.minimum_frame_time;
   }
   else
      g_extern.frame_limit.last_frame_time = rarch_get_time_usec();
}
Ejemplo n.º 2
0
/**
 * rarch_limit_frame_time:
 *
 * Limit frame time if fast forward ratio throttle is enabled.
 **/
static void rarch_limit_frame_time(settings_t *settings, runloop_t *runloop)
{
   retro_time_t target      = 0;
   retro_time_t to_sleep_ms = 0;
   retro_time_t current     = rarch_get_time_usec();
   struct retro_system_av_info *av_info = 
      video_viewport_get_system_av_info();
   double effective_fps     = av_info->timing.fps * settings->fastforward_ratio;
   double mft_f             = 1000000.0f / effective_fps;

   runloop->frames.limit.minimum_time = (retro_time_t) roundf(mft_f);

   target        = runloop->frames.limit.last_time + 
                   runloop->frames.limit.minimum_time;
   to_sleep_ms   = (target - current) / 1000;

   if (to_sleep_ms <= 0)
   {
      runloop->frames.limit.last_time = rarch_get_time_usec();
      return;
   }

   rarch_sleep((unsigned int)to_sleep_ms);

   /* Combat jitter a bit. */
   runloop->frames.limit.last_time += 
      runloop->frames.limit.minimum_time;
}
Ejemplo n.º 3
0
static void data_thread_loop(void *data)
{
   data_runloop_t *runloop = (data_runloop_t*)data;

   RARCH_LOG("[Data Thread]: Initializing data thread.\n");

   slock_lock(runloop->lock);
   while (!runloop->thread_inited)
      scond_wait(runloop->cond, runloop->lock);
   slock_unlock(runloop->lock);

   RARCH_LOG("[Data Thread]: Starting data thread.\n");

   while (runloop->alive)
   {
      slock_lock(runloop->lock);

      if (!runloop->alive)
         break;

      data_runloop_iterate(true);

      if (!rarch_main_data_active())
         rarch_sleep(10);

      slock_unlock(runloop->lock);

   }

   RARCH_LOG("[Data Thread]: Stopping data thread.\n");
}
Ejemplo n.º 4
0
static void emscripten_mainloop(void)
{
   int ret = rarch_main_iterate();
   if (ret == 1)
      rarch_sleep(10);
   rarch_main_data_iterate();
   if (ret != -1)
      return;

   main_exit(NULL);
   exit(0);
}
Ejemplo n.º 5
0
static void emscripten_mainloop(void)
{
   unsigned sleep_ms = 0;
   int ret = rarch_main_iterate(&sleep_ms);
   if (ret == 1 && sleep_ms > 0)
      rarch_sleep(sleep_ms);
   rarch_main_data_iterate();
   if (ret != -1)
      return;

   main_exit(NULL);
   exit(0);
}
Ejemplo n.º 6
0
static const char *get_rom_path(sgui_handle_t *sgui)
{
   uint16_t old_input_state = 0;
   bool can_quit = false;

   sgui_iterate(sgui, SGUI_ACTION_REFRESH);

   for (;;)
   {
      uint16_t input_state = 0;
      input_wii.poll(NULL);

      if (input_wii.key_pressed(NULL, RARCH_QUIT_KEY))
      {
         if (can_quit)
            return NULL;
      }
      else
         can_quit = true;

      for (unsigned i = 0; i < RARCH_FIRST_META_KEY; i++)
      {
         input_state |= input_wii.input_state(NULL, NULL, false,
               RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0;
      }

      uint16_t trigger_state = input_state & ~old_input_state;

      sgui_action_t action = SGUI_ACTION_NOOP;
      if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_B))
         action = SGUI_ACTION_CANCEL;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_A))
         action = SGUI_ACTION_OK;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_UP))
         action = SGUI_ACTION_UP;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN))
         action = SGUI_ACTION_DOWN;

      const char *ret = sgui_iterate(sgui, action);
      if (ret)
         return ret;

      video_wii.frame(NULL, menu_framebuf,
            SGUI_WIDTH, SGUI_HEIGHT,
            SGUI_WIDTH * sizeof(uint16_t), NULL);

      old_input_state = input_state;
      rarch_sleep(10);
   }
}
Ejemplo n.º 7
0
static void throttle_frame(void)
{
   if (!driver.menu)
      return;

   /* Throttle in case VSync is broken (avoid 1000+ FPS Menu). */
   driver.menu->time = rarch_get_time_usec();
   driver.menu->delta = (driver.menu->time - driver.menu->last_time) / 1000;
   driver.menu->target_msec = 750 / g_settings.video.refresh_rate;
   /* Try to sleep less, so we can hopefully rely on FPS logger. */
   driver.menu->sleep_msec = driver.menu->target_msec - driver.menu->delta;

   if (driver.menu->sleep_msec > 0)
      rarch_sleep((unsigned int)driver.menu->sleep_msec);
   driver.menu->last_time = rarch_get_time_usec();
}
Ejemplo n.º 8
0
static bool al_get_buffer(al_t *al, ALuint *buffer)
{
   if (!al->res_ptr)
   {
      for (;;)
      {
         if (al_unqueue_buffers(al))
            break;

         if (al->nonblock)
            return false;

         // Must sleep as there is no proper blocking method. :(
         rarch_sleep(1);
      }
   }

   *buffer = al->res_buf[--al->res_ptr];
   return true;
}
Ejemplo n.º 9
0
void wait_for_input(void)
{
   printf("\n\nPress Start.\n\n");
   fflush(stdout);

   while(aptMainLoop())
   {
      u32 kDown;

      hidScanInput();

      kDown = hidKeysDown();

      if (kDown & KEY_START)
         break;

      if (kDown & KEY_SELECT)
         select_pressed = true;

      rarch_sleep(1);
   }
}
Ejemplo n.º 10
0
///////////////////////////////////////////////////////////////////////////
//
//      SD_SetMusicMode() - sets the device to use for background music
//
///////////////////////////////////////////////////////////////////////////
boolean SD_SetMusicMode(SMMode mode)
{
   boolean result = false;

   SD_FadeOutMusic();
   while (SD_MusicPlaying())
      rarch_sleep(5);

   switch (mode)
   {
      case SMM_OFF:
         result = true;
         break;
      case SMM_ADLIB:
         if (AdLibPresent)
            result = true;
         break;
   }

   if (result)
      MusicMode = mode;

   return(result);
}
Ejemplo n.º 11
0
void VL_WaitVBL(int vbls)
{
   rarch_sleep(vbls * 8);
}
Ejemplo n.º 12
0
bool menu_iterate(void *data)
{
   unsigned action;
   static bool initial_held = true;
   static bool first_held = false;
   uint64_t input_state;
   int32_t input_entry_ret, ret;
   rgui_handle_t *rgui;

   input_state = 0;
   input_entry_ret = 0;
   ret = 0;
   rgui = (rgui_handle_t*)data;

   if (!rgui)
      return false;

   if (g_extern.lifecycle_state & (1ULL << MODE_MENU_PREINIT))
   {
      rgui->need_refresh = true;
      g_extern.lifecycle_state &= ~(1ULL << MODE_MENU_PREINIT);
      rgui->old_input_state |= 1ULL << RARCH_MENU_TOGGLE;
   }

   rarch_input_poll();
   rarch_check_block_hotkey();
#ifdef HAVE_OVERLAY
   rarch_check_overlay();
#endif
   rarch_check_fullscreen();

   if (input_key_pressed_func(RARCH_QUIT_KEY) || !video_alive_func())
   {
      g_extern.lifecycle_state |= (1ULL << MODE_GAME);
      return false;
   }

   input_state = menu_input(rgui);

   if (rgui->do_held)
   {
      if (!first_held)
      {
         first_held = true;
         rgui->delay_timer = initial_held ? 12 : 6;
         rgui->delay_count = 0;
      }

      if (rgui->delay_count >= rgui->delay_timer)
      {
         first_held = false;
         rgui->trigger_state = input_state;
         rgui->scroll_accel = min(rgui->scroll_accel + 1, 64);
      }

      initial_held = false;
   }
   else
   {
      first_held = false;
      initial_held = true;
      rgui->scroll_accel = 0;
   }

   rgui->delay_count++;
   rgui->old_input_state = input_state;

   if (driver.block_input)
      rgui->trigger_state = 0;

   action = RGUI_ACTION_NOOP;

   // don't run anything first frame, only capture held inputs for old_input_state
   if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_UP))
      action = RGUI_ACTION_UP;
   else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN))
      action = RGUI_ACTION_DOWN;
   else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT))
      action = RGUI_ACTION_LEFT;
   else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT))
      action = RGUI_ACTION_RIGHT;
   else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_L))
      action = RGUI_ACTION_SCROLL_UP;
   else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_R))
      action = RGUI_ACTION_SCROLL_DOWN;
   else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_B))
      action = RGUI_ACTION_CANCEL;
   else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_A))
      action = RGUI_ACTION_OK;
   else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_START))
      action = RGUI_ACTION_START;

   if (driver.menu_ctx && driver.menu_ctx->backend && driver.menu_ctx->backend->iterate) 
      input_entry_ret = driver.menu_ctx->backend->iterate(rgui, action);

   if (driver.video_data && driver.video_poke && driver.video_poke->set_texture_enable)
      driver.video_poke->set_texture_enable(driver.video_data, rgui->frame_buf_show, MENU_TEXTURE_FULLSCREEN);

   rarch_render_cached_frame();

   // Throttle in case VSync is broken (avoid 1000+ FPS RGUI).
   rgui->time = rarch_get_time_usec();
   rgui->delta = (rgui->time - rgui->last_time) / 1000;
   rgui->target_msec = 750 / g_settings.video.refresh_rate; // Try to sleep less, so we can hopefully rely on FPS logger.
   rgui->sleep_msec = rgui->target_msec - rgui->delta;

   if (rgui->sleep_msec > 0)
      rarch_sleep((unsigned int)rgui->sleep_msec);
   rgui->last_time = rarch_get_time_usec();

   if (driver.video_data && driver.video_poke && driver.video_poke->set_texture_enable)
      driver.video_poke->set_texture_enable(driver.video_data, false,
            MENU_TEXTURE_FULLSCREEN);

   if (driver.menu_ctx && driver.menu_ctx->input_postprocess)
      ret = driver.menu_ctx->input_postprocess(rgui, rgui->old_input_state);

   if (ret < 0)
   {
      unsigned type = 0;
      file_list_get_last(rgui->menu_stack, NULL, &type);
      while (type != RGUI_SETTINGS)
      {
         file_list_pop(rgui->menu_stack, &rgui->selection_ptr);
         file_list_get_last(rgui->menu_stack, NULL, &type);
      }
   }

   if (ret || input_entry_ret)
      return false;

   return true;
}
Ejemplo n.º 13
0
int rarch_main_iterate(void)
{
   unsigned i;
   retro_input_t trigger_input;
   int ret = 0;
   static retro_input_t last_input = 0;
   retro_input_t old_input = last_input;
   retro_input_t input = input_keys_pressed();

   last_input = input;

   if (driver.flushing_input)
      driver.flushing_input = (input) ? input_flush(&input) : false;

   trigger_input = input & ~old_input;

   if (time_to_exit(input))
      return -1;

   if (g_extern.system.frame_time.callback)
      update_frame_time();

#ifdef HAVE_MENU
   if (check_enter_menu_func(trigger_input) || (g_extern.libretro_dummy))
      do_state_check_menu_toggle();

   if (g_extern.is_menu)
   {
      if (menu_iterate(input, old_input, trigger_input) == -1)
         rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);

      if (!input && g_settings.menu.pause_libretro)
        ret = 1;
      goto success;
   }
#endif

   if (g_extern.exec)
   {
      g_extern.exec = false;
      return -1;
   }

   if (do_state_checks(input, old_input, trigger_input))
   {
      /* RetroArch has been paused */
      driver.retro_ctx.poll_cb();
      rarch_sleep(10);

      return 1;
   }

#if defined(HAVE_THREADS)
   lock_autosave();
#endif

#ifdef HAVE_NETPLAY
   if (driver.netplay_data)
      netplay_pre_frame((netplay_t*)driver.netplay_data);
#endif

   if (g_extern.bsv.movie)
      bsv_movie_set_frame_start(g_extern.bsv.movie);

   if (g_extern.system.camera_callback.caps)
      driver_camera_poll();

   /* Update binds for analog dpad modes. */
   for (i = 0; i < MAX_PLAYERS; i++)
   {
      if (!g_settings.input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(g_settings.input.binds[i],
            g_settings.input.analog_dpad_mode[i]);
      input_push_analog_dpad(g_settings.input.autoconf_binds[i],
            g_settings.input.analog_dpad_mode[i]);
   }

   if ((g_settings.video.frame_delay > 0) && !driver.nonblock_state)
      rarch_sleep(g_settings.video.frame_delay);


   /* Run libretro for one frame. */
   pretro_run();

   for (i = 0; i < MAX_PLAYERS; i++)
   {
      if (!g_settings.input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(g_settings.input.binds[i]);
      input_pop_analog_dpad(g_settings.input.autoconf_binds[i]);
   }

   if (g_extern.bsv.movie)
      bsv_movie_set_frame_end(g_extern.bsv.movie);

#ifdef HAVE_NETPLAY
   if (driver.netplay_data)
      netplay_post_frame((netplay_t*)driver.netplay_data);
#endif

#if defined(HAVE_THREADS)
   unlock_autosave();
#endif

success:
   if (g_settings.fastforward_ratio_throttle_enable)
      limit_frame_time();

   return ret;
}
Ejemplo n.º 14
0
/**
 * rarch_main_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until button input in order
 * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop. 
 **/
int rarch_main_iterate(void)
{
   unsigned i;
   retro_input_t trigger_input, old_input;
   event_cmd_state_t    cmd        = {0};
   int ret                         = 0;
   static retro_input_t last_input = 0;
   driver_t *driver                = driver_get_ptr();
   settings_t *settings            = config_get_ptr();
   global_t   *global              = global_get_ptr();
   runloop_t *runloop              = rarch_main_get_ptr();
   retro_input_t input             = input_keys_pressed(driver, settings, global);
   rarch_system_info_t *system     = rarch_system_info_get_ptr();

   old_input                       = last_input;
   last_input                      = input;

   if (driver->flushing_input)
      driver->flushing_input = (input) ? input_flush(runloop, &input) : false;

   trigger_input = input & ~old_input;

   rarch_main_cmd_get_state(&cmd, input, old_input, trigger_input);

   if (time_to_exit(driver, global, runloop, &cmd))
      return rarch_main_iterate_quit(settings, global);

   if (system->frame_time.callback)
      rarch_update_frame_time(driver, settings, runloop);

   do_pre_state_checks(settings, global, runloop, &cmd);

#ifdef HAVE_OVERLAY
   rarch_main_iterate_linefeed_overlay(driver, settings);
#endif
   
#ifdef HAVE_MENU
   if (menu_driver_alive())
   {
      menu_handle_t *menu = menu_driver_get_ptr();
      if (menu)
         if (menu_iterate(input, old_input, trigger_input) == -1)
            rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);

      if (!input && settings->menu.pause_libretro)
        ret = 1;
      goto success;
   }
#endif

   if (global->exec)
   {
      global->exec = false;
      return rarch_main_iterate_quit(settings, global);
   }

   if (do_state_checks(driver, settings, global, runloop, &cmd))
   {
      /* RetroArch has been paused */
      driver->retro_ctx.poll_cb();
      rarch_sleep(10);

      return 1;
   }

#if defined(HAVE_THREADS)
   lock_autosave();
#endif

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_pre_frame((netplay_t*)driver->netplay_data);
#endif

   if (global->bsv.movie)
      bsv_movie_set_frame_start(global->bsv.movie);

   if (system->camera_callback.caps)
      driver_camera_poll();

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) && !driver->nonblock_state)
      rarch_sleep(settings->video.frame_delay);


   /* Run libretro for one frame. */
   pretro_run();

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (global->bsv.movie)
      bsv_movie_set_frame_end(global->bsv.movie);

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_post_frame((netplay_t*)driver->netplay_data);
#endif

#if defined(HAVE_THREADS)
   unlock_autosave();
#endif

success:
   if (settings->fastforward_ratio_throttle_enable)
      rarch_limit_frame_time(settings, runloop);

   return ret;
}
Ejemplo n.º 15
0
static void get_binds(config_file_t *conf, config_file_t *auto_conf,
      int player, int joypad)
{
   int i, timeout_cnt;
   const rarch_joypad_driver_t *driver = input_joypad_init_driver(g_driver);
   if (!driver)
   {
      fprintf(stderr, "Cannot find any valid input driver.\n");
      exit(1);
   }

   if (!driver->query_pad(joypad))
   {
      fprintf(stderr, "Couldn't open joystick #%d.\n", joypad);
      exit(1);
   }

   fprintf(stderr, "Found joypad driver: %s\n", driver->ident);
   const char *joypad_name = input_joypad_name(driver, joypad);
   fprintf(stderr, "Using joypad: %s\n", joypad_name ? joypad_name : "Unknown");

   if (joypad_name && auto_conf)
   {
      config_set_string(auto_conf, "input_device", joypad_name);
      config_set_string(auto_conf, "input_driver", driver->ident);
   }

   int16_t initial_axes[MAX_AXES] = {0};
   struct poll_data old_poll = {{0}};
   struct poll_data new_poll = {{0}};

   int last_axis   = -1;
   bool block_axis = false;

   int timeout_ticks = g_timeout * 100;

   poll_joypad(driver, joypad, &old_poll);
   fprintf(stderr, "\nJoypads tend to have stale state after opened.\nPress some buttons and move some axes around to make sure joypad state is completely neutral before proceeding.\nWhen done, press Enter ... ");
   getchar();
   poll_joypad(driver, joypad, &old_poll);

   for (i = 0; i < MAX_AXES; i++)
   {
      int16_t initial = input_joypad_axis_raw(driver, joypad, i);
      if (abs(initial) < 20000)
         initial = 0;

      /* Certain joypads (such as XBox360 controller on Linux)
       * has a default negative axis for shoulder triggers,
       * which makes configuration very awkward.
       *
       * If default negative, we can't trigger on the negative axis, 
       * and similar with defaulted positive axes.
       */

      if (initial)
         fprintf(stderr, "Axis %d is defaulted to %s axis value of %d.\n", i, initial > 0 ? "positive" : "negative", initial);

      initial_axes[i] = initial;
   }

   for (i = 0; i < MAX_BUTTONS; i++)
   {
      if (old_poll.buttons[i])
         fprintf(stderr, "Button %d was initially pressed. This indicates broken initial state.\n", i);
   }

   fprintf(stderr, "Configuring binds for player #%d on joypad #%d.\n\n",
         player + 1, joypad);

   for (i = 0, timeout_cnt = 0; input_config_bind_map[i].valid; i++, timeout_cnt = 0)
   {
      int j;
      if (i == RARCH_TURBO_ENABLE)
         continue;

      unsigned meta_level = input_config_bind_map[i].meta;
      if (meta_level > g_meta_level)
         continue;

      fprintf(stderr, "%s\n", input_config_bind_map[i].desc);

      unsigned player_index = input_config_bind_map[i].meta ? 0 : player;

      for (;;)
      {
         old_poll = new_poll;

         /* To avoid pegging CPU.
          * Ideally use an event-based joypad scheme,
          * but it adds far more complexity, so, meh.
          */
         rarch_sleep(10);

         if (timeout_ticks)
         {
            timeout_cnt++;
            if (timeout_cnt >= timeout_ticks)
            {
               fprintf(stderr, "\tTimed out ...\n");
               break;
            }
         }

         poll_joypad(driver, joypad, &new_poll);
         for (j = 0; j < MAX_BUTTONS; j++)
         {
            if (new_poll.buttons[j] && !old_poll.buttons[j])
            {
               fprintf(stderr, "\tJoybutton pressed: %d\n", j);
               char key[64];
               snprintf(key, sizeof(key), "%s_%s_btn",
                     input_config_get_prefix(player_index,
                        input_config_bind_map[i].meta),
                     input_config_bind_map[i].base);
               config_set_int(conf, key, j);

               if (auto_conf)
               {
                  snprintf(key, sizeof(key), "input_%s_btn",
                        input_config_bind_map[i].base);
                  config_set_int(auto_conf, key, j);
               }

               goto out;
            }
         }

         for (j = 0; j < MAX_AXES; j++)
         {
            if (new_poll.axes[j] == old_poll.axes[j])
               continue;

            int16_t value         = new_poll.axes[j];
            bool same_axis        = last_axis == j;
            bool require_negative = initial_axes[j] > 0;
            bool require_positive = initial_axes[j] < 0;

            /* Block the axis config until we're sure 
             * axes have returned to their neutral state. */
            if (same_axis)
            {
               if (abs(value) < 10000 ||
                     (require_positive && value < 0) ||
                     (require_negative && value > 0))
                  block_axis = false;
            }

            /* If axes are in their neutral state, 
             * we can't allow it. */
            if (require_negative && value >= 0)
               continue;
            if (require_positive && value <= 0)
               continue;

            if (block_axis)
               continue;

            if (abs(value) > 20000)
            {
               last_axis = j;
               fprintf(stderr, "\tJoyaxis moved: Axis %d, Value %d\n",
                     j, value);

               char buf[8];
               snprintf(buf, sizeof(buf),
                     value > 0 ? "+%d" : "-%d", j);

               char key[64];
               snprintf(key, sizeof(key), "%s_%s_axis",
                     input_config_get_prefix(player_index,
                        input_config_bind_map[i].meta),
                     input_config_bind_map[i].base);

               config_set_string(conf, key, buf);

               if (auto_conf)
               {
                  snprintf(key, sizeof(key), "input_%s_axis",
                        input_config_bind_map[i].base);
                  config_set_string(auto_conf, key, buf);
               }

               block_axis = true;
               goto out;
            }
         }

         for (j = 0; j < MAX_HATS; j++)
         {
            const char *quark  = NULL;
            uint16_t value     = new_poll.hats[j];
            uint16_t old_value = old_poll.hats[j];

            if ((value & HAT_UP_MASK) && !(old_value & HAT_UP_MASK))
               quark = "up";
            else if ((value & HAT_LEFT_MASK) && !(old_value & HAT_LEFT_MASK))
               quark = "left";
            else if ((value & HAT_RIGHT_MASK) && !(old_value & HAT_RIGHT_MASK))
               quark = "right";
            else if ((value & HAT_DOWN_MASK) && !(old_value & HAT_DOWN_MASK))
               quark = "down";

            if (quark)
            {
               fprintf(stderr, "\tJoyhat moved: Hat %d, direction %s\n", j, quark);
               char buf[16];
               snprintf(buf, sizeof(buf), "h%d%s", j, quark);

               char key[64];
               snprintf(key, sizeof(key), "%s_%s_btn",
                     input_config_get_prefix(player_index,
                        input_config_bind_map[i].meta),
                     input_config_bind_map[i].base);

               config_set_string(conf, key, buf);

               if (auto_conf)
               {
                  snprintf(key, sizeof(key), "input_%s_btn",
                        input_config_bind_map[i].base);
                  config_set_string(auto_conf, key, buf);
               }

               goto out;
            }
         }
      }
out:
      old_poll = new_poll;
   }
}
Ejemplo n.º 16
0
///////////////////////////////////////////////////////////////////////////
//
//      SD_WaitSoundDone() - waits until the current sound is done playing
//
///////////////////////////////////////////////////////////////////////////
void
SD_WaitSoundDone(void)
{
   while (SD_SoundPlaying())
      rarch_sleep(5);
}
Ejemplo n.º 17
0
bool menu_iterate(void)
{
   rarch_time_t time, delta, target_msec, sleep_msec;
   static bool initial_held = true;
   static bool first_held = false;
   uint64_t input_state = 0;
   int input_entry_ret;

   if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU_PREINIT))
   {
      rgui->need_refresh = true;
      g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU_PREINIT);
      rgui->old_input_state |= 1ULL << DEVICE_NAV_MENU;
   }

   rarch_input_poll();
#ifdef HAVE_OVERLAY
   rarch_check_overlay();
#endif

   if (input_key_pressed_func(RARCH_QUIT_KEY) || !video_alive_func())
   {
      g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
      goto deinit;
   }

   input_state = rgui_input();

   if (rgui->do_held)
   {
      if (!first_held)
      {
         first_held = true;
         rgui->delay_timer = initial_held ? 12 : 6;
         rgui->delay_count = 0;
      }

      if (rgui->delay_count >= rgui->delay_timer)
      {
         first_held = false;
         rgui->trigger_state = input_state;
      }

      initial_held = false;
   }
   else
   {
      first_held = false;
      initial_held = true;
   }

   rgui->delay_count++;
   rgui->old_input_state = input_state;
   input_entry_ret = rgui_iterate(rgui);

   if (driver.video_poke && driver.video_poke->set_texture_enable)
      driver.video_poke->set_texture_enable(driver.video_data, rgui->frame_buf_show, MENU_TEXTURE_FULLSCREEN);

   rarch_render_cached_frame();

   // Throttle in case VSync is broken (avoid 1000+ FPS RGUI).
   time = rarch_get_time_usec();
   delta = (time - rgui->last_time) / 1000;
   target_msec = 750 / g_settings.video.refresh_rate; // Try to sleep less, so we can hopefully rely on FPS logger.
   sleep_msec = target_msec - delta;
   if (sleep_msec > 0)
      rarch_sleep(sleep_msec);
   rgui->last_time = rarch_get_time_usec();

   if (driver.video_poke && driver.video_poke->set_texture_enable)
      driver.video_poke->set_texture_enable(driver.video_data, false,
            MENU_TEXTURE_FULLSCREEN);

   if (rgui_input_postprocess(rgui, rgui->old_input_state) || input_entry_ret)
      goto deinit;

   return true;

deinit:
   return false;
}
Ejemplo n.º 18
0
/**
 * main_entry:
 *
 * Main function of RetroArch.
 *
 * If HAVE_MAIN is not defined, will contain main loop and will not
 * be exited from until we exit the program. Otherwise, will 
 * just do initialization.
 *
 * Returns: varies per platform.
 **/
int rarch_main(int argc, char *argv[], void *data)
{
   void *args                      = (void*)data;
   int ret                         = 0;
   settings_t *settings            = NULL;
   driver_t *driver                = NULL;

   rarch_main_alloc();

   driver = driver_get_ptr();

   if (driver)
      driver->frontend_ctx = (frontend_ctx_driver_t*)frontend_ctx_init_first();

   if (!driver || !driver->frontend_ctx)
      RARCH_WARN("Frontend context could not be initialized.\n");

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

   rarch_main_new();

   if (driver->frontend_ctx)
   {
      if (!(ret = (main_load_content(argc, argv, args,
                     driver->frontend_ctx->environment_get,
                     driver->frontend_ctx->process_args))))
         return ret;
   }

   event_command(EVENT_CMD_HISTORY_INIT);

   settings = config_get_ptr();

   if (settings->history_list_enable)
   {
      global_t *global             = global_get_ptr();
      rarch_system_info_t *system = rarch_system_info_get_ptr();

      if (global->inited.content || system->no_content)
         history_playlist_push(
               g_defaults.history,
               global->path.fullpath,
               settings->libretro,
               system ? &system->info : NULL);
   }

   if (driver)
      driver->ui_companion = (ui_companion_driver_t*)ui_companion_init_first();

   if (driver->ui_companion && driver->ui_companion->toggle)
   {
      if (settings->ui.companion_start_on_boot)
         driver->ui_companion->toggle(driver->ui_companion_data);
   }

#ifndef HAVE_MAIN
   do{
      ret = rarch_main_iterate();
      
      if (ret == 1)
         rarch_sleep(10);
      rarch_main_data_iterate();
   }while(ret != -1);

   main_exit(args);
#endif

   return 0;
}
Ejemplo n.º 19
0
static void get_binds(config_file_t *conf, int player, int joypad)
{
   const rarch_joypad_driver_t *driver = input_joypad_init_first();
   if (!driver)
   {
      fprintf(stderr, "Cannot find any valid input driver.\n");
      exit(1);
   }

   if (!driver->query_pad(joypad))
   {
      fprintf(stderr, "Couldn't open joystick #%u.\n", joypad);
      exit(1);
   }

   fprintf(stderr, "Found joypad driver: %s\n", driver->ident);

   int16_t initial_axes[MAX_AXES] = {0};
   struct poll_data old_poll = {{0}};
   struct poll_data new_poll = {{0}};

   int last_axis   = -1;
   bool block_axis = false;

   poll_joypad(driver, joypad, &old_poll);

   for (int i = 0; i < MAX_AXES; i++)
   {
      int16_t initial = input_joypad_axis_raw(driver, joypad, i);
      if (abs(initial) < 20000)
         initial = 0;

      // Certain joypads (such as XBox360 controller on Linux) has a default negative axis for shoulder triggers,
      // which makes configuration very awkward.
      // If default negative, we can't trigger on the negative axis, and similar with defaulted positive axes.

      if (initial)
         fprintf(stderr, "Axis %d is defaulted to %s axis value of %d\n", i, initial > 0 ? "positive" : "negative", initial);

      initial_axes[i] = initial;
   }

   fprintf(stderr, "Configuring binds for player #%d on joypad #%d.\n\n",
         player + 1, joypad);

   for (unsigned i = 0; i < sizeof(binds) / sizeof(binds[0]) && (g_use_misc || !binds[i].is_misc) ; i++)
   {
      fprintf(stderr, "%s\n", binds[i].keystr);

      unsigned player_index = binds[i].is_misc ? 0 : player;

      for (;;)
      {
         old_poll = new_poll;

         // To avoid pegging CPU.
         // Ideally use an event-based joypad scheme,
         // but it adds far more complexity, so, meh.
         rarch_sleep(10);

         poll_joypad(driver, joypad, &new_poll);
         for (int j = 0; j < MAX_BUTTONS; j++)
         {
            if (new_poll.buttons[j] && !old_poll.buttons[j])
            {
               fprintf(stderr, "\tJoybutton pressed: %u\n", j);
               config_set_int(conf, binds[i].confbtn[player_index], j);
               goto out;
            }
         }

         for (int j = 0; j < MAX_AXES; j++)
         {
            if (new_poll.axes[j] != old_poll.axes[j])
            {
               int16_t value         = new_poll.axes[j];
               bool same_axis        = last_axis == j;
               bool require_negative = initial_axes[j] > 0;
               bool require_positive = initial_axes[j] < 0;

               // Block the axis config until we're sure axes have returned to their neutral state.
               if (same_axis)
               {
                  if (abs(value) < 10000 ||
                        (require_positive && value < 0) ||
                        (require_negative && value > 0))
                     block_axis = false;
               }

               // If axes are in their neutral state, we can't allow it.
               if (require_negative && value >= 0)
                  continue;
               if (require_positive && value <= 0)
                  continue;

               if (block_axis)
                  continue;

               if (abs(value) > 20000)
               {
                  last_axis = j;
                  fprintf(stderr, "\tJoyaxis moved: Axis %d, Value %d\n", j, value);

                  char buf[8];
                  snprintf(buf, sizeof(buf),
                        value > 0 ? "+%d" : "-%d", j);

                  config_set_string(conf, binds[i].confaxis[player_index], buf);
                  block_axis = true;
                  goto out;
               }
            }
         }

         for (int j = 0; j < MAX_HATS; j++)
         {
            const char *quark  = NULL;
            uint16_t value     = new_poll.hats[j];
            uint16_t old_value = old_poll.hats[j];

            if ((value & HAT_UP_MASK) && !(old_value & HAT_UP_MASK))
               quark = "up";
            else if ((value & HAT_LEFT_MASK) && !(old_value & HAT_LEFT_MASK))
               quark = "left";
            else if ((value & HAT_RIGHT_MASK) && !(old_value & HAT_RIGHT_MASK))
               quark = "right";
            else if ((value & HAT_DOWN_MASK) && !(old_value & HAT_DOWN_MASK))
               quark = "down";

            if (quark)
            {
               fprintf(stderr, "\tJoyhat moved: Hat %d, direction %s\n", j, quark);
               char buf[16];
               snprintf(buf, sizeof(buf), "h%d%s", j, quark);
               config_set_string(conf, binds[i].confbtn[player_index], buf);
               goto out;
            }
         }
      }
out:
      old_poll = new_poll;
   }
}
Ejemplo n.º 20
0
/**
 * rarch_main_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until button input in order
 * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop. 
 **/
int rarch_main_iterate(unsigned *sleep_ms)
{
   unsigned i;
   retro_input_t trigger_input;
   event_cmd_state_t    cmd;
   bool do_quit                    = false;
   static retro_input_t last_input = 0;
   driver_t *driver                = driver_get_ptr();
   settings_t *settings            = config_get_ptr();
   global_t   *global              = global_get_ptr();
   retro_input_t input             = input_keys_pressed(driver, settings, global);
   rarch_system_info_t *system     = rarch_system_info_get_ptr();
   retro_input_t old_input         = last_input;

   last_input                      = input;

   if (driver->flushing_input)
   {
      driver->flushing_input = false;
      if (input)
      {
         input = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (main_is_paused)
            BIT64_SET(input, RARCH_PAUSE_TOGGLE);
         driver->flushing_input = true;
      }
   }

   trigger_input = input & ~old_input;

   rarch_main_cmd_get_state(driver, settings, &cmd, input, old_input, trigger_input);

   if (time_to_exit(driver, global, system, &cmd))
      do_quit = true;

   if (system->frame_time.callback)
      rarch_update_frame_time(driver, settings->slowmotion_ratio, system);

   do_pre_state_checks(settings, global, &cmd);

#ifdef HAVE_OVERLAY
   rarch_main_iterate_linefeed_overlay(driver, settings);
#endif

   if (global->exec)
   {
      global->exec = false;
      do_quit      = true;
   }

   if (do_quit)
   {
      /* Quits out of RetroArch main loop.
       * On special case, loads dummy core 
       * instead of exiting RetroArch completely.
       * Aborts core shutdown if invoked.
       */
      if (global->core_shutdown_initiated
            && settings->load_dummy_on_core_shutdown)
      {
         if (!event_command(EVENT_CMD_PREPARE_DUMMY))
            return -1;

         system->shutdown = false;
         global->core_shutdown_initiated = false;

         return 0;
      }

      return -1;
   }
   
#ifdef HAVE_MENU
   if (menu_driver_alive())
   {
      menu_handle_t *menu = menu_driver_get_ptr();
      if (menu)
         if (menu_iterate(true, menu_input_frame(input, trigger_input)) == -1)
            rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);

      if (!input && settings->menu.pause_libretro)
        return 1;
      return rarch_limit_frame_time(settings->fastforward_ratio, sleep_ms);
   }
#endif

   if (do_state_checks(driver, settings, global, &cmd))
   {
      /* RetroArch has been paused. */
      driver->retro_ctx.poll_cb();
      *sleep_ms = 10;
      return 1;
   }

#if defined(HAVE_THREADS)
   lock_autosave();
#endif

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_pre_frame((netplay_t*)driver->netplay_data);
#endif

   if (global->bsv.movie)
      bsv_movie_set_frame_start(global->bsv.movie);

   if (system->camera_callback.caps)
      driver_camera_poll();

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) && !driver->nonblock_state)
      rarch_sleep(settings->video.frame_delay);

   /* Run libretro for one frame. */
   pretro_run();

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (global->bsv.movie)
      bsv_movie_set_frame_end(global->bsv.movie);

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_post_frame((netplay_t*)driver->netplay_data);
#endif

#if defined(HAVE_THREADS)
   unlock_autosave();
#endif

   return rarch_limit_frame_time(settings->fastforward_ratio, sleep_ms);
}
Ejemplo n.º 21
0
///////////////////////////////////////////////////////////////////////////
//
//  US_LineInput() - Gets a line of user input at (x,y), the string defaults
//      to whatever is pointed at by def. Input is restricted to maxchars
//      chars or maxwidth pixels wide. If the user hits escape (and escok is
//      true), nothing is copied into buf, and false is returned. If the
//      user hits return, the current string is copied into buf, and true is
//      returned
//
///////////////////////////////////////////////////////////////////////////
boolean
US_LineInput(int x,int y,char *buf,const char *def,boolean escok,
                int maxchars,int maxwidth)
{
   boolean     redraw,
               cursorvis,cursormoved,
               done,result, checkkey;
   ScanCode    sc;
   char        c;
   char        s[MaxString],olds[MaxString];
   int         cursor,len;
   word        i,
               w,h,
               temp;
   longword    curtime, lasttime, lastdirtime, lastbuttontime, lastdirmovetime;
   ControlInfo ci;
   Direction   lastdir = dir_None;

   if (def)
      strcpy(s,def);
   else
      *s = '\0';
   *olds = '\0';
   cursor = (int) strlen(s);
   cursormoved = redraw = true;

   cursorvis = done = false;
   lasttime = lastdirtime = lastdirmovetime = GetTimeCount();
   lastbuttontime = lasttime + TickBase / 4;   // 250 ms => first button press accepted after 500 ms
   LastASCII = key_None;
   LastScan = sc_None;

   while (!done)
   {
      ReadAnyControl(&ci);

      if (cursorvis)
         USL_XORICursor(x,y,s,cursor);

      sc = LastScan;
      LastScan = sc_None;
      c = LastASCII;
      LastASCII = key_None;

      checkkey = true;
      curtime = GetTimeCount();

      // After each direction change accept the next change after 250 ms and then everz 125 ms
      if(ci.dir != lastdir || ((curtime - lastdirtime > TickBase / 4) && (curtime - lastdirmovetime > TickBase / 8)))
      {
         if(ci.dir != lastdir)
         {
            lastdir = ci.dir;
            lastdirtime = curtime;
         }
         lastdirmovetime = curtime;

         switch(ci.dir)
         {
            case dir_West:
               if(cursor)
               {
                  // Remove trailing whitespace if cursor is at end of string
                  if(s[cursor] == ' ' && s[cursor + 1] == 0)
                     s[cursor] = 0;
                  cursor--;
               }
               cursormoved = true;
               checkkey = false;
               break;
            case dir_East:
               if(cursor >= MaxString - 1) break;

               if(!s[cursor])
               {
                  USL_MeasureString(s,&w,&h);
                  if(len >= maxchars || (maxwidth && w >= maxwidth))
                     break;

                  s[cursor] = ' ';
                  s[cursor + 1] = 0;
               }
               cursor++;
               cursormoved = true;
               checkkey = false;
               break;

            case dir_North:
               if(!s[cursor])
               {
                  USL_MeasureString(s,&w,&h);
                  if(len >= maxchars || (maxwidth && w >= maxwidth))
                     break;
                  s[cursor + 1] = 0;
               }
               s[cursor] = USL_RotateChar(s[cursor], 1);
               redraw = true;
               checkkey = false;
               break;

            case dir_South:
               if(!s[cursor])
               {
                  USL_MeasureString(s,&w,&h);
                  if(len >= maxchars || (maxwidth && w >= maxwidth))
                     break;
                  s[cursor + 1] = 0;
               }
               s[cursor] = USL_RotateChar(s[cursor], -1);
               redraw = true;
               checkkey = false;
               break;
            default:
               break;
         }
      }

      if((int)(curtime - lastbuttontime) > TickBase / 4)   // 250 ms
      {
         if(ci.button0)             // acts as return
         {
            strcpy(buf,s);
            done = true;
            result = true;
            checkkey = false;
         }
         if(ci.button1 && escok)    // acts as escape
         {
            done = true;
            result = false;
            checkkey = false;
         }
         if(ci.button2)             // acts as backspace
         {
            lastbuttontime = curtime;
            if(cursor)
            {
               strcpy(s + cursor - 1,s + cursor);
               cursor--;
               redraw = true;
            }
            cursormoved = true;
            checkkey = false;
         }
      }

      if(checkkey)
      {
         switch (sc)
         {
            case sc_LeftArrow:
               if (cursor)
                  cursor--;
               c = key_None;
               cursormoved = true;
               break;
            case sc_RightArrow:
               if (s[cursor])
                  cursor++;
               c = key_None;
               cursormoved = true;
               break;
            case sc_Home:
               cursor = 0;
               c = key_None;
               cursormoved = true;
               break;
            case sc_End:
               cursor = (int) strlen(s);
               c = key_None;
               cursormoved = true;
               break;

            case sc_Return:
               strcpy(buf,s);
               done = true;
               result = true;
               c = key_None;
               break;
            case sc_Escape:
               if (escok)
               {
                  done = true;
                  result = false;
               }
               c = key_None;
               break;

            case sc_BackSpace:
               if (cursor)
               {
                  strcpy(s + cursor - 1,s + cursor);
                  cursor--;
                  redraw = true;
               }
               c = key_None;
               cursormoved = true;
               break;
            case sc_Delete:
               if (s[cursor])
               {
                  strcpy(s + cursor,s + cursor + 1);
                  redraw = true;
               }
               c = key_None;
               cursormoved = true;
               break;

            case SDLK_KP5: //0x4c:  // Keypad 5 // TODO: hmmm...
            case sc_UpArrow:
            case sc_DownArrow:
            case sc_PgUp:
            case sc_PgDn:
            case sc_Insert:
               c = key_None;
               break;
         }

         if (c)
         {
            len = (int) strlen(s);
            USL_MeasureString(s,&w,&h);

            if(isprint(c) && (len < MaxString - 1) && ((!maxchars) || (len < maxchars))
                  && ((!maxwidth) || (w < maxwidth)))
            {
               for (i = len + 1;i > cursor;i--)
                  s[i] = s[i - 1];
               s[cursor++] = c;
               redraw = true;
            }
         }
      }

      if (redraw)
      {
         px = x;
         py = y;
         temp = fontcolor;
         fontcolor = backcolor;
         USL_DrawString(olds);
         fontcolor = (byte) temp;
         strcpy(olds,s);

         px = x;
         py = y;
         USL_DrawString(s);

         redraw = false;
      }

      if (cursormoved)
      {
         cursorvis = false;
         lasttime = curtime - TickBase;

         cursormoved = false;
      }
      if (curtime - lasttime > TickBase / 2)    // 500 ms
      {
         lasttime = curtime;

         cursorvis ^= true;
      }
      else rarch_sleep(5);
      if (cursorvis)
         USL_XORICursor(x,y,s,cursor);

      VW_UpdateScreen();
   }

   if (cursorvis)
      USL_XORICursor(x,y,s,cursor);
   if (!result)
   {
      px = x;
      py = y;
      USL_DrawString(olds);
   }
   VW_UpdateScreen();

   IN_ClearKeysDown();
   return(result);
}
Ejemplo n.º 22
0
static bool get_rom_path(rgui_handle_t *rgui)
{
   uint16_t old_input_state = 0;
   bool can_quit = false;
   bool first = true;

   for (;;)
   {
      uint16_t input_state = 0;
      input_wii.poll(NULL);

      if (input_wii.key_pressed(NULL, RARCH_QUIT_KEY))
      {
         if (can_quit)
            return false;
      }
      else
         can_quit = true;

      for (unsigned i = 0; i < RARCH_FIRST_META_KEY; i++)
      {
         input_state |= input_wii.input_state(NULL, NULL, false,
               RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0;
      }

      uint16_t trigger_state = input_state & ~old_input_state;

      rgui_action_t action = RGUI_ACTION_NOOP;
      if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_B))
         action = RGUI_ACTION_CANCEL;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_A))
         action = RGUI_ACTION_OK;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_UP))
         action = RGUI_ACTION_UP;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN))
         action = RGUI_ACTION_DOWN;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT))
         action = RGUI_ACTION_LEFT;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT))
         action = RGUI_ACTION_RIGHT;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_START))
         action = RGUI_ACTION_START;
      else if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_SELECT) && !first) // don't catch start+select+l+r when exiting
         action = RGUI_ACTION_SETTINGS;

      const char *ret = rgui_iterate(rgui, action);
      video_wii.frame(NULL, menu_framebuf,
            RGUI_WIDTH, RGUI_HEIGHT,
            RGUI_WIDTH * sizeof(uint16_t), NULL);

      if (ret)
      {
         g_console.initialize_rarch_enable = true;
         strlcpy(g_console.rom_path, ret, sizeof(g_console.rom_path));
         if (rarch_startup(NULL))
            return true;
      }

      old_input_state = input_state;
      first = false;
      rarch_sleep(10);
   }
}