示例#1
0
static bool runloop_cmd_get_state_menu_toggle_button_combo(
      settings_t *settings,
      retro_input_t input, retro_input_t old_input,
      retro_input_t trigger_input)
{
   switch (settings->input.menu_toggle_gamepad_combo)
   {
      case 0:
         return false;
      case 1:
         if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_DOWN))
            return false;
         if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_Y))
            return false;
         if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_L))
            return false;
         if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_R))
            return false;
         break;
      case 2:
         if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_L3))
            return false;
         if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_R3))
            return false;
         break;
   }

   input_driver_set_flushing_input();
   return true;
}
示例#2
0
static void menu_driver_toggle(bool latch)
{
   retro_keyboard_event_t *key_event          = NULL;
   retro_keyboard_event_t *frontend_key_event = NULL;
   settings_t                 *settings       = config_get_ptr();
   
   menu_driver_ctl(RARCH_MENU_CTL_TOGGLE, &latch);

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

   runloop_ctl(RUNLOOP_CTL_FRONTEND_KEY_EVENT_GET, &frontend_key_event);
   runloop_ctl(RUNLOOP_CTL_KEY_EVENT_GET,          &key_event);

   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      bool refresh = false;
      menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);

      /* Menu should always run with vsync on. */
      command_event(CMD_EVENT_VIDEO_SET_BLOCKING_STATE, NULL);
      /* Stop all rumbling before entering the menu. */
      command_event(CMD_EVENT_RUMBLE_STOP, NULL);

      if (settings->menu.pause_libretro)
         command_event(CMD_EVENT_AUDIO_STOP, NULL);

      /* Override keyboard callback to redirect to menu instead.
       * We'll use this later for something ... */

      if (key_event && frontend_key_event)
      {
         *frontend_key_event        = *key_event;
         *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_ctl(RARCH_DRIVER_CTL_SET_NONBLOCK_STATE, NULL);

      if (settings && settings->menu.pause_libretro)
         command_event(CMD_EVENT_AUDIO_START, NULL);

      /* Prevent stray input from going to libretro core */
      input_driver_set_flushing_input();

      /* Restore libretro keyboard callback. */
      if (key_event && frontend_key_event)
         *key_event = *frontend_key_event;
   }
}
示例#3
0
void menu_input_key_end_line(void)
{
   bool keyboard_display    = false;

   menu_input_ctl(MENU_INPUT_CTL_SET_KEYBOARD_DISPLAY, &keyboard_display);
   menu_input_ctl(MENU_INPUT_CTL_UNSET_KEYBOARD_LABEL, NULL);
   menu_input_ctl(MENU_INPUT_CTL_UNSET_KEYBOARD_LABEL_SETTING, NULL);

   /* Avoid triggering states on pressing return. */
   input_driver_set_flushing_input();
}
示例#4
0
void menu_input_dialog_end(void)
{
   menu_input_dialog_keyboard_type             = 0;
   menu_input_dialog_keyboard_idx              = 0;
   menu_input_dialog_keyboard_display          = false; 
   menu_input_dialog_keyboard_label[0]         = '\0';
   menu_input_dialog_keyboard_label_setting[0] = '\0';

   /* Avoid triggering states on pressing return. */
   input_driver_set_flushing_input();
}
示例#5
0
static bool runloop_cmd_get_state_menu_toggle_button_combo(
      settings_t *settings,
      uint64_t current_input, uint64_t old_input,
      uint64_t trigger_input)
{
   switch (settings->input.menu_toggle_gamepad_combo)
   {
      case INPUT_TOGGLE_NONE:
         return false;
      case INPUT_TOGGLE_DOWN_Y_L_R:
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_DOWN))
            return false;
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_Y))
            return false;
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_L))
            return false;
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_R))
            return false;
         break;
      case INPUT_TOGGLE_L3_R3:
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_L3))
            return false;
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_R3))
            return false;
         break;
      case INPUT_TOGGLE_L1_R1_START_SELECT:
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_START))
            return false;
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_SELECT))
            return false;
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_L))
            return false;
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_R))
            return false;
         break;
      case INPUT_TOGGLE_START_SELECT:
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_START))
            return false;
         if (!BIT64_GET(current_input, RETRO_DEVICE_ID_JOYPAD_SELECT))
            return false;
         break;
   }

   input_driver_set_flushing_input();
   return true;
}
示例#6
0
/**
 * runloop_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 runloop_iterate(unsigned *sleep_ms)
{
   unsigned i;
   event_cmd_state_t    cmd;
   retro_time_t current, target, to_sleep_ms;
   static retro_input_t last_input              = {0};
   event_cmd_state_t   *cmd_ptr                 = &cmd;
   static retro_time_t frame_limit_minimum_time = 0.0;
   static retro_time_t frame_limit_last_time    = 0.0;
   settings_t *settings                         = config_get_ptr();

   cmd.state[1]                                 = last_input;
   cmd.state[0]                                 = input_keys_pressed();
   last_input                                   = cmd.state[0];

   runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_TIME_LAST, NULL);

   if (runloop_ctl(RUNLOOP_CTL_SHOULD_SET_FRAME_LIMIT, NULL))
   {
      struct retro_system_av_info *av_info = 
         video_viewport_get_system_av_info();
      float fastforward_ratio              = 
         (settings->fastforward_ratio == 0.0f) 
         ? 1.0f : settings->fastforward_ratio;

      frame_limit_last_time    = cpu_features_get_time_usec();
      frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f 
            / (av_info->timing.fps * fastforward_ratio));

      runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_LIMIT, NULL);
   }

   if (input_driver_is_flushing_input())
   {
      input_driver_unset_flushing_input();
      if (cmd.state[0].state)
      {
         cmd.state[0].state = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL))
            BIT64_SET(cmd.state[0].state, RARCH_PAUSE_TOGGLE);
         input_driver_set_flushing_input();
      }
   }
   
   if (runloop_frame_time.callback)
   {
      /* Updates frame timing if frame timing callback is in use by the core.
       * Limits frame time if fast forward ratio throttle is enabled. */

      retro_time_t current     = cpu_features_get_time_usec();
      retro_time_t delta       = current - runloop_frame_time_last;
      bool is_locked_fps       = (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) ||
                                  input_driver_is_nonblock_state()) |
                                  !!recording_driver_get_data_ptr();


      if (!runloop_frame_time_last || is_locked_fps)
         delta = runloop_frame_time.reference;

      if (!is_locked_fps && runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, NULL))
         delta /= settings->slowmotion_ratio;

      runloop_frame_time_last = current;

      if (is_locked_fps)
         runloop_frame_time_last = 0;

      runloop_frame_time.callback(delta);
   }

   cmd.state[2].state      = cmd.state[0].state & ~cmd.state[1].state;  /* trigger  */

   if (runloop_cmd_triggered(cmd_ptr, RARCH_OVERLAY_NEXT))
      command_event(CMD_EVENT_OVERLAY_NEXT, NULL);

   if (runloop_cmd_triggered(cmd_ptr, RARCH_FULLSCREEN_TOGGLE_KEY))
   {
      bool fullscreen_toggled = !runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL);
