Exemple #1
0
/**
 * check_slowmotion:
 * @slowmotion_pressed   : was slow motion key pressed or held?
 *
 * Checks if slowmotion toggle/hold was being pressed and/or held.
 **/
static void check_slowmotion(settings_t *settings, global_t *global,
      runloop_t *runloop, bool slowmotion_pressed)
{
   runloop->is_slowmotion   = slowmotion_pressed;

   if (!runloop->is_slowmotion)
      return;

   if (settings->video.black_frame_insertion)
      video_driver_cached_frame();

   if (global->rewind.frame_is_reverse)
      rarch_main_msg_queue_push_new(MSG_SLOW_MOTION_REWIND, 0, 30, true);
   else
      rarch_main_msg_queue_push_new(MSG_SLOW_MOTION, 0, 30, true);
}
Exemple #2
0
static void event_init_movie(void)
{
   settings_t *settings = config_get_ptr();
   global_t   *global   = global_get_ptr();

   if (global->bsv.movie_start_playback)
   {
      if (!(global->bsv.movie = bsv_movie_init(global->bsv.movie_start_path,
                  RARCH_MOVIE_PLAYBACK)))
      {
         RARCH_ERR("%s: \"%s\".\n",
               msg_hash_to_str(MSG_FAILED_TO_LOAD_MOVIE_FILE),
               global->bsv.movie_start_path);
         rarch_fail(1, "event_init_movie()");
      }

      global->bsv.movie_playback = true;
      rarch_main_msg_queue_push_new(MSG_STARTING_MOVIE_PLAYBACK, 2, 180, false);
      RARCH_LOG("%s.\n", msg_hash_to_str(MSG_STARTING_MOVIE_PLAYBACK));
      settings->rewind_granularity = 1;
   }
   else if (global->bsv.movie_start_recording)
   {
      char msg[PATH_MAX_LENGTH] = {0};
      snprintf(msg, sizeof(msg),
            "%s \"%s\".",
            msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
            global->bsv.movie_start_path);

      if (!(global->bsv.movie = bsv_movie_init(global->bsv.movie_start_path,
                  RARCH_MOVIE_RECORD)))
      {
         rarch_main_msg_queue_push_new(MSG_FAILED_TO_START_MOVIE_RECORD, 1, 180, true);
         RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD));
         return;
      }

      rarch_main_msg_queue_push(msg, 1, 180, true);
      RARCH_LOG("%s \"%s\".\n",
            msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
            global->bsv.movie_start_path);
      settings->rewind_granularity = 1;
   }
}
Exemple #3
0
/**
 * check_movie_record:
 *
 * Checks if movie is being recorded.
 *
 * Returns: true (1) if movie is being recorded, otherwise false (0).
 **/
static bool check_movie_record(global_t *global)
{
   if (!global->bsv.movie)
      return false;

   rarch_main_msg_queue_push_new(
         MSG_MOVIE_RECORD_STOPPED, 2, 180, true);
   RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED));

   event_command(EVENT_CMD_BSV_MOVIE_DEINIT);

   return true;
}
Exemple #4
0
/**
 * check_movie_playback:
 *
 * Checks if movie is being played.
 *
 * Returns: true (1) if movie is being played, otherwise false (0).
 **/
static bool check_movie_playback(global_t *global)
{
   if (!global->bsv.movie_end)
      return false;

   rarch_main_msg_queue_push_new(
         MSG_MOVIE_PLAYBACK_ENDED, 1, 180, false);
   RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED));

   event_command(EVENT_CMD_BSV_MOVIE_DEINIT);

   global->bsv.movie_end      = false;
   global->bsv.movie_playback = false;

   return true;
}
Exemple #5
0
static bool check_movie_init(void)
{
   char path[PATH_MAX_LENGTH]   = {0};
   char msg[PATH_MAX_LENGTH]    = {0};
   bool ret                     = true;
   settings_t *settings         = config_get_ptr();
   global_t *global             = global_get_ptr();
   
   if (global->bsv.movie)
      return false;

   settings->rewind_granularity = 1;

   if (settings->state_slot > 0)
      snprintf(path, sizeof(path), "%s%d",
            global->bsv.movie_path, settings->state_slot);
   else
      strlcpy(path, global->bsv.movie_path, sizeof(path));
   strlcat(path, ".bsv", sizeof(path));

   snprintf(msg, sizeof(msg), "%s \"%s\".",
         msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
         path);

   global->bsv.movie = bsv_movie_init(path, RARCH_MOVIE_RECORD);

   if (!global->bsv.movie)
      ret = false;


   if (global->bsv.movie)
   {
      rarch_main_msg_queue_push(msg, 1, 180, true);
      RARCH_LOG("%s \"%s\".\n",
         msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
            path);
   }
   else
   {
      rarch_main_msg_queue_push_new(
            MSG_FAILED_TO_START_MOVIE_RECORD,
            1, 180, true);
      RARCH_ERR(msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD));
   }

   return ret;
}
Exemple #6
0
bool init_netplay(void)
{
   struct retro_callbacks cbs = {0};
   driver_t *driver     = driver_get_ptr();
   settings_t *settings = config_get_ptr();
   global_t *global     = global_get_ptr();

   if (!global->netplay.enable)
      return false;

   if (global->bsv.movie_start_playback)
   {
      RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED));
      return false;
   }

   retro_set_default_callbacks(&cbs);

   if (*global->netplay.server)
   {
      RARCH_LOG("Connecting to netplay host...\n");
      global->netplay.is_client = true;
   }
   else
      RARCH_LOG("Waiting for client...\n");

   driver->netplay_data = (netplay_t*)netplay_new(
         global->netplay.is_client ? global->netplay.server : NULL,
         global->netplay.port ? global->netplay.port : RARCH_DEFAULT_PORT,
         global->netplay.sync_frames, &cbs, global->netplay.is_spectate,
         settings->username);

   if (driver->netplay_data)
      return true;

   global->netplay.is_client = false;
   RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED));

   rarch_main_msg_queue_push_new(
         MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED,
         0, 180, false);
   return false;
}
Exemple #7
0
/**
 * driver_update_system_av_info:
 * @info               : pointer to new A/V info
 *
 * Update the system Audio/Video information. 
 * Will reinitialize audio/video drivers.
 * Used by RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool driver_update_system_av_info(const struct retro_system_av_info *info)
{
   struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
   driver_t *driver = driver_get_ptr();

   memcpy(av_info, info, sizeof(*av_info));
   event_command(EVENT_CMD_REINIT);

   /* Cannot continue recording with different parameters.
    * Take the easiest route out and just restart the recording. */
   if (driver->recording_data)
   {
      rarch_main_msg_queue_push_new(
            MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, 2, 180, false);
      event_command(EVENT_CMD_RECORD_DEINIT);
      event_command(EVENT_CMD_RECORD_INIT);
   }

   return true;
}
Exemple #8
0
void rarch_main_data_db_iterate(bool is_thread)
{
   database_info_handle_t      *db   = (db_ptr) ? db_ptr->handle : NULL;
   database_state_handle_t *db_state = (db_ptr) ? &db_ptr->state : NULL;
   const char *name = db ? db->list->elems[db->list_ptr].data    : NULL;

   if (!db)
      goto do_poll;

   switch (db->status)
   {
      case DATABASE_STATUS_ITERATE_BEGIN:
         if (db_state && !db_state->list)
            db_state->list = dir_list_new_special(NULL, DIR_LIST_DATABASES, NULL);
         db->status = DATABASE_STATUS_ITERATE_START;
         break;
      case DATABASE_STATUS_ITERATE_START:
         rarch_main_data_db_cleanup_state(db_state);
         db_state->list_index  = 0;
         db_state->entry_index = 0;
         database_info_iterate_start(db, name);
         break;
      case DATABASE_STATUS_ITERATE:
         if (database_info_iterate(&db_ptr->state, db) == 0)
         {
            db->status = DATABASE_STATUS_ITERATE_NEXT;
            db->type   = DATABASE_TYPE_ITERATE;
         }
         break;
      case DATABASE_STATUS_ITERATE_NEXT:
         if (database_info_iterate_next(db) == 0)
         {
            db->status = DATABASE_STATUS_ITERATE_START;
            db->type   = DATABASE_TYPE_ITERATE;
         }
         else
         {
            rarch_main_msg_queue_push_new(MSG_SCANNING_OF_DIRECTORY_FINISHED, 0, 180, true);
            pending_scan_finished = true;
            db->status = DATABASE_STATUS_FREE;
         }
         break;
      case DATABASE_STATUS_FREE:
         if (db_state->list)
            dir_list_free(db_state->list);
         db_state->list = NULL;
         rarch_main_data_db_cleanup_state(db_state);
         database_info_free(db);
         if (db_ptr->handle)
            free(db_ptr->handle);
         db_ptr->handle = NULL;
         break;
      default:
      case DATABASE_STATUS_NONE:
         goto do_poll;
   }

   return;

do_poll:
   if (database_info_poll(db_ptr) != -1)
   {
      if (db_ptr->handle)
         db_ptr->handle->status = DATABASE_STATUS_ITERATE_BEGIN;
   }
}
Exemple #9
0
bool rarch_main_ctl(enum rarch_main_ctl_state state, void *data)
{
   driver_t     *driver  = driver_get_ptr();
   settings_t *settings  = config_get_ptr();
   global_t     *global  = global_get_ptr();

   switch (state)
   {
      case RARCH_MAIN_CTL_CHECK_STATE:
         {
            event_cmd_state_t *cmd    = (event_cmd_state_t*)data;

            if (!cmd || main_is_idle)
               return false;

            if (cmd->screenshot_pressed)
               event_command(EVENT_CMD_TAKE_SCREENSHOT);

            if (cmd->mute_pressed)
               event_command(EVENT_CMD_AUDIO_MUTE_TOGGLE);

            if (cmd->osk_pressed)
               driver->keyboard_linefeed_enable = !driver->keyboard_linefeed_enable;

            if (cmd->volume_up_pressed)
               event_command(EVENT_CMD_VOLUME_UP);
            else if (cmd->volume_down_pressed)
               event_command(EVENT_CMD_VOLUME_DOWN);

#ifdef HAVE_NETPLAY
            if (driver->netplay_data)
            {
               if (cmd->netplay_flip_pressed)
                  event_command(EVENT_CMD_NETPLAY_FLIP_PLAYERS);

               if (cmd->fullscreen_toggle)
                  event_command(EVENT_CMD_FULLSCREEN_TOGGLE);
               break;
            }
#endif

            check_pause(driver, settings,
                  cmd->pause_pressed, cmd->frameadvance_pressed);

            if (!rarch_main_ctl(RARCH_MAIN_CTL_CHECK_PAUSE_STATE, cmd))
               return false;

            check_fast_forward_button(driver,
                  cmd->fastforward_pressed,
                  cmd->hold_pressed, cmd->old_hold_pressed);
            check_stateslots(settings, cmd->state_slot_increase,
                  cmd->state_slot_decrease);

            if (cmd->save_state_pressed)
               event_command(EVENT_CMD_SAVE_STATE);
            else if (cmd->load_state_pressed)
               event_command(EVENT_CMD_LOAD_STATE);

            check_rewind(settings, global, cmd->rewind_pressed);

            rarch_main_ctl(RARCH_MAIN_CTL_CHECK_SLOWMOTION, &cmd->slowmotion_pressed);

            if (cmd->movie_record)
               rarch_main_ctl(RARCH_MAIN_CTL_CHECK_MOVIE, NULL);

            check_shader_dir(global, cmd->shader_next_pressed,
                  cmd->shader_prev_pressed);

            if (cmd->disk_eject_pressed)
               event_command(EVENT_CMD_DISK_EJECT_TOGGLE);
            else if (cmd->disk_next_pressed)
               event_command(EVENT_CMD_DISK_NEXT);
            else if (cmd->disk_prev_pressed)
               event_command(EVENT_CMD_DISK_PREV);

            if (cmd->reset_pressed)
               event_command(EVENT_CMD_RESET);

            if (global->cheat)
            {
               if (cmd->cheat_index_plus_pressed)
                  cheat_manager_index_next(global->cheat);
               else if (cmd->cheat_index_minus_pressed)
                  cheat_manager_index_prev(global->cheat);
               else if (cmd->cheat_toggle_pressed)
                  cheat_manager_toggle(global->cheat);
            }
         }
         break;
      case RARCH_MAIN_CTL_CHECK_PAUSE_STATE:
         {
            bool check_is_oneshot;
            event_cmd_state_t *cmd    = (event_cmd_state_t*)data;

            if (!cmd)
               return false;

            check_is_oneshot     = cmd->frameadvance_pressed || cmd->rewind_pressed;

            if (!main_is_paused)
               return true;

            if (cmd->fullscreen_toggle)
            {
               event_command(EVENT_CMD_FULLSCREEN_TOGGLE);
               video_driver_cached_frame();
            }

            if (!check_is_oneshot)
               return false;
         }
         break;
      case RARCH_MAIN_CTL_CHECK_SLOWMOTION:
         {
            bool *ptr            = (bool*)data;

            if (!ptr)
               return false;

            main_is_slowmotion   = *ptr;

            if (!main_is_slowmotion)
               return false;

            if (settings->video.black_frame_insertion)
               video_driver_cached_frame();

            if (state_manager_frame_is_reversed())
               rarch_main_msg_queue_push_new(MSG_SLOW_MOTION_REWIND, 0, 30, true);
            else
               rarch_main_msg_queue_push_new(MSG_SLOW_MOTION, 0, 30, true);
         }
         break;
      case RARCH_MAIN_CTL_CHECK_MOVIE:
         if (global->bsv.movie_playback)
            return rarch_main_ctl(RARCH_MAIN_CTL_CHECK_MOVIE_PLAYBACK, NULL);
         if (!global->bsv.movie)
            return rarch_main_ctl(RARCH_MAIN_CTL_CHECK_MOVIE_INIT, NULL);
         return rarch_main_ctl(RARCH_MAIN_CTL_CHECK_MOVIE_RECORD, NULL);
      case RARCH_MAIN_CTL_CHECK_MOVIE_RECORD:
         if (!global->bsv.movie)
            return false;

         rarch_main_msg_queue_push_new(
               MSG_MOVIE_RECORD_STOPPED, 2, 180, true);
         RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED));

         event_command(EVENT_CMD_BSV_MOVIE_DEINIT);
         break;
      case RARCH_MAIN_CTL_CHECK_MOVIE_INIT:
         if (global->bsv.movie)
            return false;
         {
            char path[PATH_MAX_LENGTH], msg[PATH_MAX_LENGTH];

            settings->rewind_granularity = 1;

            if (settings->state_slot > 0)
               snprintf(path, sizeof(path), "%s%d",
                     global->bsv.movie_path, settings->state_slot);
            else
               strlcpy(path, global->bsv.movie_path, sizeof(path));

            strlcat(path, ".bsv", sizeof(path));

            snprintf(msg, sizeof(msg), "%s \"%s\".",
                  msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
                  path);

            global->bsv.movie = bsv_movie_init(path, RARCH_MOVIE_RECORD);

            if (!global->bsv.movie)
               return false;
            else if (global->bsv.movie)
            {
               rarch_main_msg_queue_push(msg, 1, 180, true);
               RARCH_LOG("%s \"%s\".\n",
                     msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO),
                     path);
            }
            else
            {
               rarch_main_msg_queue_push_new(
                     MSG_FAILED_TO_START_MOVIE_RECORD,
                     1, 180, true);
               RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD));
            }
         }
         break;
      case RARCH_MAIN_CTL_CHECK_MOVIE_PLAYBACK:
         if (!global->bsv.movie_end)
            return false;

         rarch_main_msg_queue_push_new(
               MSG_MOVIE_PLAYBACK_ENDED, 1, 180, false);
         RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED));

         event_command(EVENT_CMD_BSV_MOVIE_DEINIT);

         global->bsv.movie_end      = false;
         global->bsv.movie_playback = false;
         break;
      case RARCH_MAIN_CTL_STATE_FREE:
         main_is_idle               = false;
         main_is_paused             = false;
         main_is_slowmotion         = false;
         frame_limit_last_time      = 0.0;
         main_max_frames            = 0;
         break;
      case RARCH_MAIN_CTL_GLOBAL_FREE:
         event_command(EVENT_CMD_TEMPORARY_CONTENT_DEINIT);
         event_command(EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT);
         event_command(EVENT_CMD_RECORD_DEINIT);
         event_command(EVENT_CMD_LOG_FILE_DEINIT);

         memset(&g_extern, 0, sizeof(g_extern));
         break;
      case RARCH_MAIN_CTL_CLEAR_STATE:
         driver_clear_state();
         rarch_main_ctl(RARCH_MAIN_CTL_STATE_FREE,  NULL);
         rarch_main_ctl(RARCH_MAIN_CTL_GLOBAL_FREE, NULL);
         break;
      case RARCH_MAIN_CTL_SET_MAX_FRAMES:
         {
            unsigned *ptr = (unsigned*)data;
            if (!ptr)
               return false;
            main_max_frames = *ptr;
         }
         break;
      case RARCH_MAIN_CTL_SET_FRAME_LIMIT_LAST_TIME:
         {
            struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
            float fastforward_ratio              = settings->fastforward_ratio;

            if (fastforward_ratio == 0.0f)
               fastforward_ratio = 1.0f;

            frame_limit_last_time    = retro_get_time_usec();
            frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f / (av_info->timing.fps * fastforward_ratio));
         }
         break;
      case RARCH_MAIN_CTL_IS_IDLE:
         {
            bool *ptr = (bool*)data;
            if (!ptr)
               return false;
            *ptr = main_is_idle;
         }
         break;
      case RARCH_MAIN_CTL_SET_IDLE:
         {
            bool *ptr = (bool*)data;
            if (!ptr)
               return false;
            main_is_idle = *ptr;
         }
         break;
      case RARCH_MAIN_CTL_IS_SLOWMOTION:
         {
            bool *ptr = (bool*)data;
            if (!ptr)
               return false;
            *ptr = main_is_slowmotion;
         }
         break;
      case RARCH_MAIN_CTL_SET_SLOWMOTION:
         {
            bool *ptr = (bool*)data;
            if (!ptr)
               return false;
            main_is_slowmotion = *ptr;
         }
         break;
      case RARCH_MAIN_CTL_SET_PAUSED:
         {
            bool *ptr = (bool*)data;
            if (!ptr)
               return false;
            main_is_paused = *ptr;
         }
         break;
      case RARCH_MAIN_CTL_IS_PAUSED:
         {
            bool *ptr = (bool*)data;
            if (!ptr)
               return false;
            *ptr = main_is_paused;
         }
         break;
      default:
         return false;
   }

   return true;
}
Exemple #10
0
/**
 * check_rewind:
 * @pressed              : was rewind key pressed or held?
 *
 * Checks if rewind toggle/hold was being pressed and/or held.
 **/