#ifdef HAVE_MENU
      fullscreen_toggled = fullscreen_toggled || 
         menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL);
#endif

      if (fullscreen_toggled)
         command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL);
   }

   if (runloop_cmd_triggered(cmd_ptr, RARCH_GRAB_MOUSE_TOGGLE))
      command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL);

#ifdef HAVE_MENU
   if (runloop_cmd_menu_press(cmd_ptr) || 
         rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
   {
      if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
      {
         if (rarch_ctl(RARCH_CTL_IS_INITED, NULL) && 
               !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
      }
      else
         rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
   }
#endif

#ifdef HAVE_OVERLAY
   runloop_iterate_linefeed_overlay(settings);
#endif

   if (runloop_iterate_time_to_exit(
            runloop_cmd_press(cmd_ptr, RARCH_QUIT_KEY)) != 1)
   {
      frame_limit_last_time = 0.0;
      return -1;
   }


#ifdef HAVE_MENU
   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      int ret = runloop_iterate_menu((enum menu_action)
      menu_input_frame_retropad(cmd.state[0], cmd.state[2]),
      sleep_ms);

      if (ret == -1)
         goto end;
      return ret;
   }
#endif

   if (!runloop_check_state(&cmd, &runloop_shader_dir))
   {
      /* RetroArch has been paused. */
      core_poll();
      *sleep_ms = 10;
      return 1;
   }

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

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_PRE_FRAME, NULL);
#endif

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_START, NULL);

   camera_driver_ctl(RARCH_CAMERA_CTL_POLL, NULL);

   /* 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) && 
         !input_driver_is_nonblock_state())
      retro_sleep(settings->video.frame_delay);

   core_run();

#ifdef HAVE_CHEEVOS
   cheevos_test();
#endif

   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 (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_END, NULL);

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_POST_FRAME, NULL);
#endif

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

   if (!settings->fastforward_ratio)
      return 0;
#ifdef HAVE_MENU
end:
#endif

   current                        = cpu_features_get_time_usec();
   target                         = frame_limit_last_time + 
      frame_limit_minimum_time;
   to_sleep_ms                    = (target - current) / 1000;

   if (to_sleep_ms > 0)
   {
      *sleep_ms = (unsigned)to_sleep_ms;
      /* Combat jitter a bit. */
      frame_limit_last_time += frame_limit_minimum_time;
      return 1;
   }

   frame_limit_last_time  = cpu_features_get_time_usec();

   return 0;
}
示例#7
0
static bool menu_input_key_bind_iterate(char *s, size_t len)
{
   struct menu_bind_state binds;
   bool               timed_out = false;
   menu_input_t *menu_input     = menu_input_get_ptr();
   int64_t current              = cpu_features_get_time_usec();
   int timeout                  = 
      (menu_input->binds.timeout_end - current) / 1000000;

   if (timeout <= 0)
   {
      input_driver_keyboard_mapping_set_block(false);

      menu_input->binds.begin++;
      menu_input->binds.target++;
      menu_input->binds.timeout_end = cpu_features_get_time_usec() +
         MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000;
      timed_out = true;
   }

   snprintf(s, len,
         "[%s]\npress keyboard or joypad\n(timeout %d %s)",
         input_config_bind_map_get_desc(
         menu_input->binds.begin - MENU_SETTINGS_BIND_BEGIN),
         timeout,
         menu_hash_to_str(MENU_VALUE_SECONDS));

   /* binds.begin is updated in keyboard_press callback. */
   if (menu_input->binds.begin > menu_input->binds.last)
   {
      /* Avoid new binds triggering things right away. */
      input_driver_set_flushing_input();

      /* We won't be getting any key events, so just cancel early. */
      if (timed_out)
         input_keyboard_ctl(RARCH_INPUT_KEYBOARD_CTL_CANCEL_WAIT_KEYS, NULL);

      return true;
   }

   binds = menu_input->binds;

   input_driver_keyboard_mapping_set_block(true);
   menu_input_key_bind_poll_bind_state(&binds, bind_port, timed_out);

   if ((binds.skip && !menu_input->binds.skip) ||
         menu_input_key_bind_poll_find_trigger(&menu_input->binds, &binds))
   {
      input_driver_keyboard_mapping_set_block(false);

      /* Avoid new binds triggering things right away. */
      input_driver_set_flushing_input();

      binds.begin++;

      if (binds.begin > binds.last)
      {
         input_keyboard_ctl(RARCH_INPUT_KEYBOARD_CTL_CANCEL_WAIT_KEYS, NULL);
         return true;
      }

      binds.target++;
      binds.timeout_end = cpu_features_get_time_usec() +
         MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000;
   }
   menu_input->binds = binds;

   return false;
}
bool menu_input_key_bind_iterate(menu_input_ctx_bind_t *bind)
{
   struct menu_bind_state binds;
   bool               timed_out = false;
   settings_t *settings         = config_get_ptr();

   rarch_timer_tick(&menu_input_binds.timer);

   if (!bind)
      return false;

   if (rarch_timer_has_expired(&menu_input_binds.timer))
   {
      input_driver_keyboard_mapping_set_block(false);

      menu_input_binds.begin++;
      menu_input_binds.target++;
      rarch_timer_begin_new_time(&menu_input_binds.timer, settings->uints.input_bind_timeout);
      timed_out = true;
   }

   snprintf(bind->s, bind->len,
         "[%s]\npress keyboard or joypad\n(timeout %d %s)",
         input_config_bind_map_get_desc(
            menu_input_binds.begin - MENU_SETTINGS_BIND_BEGIN),
         rarch_timer_get_timeout(&menu_input_binds.timer),
         msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SECONDS));

   /* binds.begin is updated in keyboard_press callback. */
   if (menu_input_binds.begin > menu_input_binds.last)
   {
      /* Avoid new binds triggering things right away. */
      input_driver_set_flushing_input();

      /* We won't be getting any key events, so just cancel early. */
      if (timed_out)
         input_keyboard_ctl(RARCH_INPUT_KEYBOARD_CTL_CANCEL_WAIT_KEYS, NULL);

      return true;
   }

   binds = menu_input_binds;

   input_driver_keyboard_mapping_set_block(true);
   menu_input_key_bind_poll_bind_state(&binds, menu_bind_port, timed_out);

   if ((binds.skip && !menu_input_binds.skip) ||
         menu_input_key_bind_poll_find_trigger(&menu_input_binds, &binds))
   {
      input_driver_keyboard_mapping_set_block(false);

      /* Avoid new binds triggering things right away. */
      input_driver_set_flushing_input();

      binds.begin++;

      if (binds.begin > binds.last)
      {
         input_keyboard_ctl(RARCH_INPUT_KEYBOARD_CTL_CANCEL_WAIT_KEYS, NULL);
         return true;
      }

      binds.target++;
      rarch_timer_begin_new_time(&binds.timer, settings->uints.input_bind_timeout);
   }
   menu_input_binds = binds;

   return false;
}
示例#9
0
static enum runloop_state runloop_check_state(
      settings_t *settings,
      uint64_t current_input,
      uint64_t old_input,
      unsigned *sleep_ms)
{
   static bool old_focus            = true;
#ifdef HAVE_OVERLAY
   static char prev_overlay_restore = false;
   bool osk_enable                  = input_driver_is_onscreen_keyboard_enabled();
#endif
#ifdef HAVE_NETWORKING
   bool tmp                         = false;
#endif
   bool focused                     = true;
   uint64_t trigger_input           = current_input & ~old_input;
   bool pause_pressed               = runloop_cmd_triggered(trigger_input, RARCH_PAUSE_TOGGLE);

   if (input_driver_is_flushing_input())
   {
      input_driver_unset_flushing_input();
      if (current_input)
      {
         current_input = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (runloop_paused)
            BIT64_SET(current_input, RARCH_PAUSE_TOGGLE);
         input_driver_set_flushing_input();
      }
   }

   if (runloop_cmd_triggered(trigger_input, RARCH_OVERLAY_NEXT))
      command_event(CMD_EVENT_OVERLAY_NEXT, NULL);

   if (runloop_cmd_triggered(trigger_input, RARCH_FULLSCREEN_TOGGLE_KEY))
   {
      bool fullscreen_toggled = !runloop_paused;
#ifdef HAVE_MENU
      fullscreen_toggled = fullscreen_toggled ||
         menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL);
#endif

      if (fullscreen_toggled)
         command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL);
   }

   if (runloop_cmd_triggered(trigger_input, RARCH_GRAB_MOUSE_TOGGLE))
      command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL);


#ifdef HAVE_OVERLAY
   if (osk_enable && !input_keyboard_ctl(
            RARCH_INPUT_KEYBOARD_CTL_IS_LINEFEED_ENABLED, NULL))
   {
      input_driver_unset_onscreen_keyboard_enabled();
      prev_overlay_restore  = true;
      command_event(CMD_EVENT_OVERLAY_DEINIT, NULL);
   }
   else if (!osk_enable && input_keyboard_ctl(
            RARCH_INPUT_KEYBOARD_CTL_IS_LINEFEED_ENABLED, NULL))
   {
      input_driver_set_onscreen_keyboard_enabled();
      prev_overlay_restore  = false;
      command_event(CMD_EVENT_OVERLAY_INIT, NULL);
   }
   else if (prev_overlay_restore)
   {
      if (!settings->input.overlay_hide_in_menu)
         command_event(CMD_EVENT_OVERLAY_INIT, NULL);
      prev_overlay_restore = false;
   }
#endif

   if (runloop_iterate_time_to_exit(
            runloop_cmd_press(current_input, RARCH_QUIT_KEY)) != 1)
      return RUNLOOP_STATE_QUIT;

#ifdef HAVE_MENU
   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      menu_ctx_iterate_t iter;
      bool skip = false;
#ifdef HAVE_OVERLAY
      skip = osk_enable && input_keyboard_return_pressed();