static void check_rewind(settings_t *settings,
      global_t *global, bool pressed)
{
   static bool first = true;

   if (state_manager_frame_is_reversed())
   {
      audio_driver_frame_is_reverse();
      state_manager_set_frame_is_reversed(false);
   }

   if (first)
   {
      first = false;
      return;
   }

   if (!global->rewind.state)
      return;

   if (pressed)
   {
      const void *buf    = NULL;

      if (state_manager_pop(global->rewind.state, &buf))
      {
         state_manager_set_frame_is_reversed(true);
         audio_driver_setup_rewind();

         rarch_main_msg_queue_push_new(MSG_REWINDING, 0,
               main_is_paused ? 1 : 30, true);
         core.retro_unserialize(buf, global->rewind.size);

         if (global->bsv.movie)
            bsv_movie_frame_rewind(global->bsv.movie);
      }
      else
         rarch_main_msg_queue_push_new(MSG_REWIND_REACHED_END,
               0, 30, true);
   }
   else
   {
      static unsigned cnt      = 0;

      cnt = (cnt + 1) % (settings->rewind_granularity ?
            settings->rewind_granularity : 1); /* Avoid possible SIGFPE. */

      if ((cnt == 0) || global->bsv.movie)
      {
         static struct retro_perf_counter rewind_serialize = {0};
         void *state = NULL;

         state_manager_push_where(global->rewind.state, &state);

         rarch_perf_init(&rewind_serialize, "rewind_serialize");
         retro_perf_start(&rewind_serialize);
         core.retro_serialize(state, global->rewind.size);
         retro_perf_stop(&rewind_serialize);

         state_manager_push_do(global->rewind.state);
      }
   }

   retro_set_rewind_callbacks();
}
Exemple #11
0
void recording_dump_frame(const void *data, unsigned width,
      unsigned height, size_t pitch)
{
   struct ffemu_video_data ffemu_data = {0};
   driver_t *driver = driver_get_ptr();
   global_t *global = global_get_ptr();

   if (!driver->recording_data)
      return;

   ffemu_data.pitch   = pitch;
   ffemu_data.width   = width;
   ffemu_data.height  = height;
   ffemu_data.data    = data;

   if (global->record.gpu_buffer)
   {
      struct video_viewport vp = {0};

      video_driver_viewport_info(&vp);

      if (!vp.width || !vp.height)
      {
         RARCH_WARN("%s \n",
               msg_hash_to_str(MSG_VIEWPORT_SIZE_CALCULATION_FAILED));
         event_command(EVENT_CMD_GPU_RECORD_DEINIT);

         recording_dump_frame(data, width, height, pitch);
         return;
      }

      /* User has resized. We kinda have a problem now. */
      if (vp.width != global->record.gpu_width ||
            vp.height != global->record.gpu_height)
      {
         RARCH_WARN("%s\n", msg_hash_to_str(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE));

         rarch_main_msg_queue_push_new(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, 1, 180, true);
         event_command(EVENT_CMD_RECORD_DEINIT);
         return;
      }

      /* Big bottleneck.
       * Since we might need to do read-backs asynchronously,
       * it might take 3-4 times before this returns true. */
      if (!video_driver_read_viewport(global->record.gpu_buffer))
            return;

      ffemu_data.pitch  = global->record.gpu_width * 3;
      ffemu_data.width  = global->record.gpu_width;
      ffemu_data.height = global->record.gpu_height;
      ffemu_data.data   = global->record.gpu_buffer +
         (ffemu_data.height - 1) * ffemu_data.pitch;

      ffemu_data.pitch  = -ffemu_data.pitch;
   }

   if (!global->record.gpu_buffer)
      ffemu_data.is_dupe = !data;

   if (driver->recording && driver->recording->push_video)
      driver->recording->push_video(driver->recording_data, &ffemu_data);
}
Exemple #12
0
/**
 * check_rewind:
 * @pressed              : was rewind key pressed or held?
 *
 * Checks if rewind toggle/hold was being pressed and/or held.
 **/
static void check_rewind(settings_t *settings,
      global_t *global, runloop_t *runloop, bool pressed)
{
   static bool first = true;

   if (global->rewind.frame_is_reverse)
   {
      audio_driver_frame_is_reverse();
      global->rewind.frame_is_reverse = false;
   }

   if (first)
   {
      first = false;
      return;
   }

   if (!global->rewind.state)
      return;

   if (pressed)
   {
      const void *buf    = NULL;

      if (state_manager_pop(global->rewind.state, &buf))
      {
         global->rewind.frame_is_reverse = true;
         audio_driver_setup_rewind();

         rarch_main_msg_queue_push_new(MSG_REWINDING, 0,
               runloop->is_paused ? 1 : 30, true);
         pretro_unserialize(buf, global->rewind.size);

         if (global->bsv.movie)
            bsv_movie_frame_rewind(global->bsv.movie);
      }
      else
         rarch_main_msg_queue_push_new(MSG_REWIND_REACHED_END,
               0, 30, true);
   }
   else
   {
      static unsigned cnt      = 0;

      cnt = (cnt + 1) % (settings->rewind_granularity ?
            settings->rewind_granularity : 1); /* Avoid possible SIGFPE. */

      if ((cnt == 0) || global->bsv.movie)
      {
         void *state = NULL;
         state_manager_push_where(global->rewind.state, &state);

         RARCH_PERFORMANCE_INIT(rewind_serialize);
         RARCH_PERFORMANCE_START(rewind_serialize);
         pretro_serialize(state, global->rewind.size);
         RARCH_PERFORMANCE_STOP(rewind_serialize);

         state_manager_push_do(global->rewind.state);
      }
   }

   retro_set_rewind_callbacks();
}
Exemple #13
0
/**
 * event_save_core_config:
 *
 * Saves a new (core) configuration to a file. Filename is based
 * on heuristics to avoid typing.
 *
 * Returns: true (1) on success, otherwise false (0).
 **/