#endif

      if (!skip)
      {
         enum menu_action action = (enum menu_action)menu_event(current_input, trigger_input);
         bool focused            = settings->pause_nonactive ? video_driver_is_focused() : true;

         focused                 = focused && !ui_companion_is_on_foreground();

         iter.action             = action;

         if (!menu_driver_ctl(RARCH_MENU_CTL_ITERATE, &iter))
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);

         if (focused || !runloop_idle)
            menu_driver_ctl(RARCH_MENU_CTL_RENDER, NULL);

         if (!focused)
            return RUNLOOP_STATE_SLEEP;

         if (action == MENU_ACTION_QUIT)
            return RUNLOOP_STATE_QUIT;
      }
   }
#endif
   
   if (runloop_idle)
      return RUNLOOP_STATE_SLEEP;

#ifdef HAVE_MENU
   if (menu_event_keyboard_is_set(RETROK_F1) == 1)
   {
      if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
      {
         if (rarch_ctl(RARCH_CTL_IS_INITED, NULL) &&
               !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
         {
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
            menu_event_keyboard_set(false, RETROK_F1);
         }
      }
   }
   else if ((!menu_event_keyboard_is_set(RETROK_F1) && runloop_cmd_menu_press(current_input, old_input, trigger_input)) ||
         rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
   {
      if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
      {
         if (rarch_ctl(RARCH_CTL_IS_INITED, NULL) &&
               !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
      }
      else
      {
        menu_display_toggle_set_reason(MENU_TOGGLE_REASON_USER);
        rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
      }
   }
   else
      menu_event_keyboard_set(false, RETROK_F1);

   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      if (!settings->menu.throttle_framerate && !settings->fastforward_ratio)
         return RUNLOOP_STATE_MENU_ITERATE;

      return RUNLOOP_STATE_END;
   }
#endif

   if (settings->pause_nonactive)
      focused                = video_driver_is_focused();

   if (runloop_cmd_triggered(trigger_input, RARCH_SCREENSHOT))
      command_event(CMD_EVENT_TAKE_SCREENSHOT, NULL);

   if (runloop_cmd_triggered(trigger_input, RARCH_MUTE))
      command_event(CMD_EVENT_AUDIO_MUTE_TOGGLE, NULL);

   if (runloop_cmd_triggered(trigger_input, RARCH_OSK))
   {
      if (input_keyboard_ctl(
               RARCH_INPUT_KEYBOARD_CTL_IS_LINEFEED_ENABLED, NULL))
         input_keyboard_ctl(
               RARCH_INPUT_KEYBOARD_CTL_UNSET_LINEFEED_ENABLED, NULL);
      else
         input_keyboard_ctl(
               RARCH_INPUT_KEYBOARD_CTL_SET_LINEFEED_ENABLED, NULL);
   }

   if (runloop_cmd_press(current_input, RARCH_VOLUME_UP))
      command_event(CMD_EVENT_VOLUME_UP, NULL);
   else if (runloop_cmd_press(current_input, RARCH_VOLUME_DOWN))
      command_event(CMD_EVENT_VOLUME_DOWN, NULL);

#ifdef HAVE_NETWORKING
   tmp = runloop_cmd_triggered(trigger_input, RARCH_NETPLAY_FLIP);
   netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, &tmp);
   tmp = runloop_cmd_triggered(trigger_input, RARCH_FULLSCREEN_TOGGLE_KEY);
   netplay_driver_ctl(RARCH_NETPLAY_CTL_FULLSCREEN_TOGGLE, &tmp);
#endif

   /* Check if libretro pause key was pressed. If so, pause or
    * unpause the libretro core. */

   /* FRAMEADVANCE will set us into pause mode. */
   pause_pressed |= !runloop_paused && runloop_cmd_triggered(trigger_input, RARCH_FRAMEADVANCE);

   if (focused && pause_pressed)
      command_event(CMD_EVENT_PAUSE_TOGGLE, NULL);
   else if (focused && !old_focus)
      command_event(CMD_EVENT_UNPAUSE, NULL);
   else if (!focused && old_focus)
      command_event(CMD_EVENT_PAUSE, NULL);

   old_focus = focused;

   if (!focused)
      return RUNLOOP_STATE_SLEEP;

   if (runloop_paused)
   {
      /* check pause state */

      bool check_is_oneshot = runloop_cmd_triggered(trigger_input,
            RARCH_FRAMEADVANCE)
         || runloop_cmd_press(current_input, RARCH_REWIND);
      if (runloop_cmd_triggered(trigger_input, RARCH_FULLSCREEN_TOGGLE_KEY))
      {
         command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL);
         if (!runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL))
            video_driver_cached_frame();
      }

      if (!check_is_oneshot)
         return RUNLOOP_STATE_SLEEP;
   }

   /* 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 (runloop_cmd_triggered(trigger_input, RARCH_FAST_FORWARD_KEY))
   {
      if (input_driver_is_nonblock_state())
         input_driver_unset_nonblock_state();
      else
         input_driver_set_nonblock_state();
      driver_ctl(RARCH_DRIVER_CTL_SET_NONBLOCK_STATE, NULL);
   }
   else if ((runloop_cmd_pressed(old_input, RARCH_FAST_FORWARD_HOLD_KEY) 
         != runloop_cmd_press(current_input, RARCH_FAST_FORWARD_HOLD_KEY)))
   {
      if (runloop_cmd_press(current_input, RARCH_FAST_FORWARD_HOLD_KEY))
         input_driver_set_nonblock_state();
      else
         input_driver_unset_nonblock_state();
      driver_ctl(RARCH_DRIVER_CTL_SET_NONBLOCK_STATE, NULL);
   }

   /* Checks if the state increase/decrease keys have been pressed 
    * for this frame. */
   if (runloop_cmd_triggered(trigger_input, RARCH_STATE_SLOT_PLUS))
   {
      char msg[128];

      msg[0] = '\0';

      settings->state_slot++;

      snprintf(msg, sizeof(msg), "%s: %d",
            msg_hash_to_str(MSG_STATE_SLOT),
            settings->state_slot);

      runloop_msg_queue_push(msg, 2, 180, true);

      RARCH_LOG("%s\n", msg);
   }
   else if (runloop_cmd_triggered(trigger_input, RARCH_STATE_SLOT_MINUS))
   {
      char msg[128];

      msg[0] = '\0';

      if (settings->state_slot > 0)
         settings->state_slot--;

      snprintf(msg, sizeof(msg), "%s: %d",
            msg_hash_to_str(MSG_STATE_SLOT),
            settings->state_slot);

      runloop_msg_queue_push(msg, 2, 180, true);

      RARCH_LOG("%s\n", msg);
   }

   if (runloop_cmd_triggered(trigger_input, RARCH_SAVE_STATE_KEY))
      command_event(CMD_EVENT_SAVE_STATE, NULL);
   else if (runloop_cmd_triggered(trigger_input, RARCH_LOAD_STATE_KEY))
      command_event(CMD_EVENT_LOAD_STATE, NULL);