static bool event_save_core_config(void)
{
   char config_dir[PATH_MAX_LENGTH]  = {0};
   char config_name[PATH_MAX_LENGTH] = {0};
   char config_path[PATH_MAX_LENGTH] = {0};
   char msg[PATH_MAX_LENGTH]         = {0};
   bool ret                          = false;
   bool found_path                   = false;
   bool overrides_active             = false;
   settings_t *settings              = config_get_ptr();
   global_t   *global                = global_get_ptr();

   *config_dir = '\0';

   if (*settings->menu_config_directory)
      strlcpy(config_dir, settings->menu_config_directory,
            sizeof(config_dir));
   else if (*global->path.config) /* Fallback */
      fill_pathname_basedir(config_dir, global->path.config,
            sizeof(config_dir));
   else
   {
      rarch_main_msg_queue_push_new(MSG_CONFIG_DIRECTORY_NOT_SET, 1, 180, true);
      RARCH_ERR("%s\n", msg_hash_to_str(MSG_CONFIG_DIRECTORY_NOT_SET));
      return false;
   }

   /* Infer file name based on libretro core. */
   if (*settings->libretro && path_file_exists(settings->libretro))
   {
      unsigned i;

      /* In case of collision, find an alternative name. */
      for (i = 0; i < 16; i++)
      {
         char tmp[64] = {0};

         fill_pathname_base(config_name, settings->libretro,
               sizeof(config_name));
         path_remove_extension(config_name);
         fill_pathname_join(config_path, config_dir, config_name,
               sizeof(config_path));

         *tmp = '\0';

         if (i)
            snprintf(tmp, sizeof(tmp), "-%u.cfg", i);
         else
            strlcpy(tmp, ".cfg", sizeof(tmp));

         strlcat(config_path, tmp, sizeof(config_path));

         if (!path_file_exists(config_path))
         {
            found_path = true;
            break;
         }
      }
   }

   /* Fallback to system time... */
   if (!found_path)
   {
      RARCH_WARN("Cannot infer new config path. Use current time.\n");
      fill_dated_filename(config_name, "cfg", sizeof(config_name));
      fill_pathname_join(config_path, config_dir, config_name,
            sizeof(config_path));
   }

   /* Overrides block config file saving, make it appear as overrides weren't enabled for a manual save */
   if (global->overrides_active)
   {
      global->overrides_active = false;
	  overrides_active = true;
   }

   if ((ret = config_save_file(config_path)))
   {
      strlcpy(global->path.config, config_path,
            sizeof(global->path.config));
      snprintf(msg, sizeof(msg), "Saved new config to \"%s\".",
            config_path);
      RARCH_LOG("%s\n", msg);
   }
   else
   {
      snprintf(msg, sizeof(msg), "Failed saving config to \"%s\".",
            config_path);
      RARCH_ERR("%s\n", msg);
   }

   rarch_main_msg_queue_push(msg, 1, 180, true);
   global->overrides_active = overrides_active;
   return ret;
}
Exemple #14
0
/**
 * event_command:
 * @cmd                  : Event command index.
 *
 * Performs program event command with index @cmd.
 *
 * Returns: true (1) on success, otherwise false (0).
 **/
bool event_command(enum event_command cmd)
{
   unsigned i           = 0;
   bool boolean         = false;
   driver_t  *driver    = driver_get_ptr();
   global_t  *global    = global_get_ptr();
   settings_t *settings = config_get_ptr();
   rarch_system_info_t *system = rarch_system_info_get_ptr();

   (void)i;

   switch (cmd)
   {
      case EVENT_CMD_LOAD_CONTENT_PERSIST:
#ifdef HAVE_DYNAMIC
         event_command(EVENT_CMD_LOAD_CORE);
#endif
         rarch_ctl(RARCH_ACTION_STATE_LOAD_CONTENT, NULL);
         break;
#ifdef HAVE_FFMPEG
      case EVENT_CMD_LOAD_CONTENT_FFMPEG:
         rarch_ctl(RARCH_ACTION_STATE_LOAD_CONTENT_FFMPEG, NULL);
         break;
#endif
      case EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER:
         rarch_ctl(RARCH_ACTION_STATE_LOAD_CONTENT_IMAGEVIEWER, NULL);
         break;
      case EVENT_CMD_LOAD_CONTENT:
#ifdef HAVE_DYNAMIC
         event_command(EVENT_CMD_LOAD_CONTENT_PERSIST);
#else
         rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH,
               (void*)settings->libretro);
         rarch_environment_cb(RETRO_ENVIRONMENT_EXEC,
               (void*)global->path.fullpath);
         event_command(EVENT_CMD_QUIT);
#endif
         break;
      case EVENT_CMD_LOAD_CORE_DEINIT:
#ifdef HAVE_DYNAMIC
         libretro_free_system_info(&global->menu.info);
#endif
         break;
      case EVENT_CMD_LOAD_CORE_PERSIST:
         event_command(EVENT_CMD_LOAD_CORE_DEINIT);
         {
#ifdef HAVE_MENU
            menu_handle_t *menu = menu_driver_get_ptr();
            if (menu)
               event_update_system_info(&global->menu.info,
                     &menu->load_no_content);
#endif
         }
         break;
      case EVENT_CMD_LOAD_CORE:
         event_command(EVENT_CMD_LOAD_CORE_PERSIST);
#ifndef HAVE_DYNAMIC
         event_command(EVENT_CMD_QUIT);
#endif
         break;
      case EVENT_CMD_LOAD_STATE:
         /* Immutable - disallow savestate load when
          * we absolutely cannot change game state. */
         if (global->bsv.movie)
            return false;

#ifdef HAVE_NETPLAY
         if (driver->netplay_data)
            return false;
#endif
         event_main_state(cmd);
         break;
      case EVENT_CMD_RESIZE_WINDOWED_SCALE:
         if (global->pending.windowed_scale == 0)
            return false;

         settings->video.scale = global->pending.windowed_scale;

         if (!settings->video.fullscreen)
            event_command(EVENT_CMD_REINIT);

         global->pending.windowed_scale = 0;
         break;
      case EVENT_CMD_MENU_TOGGLE:
#ifdef HAVE_MENU
         if (menu_driver_alive())
            rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL);
         else
            rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING, NULL);
#endif
         break;
      case EVENT_CMD_CONTROLLERS_INIT:
         event_init_controllers();
         break;
      case EVENT_CMD_RESET:
         RARCH_LOG("%s.\n", msg_hash_to_str(MSG_RESET));
         rarch_main_msg_queue_push_new(MSG_RESET, 1, 120, true);
         core.retro_reset();

         /* bSNES since v073r01 resets controllers to JOYPAD
          * after a reset, so just enforce it here. */
         event_command(EVENT_CMD_CONTROLLERS_INIT);
         break;
      case EVENT_CMD_SAVE_STATE:
         if (settings->savestate_auto_index)
            settings->state_slot++;

         event_main_state(cmd);
         break;
      case EVENT_CMD_SAVE_STATE_DECREMENT:
         /* Slot -1 is (auto) slot. */
         if (settings->state_slot >= 0)
            settings->state_slot--;
         break;
      case EVENT_CMD_SAVE_STATE_INCREMENT:
         settings->state_slot++;
         break;
      case EVENT_CMD_TAKE_SCREENSHOT:
         if (!take_screenshot())
            return false;
         break;
      case EVENT_CMD_PREPARE_DUMMY:
         {
#ifdef HAVE_MENU
            menu_handle_t *menu = menu_driver_get_ptr();
            if (menu)
               menu->load_no_content = false;
#endif
            rarch_main_data_deinit();

            *global->path.fullpath = '\0';

            rarch_ctl(RARCH_ACTION_STATE_LOAD_CONTENT, NULL);
         }
         break;
      case EVENT_CMD_UNLOAD_CORE:
         event_command(EVENT_CMD_PREPARE_DUMMY);
         event_command(EVENT_CMD_LOAD_CORE_DEINIT);
         break;
      case EVENT_CMD_QUIT:
         rarch_ctl(RARCH_ACTION_STATE_QUIT, NULL);
         break;
      case EVENT_CMD_REINIT:
         {
            const struct retro_hw_render_callback *hw_render =
               (const struct retro_hw_render_callback*)video_driver_callback();
            const input_driver_t *input     = driver ?
               (const input_driver_t*)driver->input : NULL;

            driver->video_cache_context     = hw_render->cache_context;
            driver->video_cache_context_ack = false;
            event_command(EVENT_CMD_RESET_CONTEXT);
            driver->video_cache_context     = false;

            /* Poll input to avoid possibly stale data to corrupt things. */
            input->poll(driver->input_data);

#ifdef HAVE_MENU
            menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL);

            if (menu_driver_alive())
               event_command(EVENT_CMD_VIDEO_SET_BLOCKING_STATE);
#endif
         }
         break;
      case EVENT_CMD_CHEATS_DEINIT:
         if (!global)
            break;

         if (global->cheat)
            cheat_manager_free(global->cheat);
         global->cheat = NULL;
         break;
      case EVENT_CMD_CHEATS_INIT:
         event_command(EVENT_CMD_CHEATS_DEINIT);
         event_init_cheats();
         break;
      case EVENT_CMD_CHEATS_APPLY:
         if (!global->cheat)
            break;

         cheat_manager_apply_cheats(global->cheat);
         break;
      case EVENT_CMD_REMAPPING_DEINIT:
         break;
      case EVENT_CMD_REMAPPING_INIT:
         event_command(EVENT_CMD_REMAPPING_DEINIT);
         event_init_remapping();
         break;
      case EVENT_CMD_REWIND_DEINIT:
         if (!global)
            break;
#ifdef HAVE_NETPLAY
         if (driver->netplay_data)
            return false;
#endif
         if (global->rewind.state)
            state_manager_free(global->rewind.state);
         global->rewind.state = NULL;
         break;
      case EVENT_CMD_REWIND_INIT:
         if (!driver->netplay_data)
            init_rewind();
         break;
      case EVENT_CMD_REWIND_TOGGLE:
         if (settings->rewind_enable)
            event_command(EVENT_CMD_REWIND_INIT);
         else
            event_command(EVENT_CMD_REWIND_DEINIT);
         break;
      case EVENT_CMD_AUTOSAVE_DEINIT:
#ifdef HAVE_THREADS
         event_deinit_autosave();
#endif
         break;
      case EVENT_CMD_AUTOSAVE_INIT:
         event_command(EVENT_CMD_AUTOSAVE_DEINIT);
#ifdef HAVE_THREADS
         event_init_autosave();
#endif
         break;
      case EVENT_CMD_AUTOSAVE_STATE:
         event_save_auto_state();
         break;
      case EVENT_CMD_AUDIO_STOP:
         if (!driver->audio_data)
            return false;
         if (!audio_driver_alive())
            return false;

         if (!audio_driver_stop())
            return false;
         break;
      case EVENT_CMD_AUDIO_START:
         if (!driver->audio_data || audio_driver_alive())
            return false;

         if (!settings->audio.mute_enable && !audio_driver_start())
         {
            RARCH_ERR("Failed to start audio driver. Will continue without audio.\n");
            driver->audio_active = false;
         }
         break;
      case EVENT_CMD_AUDIO_MUTE_TOGGLE:
         {
            const char *msg = !settings->audio.mute_enable ?
               msg_hash_to_str(MSG_AUDIO_MUTED):
               msg_hash_to_str(MSG_AUDIO_UNMUTED);

            if (!audio_driver_mute_toggle())
            {
               RARCH_ERR("%s.\n",
                     msg_hash_to_str(MSG_FAILED_TO_UNMUTE_AUDIO));
               return false;
            }

            rarch_main_msg_queue_push(msg, 1, 180, true);
            RARCH_LOG("%s\n", msg);
         }
         break;
      case EVENT_CMD_OVERLAY_DEINIT:
#ifdef HAVE_OVERLAY
         input_overlay_free_ptr();
#endif
         break;
      case EVENT_CMD_OVERLAY_INIT:
         event_command(EVENT_CMD_OVERLAY_DEINIT);
#ifdef HAVE_OVERLAY
         if (input_overlay_new_ptr() == -1)
            RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_OVERLAY));
#endif
         break;
      case EVENT_CMD_OVERLAY_NEXT:
#ifdef HAVE_OVERLAY
         input_overlay_next(settings->input.overlay_opacity);