#ifdef HAVE_CHEEVOS
   if (!settings->cheevos.hardcore_mode_enable)
#endif
      state_manager_check_rewind(runloop_cmd_press(current_input, RARCH_REWIND));

   runloop_slowmotion = runloop_cmd_press(current_input, RARCH_SLOWMOTION);

   if (runloop_slowmotion)
   {
      /* Checks if slowmotion toggle/hold was being pressed and/or held. */
      if (settings->video.black_frame_insertion)
      {
         if (!runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL))
            video_driver_cached_frame();
      }

      if (state_manager_frame_is_reversed())
         runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION_REWIND), 2, 30, true);
      else
         runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION), 2, 30, true);
   }

   if (runloop_cmd_triggered(trigger_input, RARCH_MOVIE_RECORD_TOGGLE))
      bsv_movie_check();

   if (runloop_cmd_triggered(trigger_input, RARCH_SHADER_NEXT) ||
      runloop_cmd_triggered(trigger_input, RARCH_SHADER_PREV))
      dir_check_shader(
            runloop_cmd_triggered(trigger_input, RARCH_SHADER_NEXT),
            runloop_cmd_triggered(trigger_input, RARCH_SHADER_PREV));

   if (runloop_cmd_triggered(trigger_input, RARCH_DISK_EJECT_TOGGLE))
      command_event(CMD_EVENT_DISK_EJECT_TOGGLE, NULL);
   else if (runloop_cmd_triggered(trigger_input, RARCH_DISK_NEXT))
      command_event(CMD_EVENT_DISK_NEXT, NULL);
   else if (runloop_cmd_triggered(trigger_input, RARCH_DISK_PREV))
      command_event(CMD_EVENT_DISK_PREV, NULL);

   if (runloop_cmd_triggered(trigger_input, RARCH_RESET))
      command_event(CMD_EVENT_RESET, NULL);

   cheat_manager_state_checks(
         runloop_cmd_triggered(trigger_input, RARCH_CHEAT_INDEX_PLUS),
         runloop_cmd_triggered(trigger_input, RARCH_CHEAT_INDEX_MINUS),
         runloop_cmd_triggered(trigger_input, RARCH_CHEAT_TOGGLE));

   return RUNLOOP_STATE_ITERATE;
}