#endif
         break;
      case EVENT_CMD_DSP_FILTER_DEINIT:
         if (!global)
            break;

         audio_driver_dsp_filter_free();
         break;
      case EVENT_CMD_DSP_FILTER_INIT:
         event_command(EVENT_CMD_DSP_FILTER_DEINIT);
         if (!*settings->audio.dsp_plugin)
            break;
         audio_driver_dsp_filter_init(settings->audio.dsp_plugin);
         break;
      case EVENT_CMD_GPU_RECORD_DEINIT:
         if (!global)
            break;

         if (global->record.gpu_buffer)
            free(global->record.gpu_buffer);
         global->record.gpu_buffer = NULL;
         break;
      case EVENT_CMD_RECORD_DEINIT:
         if (!recording_deinit())
            return false;
         break;
      case EVENT_CMD_RECORD_INIT:
         event_command(EVENT_CMD_HISTORY_DEINIT);
         if (!recording_init())
            return false;
         break;
      case EVENT_CMD_HISTORY_DEINIT:
         if (g_defaults.history)
         {
            content_playlist_write_file(g_defaults.history);
            content_playlist_free(g_defaults.history);
         }
         g_defaults.history = NULL;
         break;
      case EVENT_CMD_HISTORY_INIT:
         event_command(EVENT_CMD_HISTORY_DEINIT);
         if (!settings->history_list_enable)
            return false;
         RARCH_LOG("%s: [%s].\n",
               msg_hash_to_str(MSG_LOADING_HISTORY_FILE),
               settings->content_history_path);
         g_defaults.history = content_playlist_init(
               settings->content_history_path,
               settings->content_history_size);
         break;
      case EVENT_CMD_CORE_INFO_DEINIT:
         if (!global)
            break;

         if (global->core_info.list)
            core_info_list_free(global->core_info.list);
         global->core_info.list = NULL;
         break;
      case EVENT_CMD_DATA_RUNLOOP_FREE:
         rarch_main_data_free();
         break;
      case EVENT_CMD_CORE_INFO_INIT:
         event_command(EVENT_CMD_CORE_INFO_DEINIT);

         if (*settings->libretro_directory)
            global->core_info.list = core_info_list_new();
         break;
      case EVENT_CMD_CORE_DEINIT:
         {
            struct retro_hw_render_callback *cb = video_driver_callback();
            event_deinit_core(true);

            if (cb)
               memset(cb, 0, sizeof(*cb));

            break;
         }
      case EVENT_CMD_CORE_INIT:
         if (!event_init_core())
            return false;
         break;
      case EVENT_CMD_VIDEO_APPLY_STATE_CHANGES:
         video_driver_apply_state_changes();
         break;
      case EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE:
         boolean = true; /* fall-through */
      case EVENT_CMD_VIDEO_SET_BLOCKING_STATE:
         video_driver_set_nonblock_state(boolean);
         break;
      case EVENT_CMD_VIDEO_SET_ASPECT_RATIO:
         video_driver_set_aspect_ratio(settings->video.aspect_ratio_idx);
         break;
      case EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE:
         boolean = true; /* fall-through */
      case EVENT_CMD_AUDIO_SET_BLOCKING_STATE:
         audio_driver_set_nonblock_state(boolean);
         break;
      case EVENT_CMD_OVERLAY_SET_SCALE_FACTOR:
#ifdef HAVE_OVERLAY
         input_overlay_set_scale_factor(settings->input.overlay_scale);
#endif
         break;
      case EVENT_CMD_OVERLAY_SET_ALPHA_MOD:
#ifdef HAVE_OVERLAY
         input_overlay_set_alpha_mod(settings->input.overlay_opacity);
#endif
         break;
      case EVENT_CMD_DRIVERS_DEINIT:
         uninit_drivers(DRIVERS_CMD_ALL);
         break;
      case EVENT_CMD_DRIVERS_INIT:
         init_drivers(DRIVERS_CMD_ALL);
         break;
      case EVENT_CMD_AUDIO_REINIT:
         uninit_drivers(DRIVER_AUDIO);
         init_drivers(DRIVER_AUDIO);
         break;
      case EVENT_CMD_RESET_CONTEXT:
         event_command(EVENT_CMD_DRIVERS_DEINIT);
         event_command(EVENT_CMD_DRIVERS_INIT);
         break;
      case EVENT_CMD_QUIT_RETROARCH:
         rarch_ctl(RARCH_ACTION_STATE_FORCE_QUIT, NULL);
         break;
      case EVENT_CMD_RESUME:
         rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL);
         break;
      case EVENT_CMD_RESTART_RETROARCH:
#if defined(GEKKO) && defined(HW_RVL)
         fill_pathname_join(global->path.fullpath, g_defaults.dir.core,
               SALAMANDER_FILE,
               sizeof(global->path.fullpath));
#endif
         if (driver->frontend_ctx && driver->frontend_ctx->set_fork)
            driver->frontend_ctx->set_fork(true, false);
         break;
      case EVENT_CMD_MENU_SAVE_CONFIG:
         if (!event_save_core_config())
            return false;
         break;
      case EVENT_CMD_SHADERS_APPLY_CHANGES:
#ifdef HAVE_MENU
         menu_shader_manager_apply_changes();
#endif
         break;
      case EVENT_CMD_PAUSE_CHECKS:
         rarch_main_ctl(RARCH_MAIN_CTL_IS_PAUSED, &boolean);

         if (boolean)
         {
            RARCH_LOG("%s\n", msg_hash_to_str(MSG_PAUSED));
            event_command(EVENT_CMD_AUDIO_STOP);

            if (settings->video.black_frame_insertion)
               video_driver_cached_frame();
         }
         else
         {
            RARCH_LOG("%s\n", msg_hash_to_str(MSG_UNPAUSED));
            event_command(EVENT_CMD_AUDIO_START);
         }
         break;
      case EVENT_CMD_PAUSE_TOGGLE:
         rarch_main_ctl(RARCH_MAIN_CTL_IS_PAUSED,  &boolean);
         boolean = !boolean;
         rarch_main_ctl(RARCH_MAIN_CTL_SET_PAUSED, &boolean);
         event_command(EVENT_CMD_PAUSE_CHECKS);
         break;
      case EVENT_CMD_UNPAUSE:
         boolean = false;

         rarch_main_ctl(RARCH_MAIN_CTL_SET_PAUSED, &boolean);
         event_command(EVENT_CMD_PAUSE_CHECKS);
         break;
      case EVENT_CMD_PAUSE:
         boolean = true;

         rarch_main_ctl(RARCH_MAIN_CTL_SET_PAUSED, &boolean);
         event_command(EVENT_CMD_PAUSE_CHECKS);
         break;
      case EVENT_CMD_MENU_PAUSE_LIBRETRO:
#ifdef HAVE_MENU
         if (menu_driver_alive())
         {
            if (settings->menu.pause_libretro)
               event_command(EVENT_CMD_AUDIO_STOP);
            else
               event_command(EVENT_CMD_AUDIO_START);
         }
         else
         {
            if (settings->menu.pause_libretro)
               event_command(EVENT_CMD_AUDIO_START);
         }
#endif
         break;
      case EVENT_CMD_SHADER_DIR_DEINIT:
         if (!global)
            break;

         dir_list_free(global->shader_dir.list);
         global->shader_dir.list = NULL;
         global->shader_dir.ptr  = 0;
         break;
      case EVENT_CMD_SHADER_DIR_INIT:
         event_command(EVENT_CMD_SHADER_DIR_DEINIT);

         if (!*settings->video.shader_dir)
            return false;

         global->shader_dir.list = dir_list_new_special(NULL, DIR_LIST_SHADERS);

         if (!global->shader_dir.list || global->shader_dir.list->size == 0)
         {
            event_command(EVENT_CMD_SHADER_DIR_DEINIT);
            return false;
         }

         global->shader_dir.ptr  = 0;
         dir_list_sort(global->shader_dir.list, false);

         for (i = 0; i < global->shader_dir.list->size; i++)
            RARCH_LOG("%s \"%s\"\n",
                  msg_hash_to_str(MSG_FOUND_SHADER),
                  global->shader_dir.list->elems[i].data);
         break;
      case EVENT_CMD_SAVEFILES:
         event_save_files();
         break;
      case EVENT_CMD_SAVEFILES_DEINIT:
         if (!global)
            break;

         if (global->savefiles)
            string_list_free(global->savefiles);
         global->savefiles = NULL;
         break;
      case EVENT_CMD_SAVEFILES_INIT:
         global->sram.use = global->sram.use && !global->sram.save_disable
#ifdef HAVE_NETPLAY
            && (!driver->netplay_data || !global->netplay.is_client)
#endif
            ;

         if (!global->sram.use)
            RARCH_LOG("%s\n",
                  msg_hash_to_str(MSG_SRAM_WILL_NOT_BE_SAVED));

         if (global->sram.use)
            event_command(EVENT_CMD_AUTOSAVE_INIT);
         break;
      case EVENT_CMD_MSG_QUEUE_DEINIT:
         rarch_main_msg_queue_free();
         break;
      case EVENT_CMD_MSG_QUEUE_INIT:
         event_command(EVENT_CMD_MSG_QUEUE_DEINIT);
         rarch_main_msg_queue_init();
         rarch_main_data_init_queues();
         break;
      case EVENT_CMD_BSV_MOVIE_DEINIT:
         if (!global)
            break;

         if (global->bsv.movie)
            bsv_movie_free(global->bsv.movie);
         global->bsv.movie = NULL;
         break;
      case EVENT_CMD_BSV_MOVIE_INIT:
         event_command(EVENT_CMD_BSV_MOVIE_DEINIT);
         event_init_movie();
         break;
      case EVENT_CMD_NETPLAY_DEINIT:
#ifdef HAVE_NETPLAY
         deinit_netplay();
#endif
         break;
      case EVENT_CMD_NETWORK_DEINIT:
#ifdef HAVE_NETWORKING
         network_deinit();
#endif
         break;
      case EVENT_CMD_NETWORK_INIT:
#ifdef HAVE_NETWORKING
         network_init();
#endif
         break;
      case EVENT_CMD_NETPLAY_INIT:
         event_command(EVENT_CMD_NETPLAY_DEINIT);
#ifdef HAVE_NETPLAY
         if (!init_netplay())
            return false;
#endif
         break;
      case EVENT_CMD_NETPLAY_FLIP_PLAYERS:
#ifdef HAVE_NETPLAY
         {
            netplay_t *netplay = (netplay_t*)driver->netplay_data;
            if (!netplay)
               return false;
            netplay_flip_users(netplay);
         }
#endif
         break;
      case EVENT_CMD_FULLSCREEN_TOGGLE:
         if (!video_driver_has_windowed())
            return false;

         /* If we go fullscreen we drop all drivers and
          * reinitialize to be safe. */
         settings->video.fullscreen = !settings->video.fullscreen;
         event_command(EVENT_CMD_REINIT);
         break;
      case EVENT_CMD_COMMAND_DEINIT:
#ifdef HAVE_COMMAND
         if (driver->command)
            rarch_cmd_free(driver->command);
         driver->command = NULL;
#endif
         break;
      case EVENT_CMD_COMMAND_INIT:
         event_command(EVENT_CMD_COMMAND_DEINIT);

#ifdef HAVE_COMMAND
         event_init_command();
#endif
         break;
      case EVENT_CMD_TEMPORARY_CONTENT_DEINIT:
         if (!global)
            break;

         if (global->temporary_content)
            event_free_temporary_content();
         global->temporary_content = NULL;
         break;
      case EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT:
         if (!global)
            break;

         if (global->subsystem_fullpaths)
            string_list_free(global->subsystem_fullpaths);
         global->subsystem_fullpaths = NULL;
         break;
      case EVENT_CMD_LOG_FILE_DEINIT:
         if (!global)
            break;

         if (global->log_file && global->log_file != stderr)
            fclose(global->log_file);
         global->log_file = NULL;
         break;
      case EVENT_CMD_DISK_EJECT_TOGGLE:
         if (system && system->disk_control.get_num_images)
         {
            const struct retro_disk_control_callback *control =
               (const struct retro_disk_control_callback*)
               &system->disk_control;

            if (control)
               event_check_disk_eject(control);
         }
         else
            rarch_main_msg_queue_push_new(
                  MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS,
                  1, 120, true);
         break;
      case EVENT_CMD_DISK_NEXT:
         if (system && system->disk_control.get_num_images)
         {
            const struct retro_disk_control_callback *control =
               (const struct retro_disk_control_callback*)
               &system->disk_control;

            if (!control)
               return false;

            if (!control->get_eject_state())
               return false;

            event_check_disk_next(control);
         }
         else
            rarch_main_msg_queue_push_new(
                  MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS,
                  1, 120, true);
         break;
      case EVENT_CMD_DISK_PREV:
         if (system && system->disk_control.get_num_images)
         {
            const struct retro_disk_control_callback *control =
               (const struct retro_disk_control_callback*)
               &system->disk_control;

            if (!control)
               return false;

            if (!control->get_eject_state())
               return false;

            event_check_disk_prev(control);
         }
         else
            rarch_main_msg_queue_push_new(
                  MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS,
                  1, 120, true);
         break;
      case EVENT_CMD_RUMBLE_STOP:
         for (i = 0; i < MAX_USERS; i++)
         {
            input_driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0);
            input_driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0);
         }
         break;
      case EVENT_CMD_GRAB_MOUSE_TOGGLE:
         {
            static bool grab_mouse_state  = false;

            grab_mouse_state = !grab_mouse_state;

            if (!driver->input || !input_driver_grab_mouse(grab_mouse_state))
               return false;

            RARCH_LOG("%s: %s.\n",
                  msg_hash_to_str(MSG_GRAB_MOUSE_STATE),
                  grab_mouse_state ? "yes" : "no");

            video_driver_show_mouse(!grab_mouse_state);
         }
         break;
      case EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG:
         rarch_perf_log();
         break;
      case EVENT_CMD_VOLUME_UP:
         event_set_volume(0.5f);
         break;
      case EVENT_CMD_VOLUME_DOWN:
         event_set_volume(-0.5f);
         break;
      case EVENT_CMD_SET_FRAME_LIMIT:
         rarch_main_ctl(RARCH_MAIN_CTL_SET_FRAME_LIMIT_LAST_TIME, NULL);
         break;
      case EVENT_CMD_NONE:
      default:
         return false;
   }

   return true;
}