diff --git a/Makefile.common b/Makefile.common
index e766c25458..8c76f1cfba 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -98,6 +98,7 @@ OBJ += frontend/frontend.o \
ui/drivers/ui_null.o \
libretro_version_1.o \
retroarch.o \
+ command_event.o \
runloop.o \
runloop_data.o \
content.o \
diff --git a/command_event.c b/command_event.c
new file mode 100644
index 0000000000..f0a02799be
--- /dev/null
+++ b/command_event.c
@@ -0,0 +1,1463 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2011-2015 - Daniel De Matteis
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#include "command_event.h"
+#include "performance.h"
+#include "runloop_data.h"
+#include "runloop.h"
+#include "dynamic.h"
+#include "content.h"
+#include "screenshot.h"
+#include "intl/intl.h"
+#include "retroarch.h"
+
+#include
+#include
+
+#include "input/input_remapping.h"
+
+#ifdef HAVE_MENU
+#include "menu/menu.h"
+#include "menu/menu_shader.h"
+#include "menu/menu_input.h"
+#endif
+
+#ifdef HAVE_NETPLAY
+#include "netplay.h"
+#endif
+
+#ifdef HAVE_NETWORKING
+#include
+#endif
+
+#ifdef HAVE_COMMAND
+static void event_init_command(void)
+{
+ driver_t *driver = driver_get_ptr();
+ settings_t *settings = config_get_ptr();
+
+ if (!settings->stdin_cmd_enable && !settings->network_cmd_enable)
+ return;
+
+ if (settings->stdin_cmd_enable && driver->stdin_claimed)
+ {
+ RARCH_WARN("stdin command interface is desired, but input driver has already claimed stdin.\n"
+ "Cannot use this command interface.\n");
+ }
+
+ if (!(driver->command = rarch_cmd_new(settings->stdin_cmd_enable
+ && !driver->stdin_claimed,
+ settings->network_cmd_enable, settings->network_cmd_port)))
+ RARCH_ERR("Failed to initialize command interface.\n");
+}
+#endif
+
+/**
+ * event_free_temporary_content:
+ *
+ * Frees temporary content handle.
+ **/
+static void event_free_temporary_content(void)
+{
+ unsigned i;
+ global_t *global = global_get_ptr();
+
+ for (i = 0; i < global->temporary_content->size; i++)
+ {
+ const char *path = global->temporary_content->elems[i].data;
+
+ RARCH_LOG("Removing temporary content file: %s.\n", path);
+ if (remove(path) < 0)
+ RARCH_ERR("Failed to remove temporary file: %s.\n", path);
+ }
+ string_list_free(global->temporary_content);
+}
+
+#if defined(HAVE_THREADS)
+static void event_init_autosave(void)
+{
+ unsigned i;
+ settings_t *settings = config_get_ptr();
+ global_t *global = global_get_ptr();
+
+ if (settings->autosave_interval < 1 || !global->savefiles)
+ return;
+
+ if (!(global->autosave = (autosave_t**)calloc(global->savefiles->size,
+ sizeof(*global->autosave))))
+ return;
+
+ global->num_autosave = global->savefiles->size;
+
+ for (i = 0; i < global->savefiles->size; i++)
+ {
+ const char *path = global->savefiles->elems[i].data;
+ unsigned type = global->savefiles->elems[i].attr.i;
+
+ if (pretro_get_memory_size(type) <= 0)
+ continue;
+
+ global->autosave[i] = autosave_new(path,
+ pretro_get_memory_data(type),
+ pretro_get_memory_size(type),
+ settings->autosave_interval);
+
+ if (!global->autosave[i])
+ RARCH_WARN(RETRO_LOG_INIT_AUTOSAVE_FAILED);
+ }
+}
+
+static void event_deinit_autosave(void)
+{
+ unsigned i;
+ global_t *global = global_get_ptr();
+
+ for (i = 0; i < global->num_autosave; i++)
+ autosave_free(global->autosave[i]);
+
+ if (global->autosave)
+ free(global->autosave);
+ global->autosave = NULL;
+
+ global->num_autosave = 0;
+}
+#endif
+
+static void event_save_files(void)
+{
+ unsigned i;
+ global_t *global = global_get_ptr();
+
+ if (!global->savefiles || !global->use_sram)
+ return;
+
+ for (i = 0; i < global->savefiles->size; i++)
+ {
+ unsigned type = global->savefiles->elems[i].attr.i;
+ const char *path = global->savefiles->elems[i].data;
+ RARCH_LOG("Saving RAM type #%u to \"%s\".\n", type, path);
+ save_ram_file(path, type);
+ }
+}
+
+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("Failed to load movie file: \"%s\".\n",
+ global->bsv.movie_start_path);
+ rarch_fail(1, "event_init_movie()");
+ }
+
+ global->bsv.movie_playback = true;
+ rarch_main_msg_queue_push("Starting movie playback.", 2, 180, false);
+ RARCH_LOG("Starting movie playback.\n");
+ settings->rewind_granularity = 1;
+ }
+ else if (global->bsv.movie_start_recording)
+ {
+ char msg[PATH_MAX_LENGTH];
+ snprintf(msg, sizeof(msg), "Starting movie record to \"%s\".",
+ 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("Failed to start movie record.", 1, 180, true);
+ RARCH_ERR("Failed to start movie record.\n");
+ return;
+ }
+
+ rarch_main_msg_queue_push(msg, 1, 180, true);
+ RARCH_LOG("Starting movie record to \"%s\".\n",
+ global->bsv.movie_start_path);
+ settings->rewind_granularity = 1;
+ }
+}
+
+/**
+ * event_check_disk_eject:
+ * @control : Handle to disk control handle.
+ *
+ * Perform disk eject (Core Disk Options).
+ **/
+static void event_check_disk_eject(
+ const struct retro_disk_control_callback *control)
+{
+ bool new_state = !control->get_eject_state();
+ rarch_disk_control_set_eject(new_state, true);
+}
+
+/**
+ * event_check_disk_prev:
+ * @control : Handle to disk control handle.
+ *
+ * Perform disk cycle to previous index action (Core Disk Options).
+ **/
+static void event_check_disk_prev(
+ const struct retro_disk_control_callback *control)
+{
+ unsigned num_disks = control->get_num_images();
+ unsigned current = control->get_image_index();
+ bool disk_prev_enable = num_disks && num_disks != UINT_MAX;
+
+ if (!disk_prev_enable)
+ {
+ RARCH_ERR("Got invalid disk index from libretro.\n");
+ return;
+ }
+
+ if (current > 0)
+ current--;
+ rarch_disk_control_set_index(current);
+}
+
+/**
+ * event_check_disk_next:
+ * @control : Handle to disk control handle.
+ *
+ * Perform disk cycle to next index action (Core Disk Options).
+ **/
+static void event_check_disk_next(
+ const struct retro_disk_control_callback *control)
+{
+ unsigned num_disks = control->get_num_images();
+ unsigned current = control->get_image_index();
+ bool disk_next_enable = num_disks && num_disks != UINT_MAX;
+
+ if (!disk_next_enable)
+ {
+ RARCH_ERR("Got invalid disk index from libretro.\n");
+ return;
+ }
+
+ if (current < num_disks - 1)
+ current++;
+ rarch_disk_control_set_index(current);
+}
+
+/**
+ * event_set_volume:
+ * @gain : amount of gain to be applied to current volume level.
+ *
+ * Adjusts the current audio volume level.
+ *
+ **/
+static void event_set_volume(float gain)
+{
+ char msg[PATH_MAX_LENGTH];
+ settings_t *settings = config_get_ptr();
+ global_t *global = global_get_ptr();
+
+ settings->audio.volume += gain;
+ settings->audio.volume = max(settings->audio.volume, -80.0f);
+ settings->audio.volume = min(settings->audio.volume, 12.0f);
+
+ snprintf(msg, sizeof(msg), "Volume: %.1f dB", settings->audio.volume);
+ rarch_main_msg_queue_push(msg, 1, 180, true);
+ RARCH_LOG("%s\n", msg);
+
+ global->audio_data.volume_gain = db_to_gain(settings->audio.volume);
+}
+
+/**
+ * event_init_controllers:
+ *
+ * Initialize libretro controllers.
+ **/
+static void event_init_controllers(void)
+{
+ unsigned i;
+ settings_t *settings = config_get_ptr();
+ global_t *global = global_get_ptr();
+
+ for (i = 0; i < MAX_USERS; i++)
+ {
+ const char *ident = NULL;
+ const struct retro_controller_description *desc = NULL;
+ unsigned device = settings->input.libretro_device[i];
+
+ if (i < global->system.num_ports)
+ desc = libretro_find_controller_description(
+ &global->system.ports[i], device);
+
+ if (desc)
+ ident = desc->desc;
+
+ if (!ident)
+ {
+ /* If we're trying to connect a completely unknown device,
+ * revert back to JOYPAD. */
+
+ if (device != RETRO_DEVICE_JOYPAD && device != RETRO_DEVICE_NONE)
+ {
+ /* Do not fix settings->input.libretro_device[i],
+ * because any use of dummy core will reset this,
+ * which is not a good idea. */
+ RARCH_WARN("Input device ID %u is unknown to this libretro implementation. Using RETRO_DEVICE_JOYPAD.\n", device);
+ device = RETRO_DEVICE_JOYPAD;
+ }
+ ident = "Joypad";
+ }
+
+ switch (device)
+ {
+ case RETRO_DEVICE_NONE:
+ RARCH_LOG("Disconnecting device from port %u.\n", i + 1);
+ pretro_set_controller_port_device(i, device);
+ break;
+ case RETRO_DEVICE_JOYPAD:
+ break;
+ default:
+ /* Some cores do not properly range check port argument.
+ * This is broken behavior of course, but avoid breaking
+ * cores needlessly. */
+ RARCH_LOG("Connecting %s (ID: %u) to port %u.\n", ident,
+ device, i + 1);
+ pretro_set_controller_port_device(i, device);
+ break;
+ }
+ }
+}
+
+static void event_deinit_core(bool reinit)
+{
+ global_t *global = global_get_ptr();
+
+ pretro_unload_game();
+ pretro_deinit();
+
+ if (reinit)
+ rarch_main_command(EVENT_CMD_DRIVERS_DEINIT);
+
+ if(global->overrides_active)
+ {
+ config_unload_override();
+ global->overrides_active = false;
+ }
+ pretro_set_environment(rarch_environment_cb);
+ uninit_libretro_sym();
+}
+
+static void event_init_cheats(void)
+{
+ bool allow_cheats = true;
+ driver_t *driver = driver_get_ptr();
+ global_t *global = global_get_ptr();
+
+ (void)driver;
+
+#ifdef HAVE_NETPLAY
+ allow_cheats &= !driver->netplay_data;
+#endif
+ allow_cheats &= !global->bsv.movie;
+
+ if (!allow_cheats)
+ return;
+
+ /* TODO/FIXME - add some stuff here. */
+}
+
+static bool event_load_save_files(void)
+{
+ unsigned i;
+ global_t *global = global_get_ptr();
+
+ if (!global->savefiles || global->sram_load_disable)
+ return false;
+
+ for (i = 0; i < global->savefiles->size; i++)
+ load_ram_file(global->savefiles->elems[i].data,
+ global->savefiles->elems[i].attr.i);
+
+ return true;
+}
+
+static void event_load_auto_state(void)
+{
+ bool ret;
+ char msg[PATH_MAX_LENGTH];
+ char savestate_name_auto[PATH_MAX_LENGTH];
+ settings_t *settings = config_get_ptr();
+ global_t *global = global_get_ptr();
+
+#ifdef HAVE_NETPLAY
+ if (global->netplay_enable && !global->netplay_is_spectate)
+ return;
+#endif
+
+ if (!settings->savestate_auto_load)
+ return;
+
+ fill_pathname_noext(savestate_name_auto, global->savestate_name,
+ ".auto", sizeof(savestate_name_auto));
+
+ if (!path_file_exists(savestate_name_auto))
+ return;
+
+ ret = load_state(savestate_name_auto);
+
+ RARCH_LOG("Found auto savestate in: %s\n", savestate_name_auto);
+
+ snprintf(msg, sizeof(msg), "Auto-loading savestate from \"%s\" %s.",
+ savestate_name_auto, ret ? "succeeded" : "failed");
+ rarch_main_msg_queue_push(msg, 1, 180, false);
+ RARCH_LOG("%s\n", msg);
+}
+
+static void event_set_savestate_auto_index(void)
+{
+ char state_dir[PATH_MAX_LENGTH], state_base[PATH_MAX_LENGTH];
+ size_t i;
+ struct string_list *dir_list = NULL;
+ unsigned max_idx = 0;
+ settings_t *settings = config_get_ptr();
+ global_t *global = global_get_ptr();
+
+ if (!settings->savestate_auto_index)
+ return;
+
+ /* Find the file in the same directory as global->savestate_name
+ * with the largest numeral suffix.
+ *
+ * E.g. /foo/path/content.state, will try to find
+ * /foo/path/content.state%d, where %d is the largest number available.
+ */
+
+ fill_pathname_basedir(state_dir, global->savestate_name,
+ sizeof(state_dir));
+ fill_pathname_base(state_base, global->savestate_name,
+ sizeof(state_base));
+
+ if (!(dir_list = dir_list_new(state_dir, NULL, false)))
+ return;
+
+ for (i = 0; i < dir_list->size; i++)
+ {
+ unsigned idx;
+ char elem_base[PATH_MAX_LENGTH];
+ const char *end = NULL;
+ const char *dir_elem = dir_list->elems[i].data;
+
+ fill_pathname_base(elem_base, dir_elem, sizeof(elem_base));
+
+ if (strstr(elem_base, state_base) != elem_base)
+ continue;
+
+ end = dir_elem + strlen(dir_elem);
+ while ((end > dir_elem) && isdigit(end[-1]))
+ end--;
+
+ idx = strtoul(end, NULL, 0);
+ if (idx > max_idx)
+ max_idx = idx;
+ }
+
+ dir_list_free(dir_list);
+
+ settings->state_slot = max_idx;
+ RARCH_LOG("Found last state slot: #%d\n", settings->state_slot);
+}
+
+static bool event_init_content(void)
+{
+ global_t *global = global_get_ptr();
+
+ /* No content to be loaded for dummy core,
+ * just successfully exit. */
+ if (global->libretro_dummy)
+ return true;
+
+ if (!global->libretro_no_content)
+ rarch_fill_pathnames();
+
+ if (!init_content_file())
+ return false;
+
+ if (global->libretro_no_content)
+ return true;
+
+ event_set_savestate_auto_index();
+
+ if (event_load_save_files())
+ RARCH_LOG("Skipping SRAM load.\n");
+
+ event_load_auto_state();
+ rarch_main_command(EVENT_CMD_BSV_MOVIE_INIT);
+ rarch_main_command(EVENT_CMD_NETPLAY_INIT);
+
+ return true;
+}
+
+static bool event_init_core(void)
+{
+ driver_t *driver = driver_get_ptr();
+ global_t *global = global_get_ptr();
+
+ if (config_load_override())
+ global->overrides_active = true;
+ else
+ global->overrides_active = false;
+
+ pretro_set_environment(rarch_environment_cb);
+
+ config_load_remap();
+
+ rarch_verify_api_version();
+ pretro_init();
+
+ global->use_sram = !global->libretro_dummy &&
+ !global->libretro_no_content;
+
+ if (!event_init_content())
+ return false;
+
+ retro_init_libretro_cbs(&driver->retro_ctx);
+ rarch_init_system_av_info();
+
+ return true;
+}
+
+static bool event_save_auto_state(void)
+{
+ bool ret;
+ char savestate_name_auto[PATH_MAX_LENGTH];
+ settings_t *settings = config_get_ptr();
+ global_t *global = global_get_ptr();
+
+ if (!settings->savestate_auto_save || global->libretro_dummy ||
+ global->libretro_no_content)
+ return false;
+
+ fill_pathname_noext(savestate_name_auto, global->savestate_name,
+ ".auto", sizeof(savestate_name_auto));
+
+ ret = save_state(savestate_name_auto);
+ RARCH_LOG("Auto save state to \"%s\" %s.\n", savestate_name_auto, ret ?
+ "succeeded" : "failed");
+
+ return true;
+}
+
+static void event_init_remapping(void)
+{
+ settings_t *settings = config_get_ptr();
+
+ if (!settings->input.remap_binds_enable)
+ return;
+
+ input_remapping_load_file(settings->input.remapping_path);
+}
+
+/**
+ * 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], config_name[PATH_MAX_LENGTH],
+ config_path[PATH_MAX_LENGTH], msg[PATH_MAX_LENGTH];
+ bool ret = false;
+ bool found_path = 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->config_path) /* Fallback */
+ fill_pathname_basedir(config_dir, global->config_path,
+ sizeof(config_dir));
+ else
+ {
+ const char *message = "Config directory not set. Cannot save new config.";
+ rarch_main_msg_queue_push(message, 1, 180, true);
+ RARCH_ERR("%s\n", message);
+ 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];
+
+ 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));
+ }
+
+ if ((ret = config_save_file(config_path)))
+ {
+ strlcpy(global->config_path, config_path,
+ sizeof(global->config_path));
+ 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);
+
+ return ret;
+}
+
+/**
+ * event_save_state
+ * @path : Path to state.
+ * @msg : Message.
+ * @sizeof_msg : Size of @msg.
+ *
+ * Saves a state with path being @path.
+ **/
+static void event_save_state(const char *path,
+ char *msg, size_t sizeof_msg)
+{
+ settings_t *settings = config_get_ptr();
+
+ if (!save_state(path))
+ {
+ snprintf(msg, sizeof_msg,
+ "Failed to save state to \"%s\".", path);
+ return;
+ }
+
+ if (settings->state_slot < 0)
+ snprintf(msg, sizeof_msg,
+ "Saved state to slot #-1 (auto).");
+ else
+ snprintf(msg, sizeof_msg,
+ "Saved state to slot #%d.", settings->state_slot);
+}
+
+/**
+ * event_load_state
+ * @path : Path to state.
+ * @msg : Message.
+ * @sizeof_msg : Size of @msg.
+ *
+ * Loads a state with path being @path.
+ **/
+static void event_load_state(const char *path,
+ char *msg, size_t sizeof_msg)
+{
+ settings_t *settings = config_get_ptr();
+
+ if (!load_state(path))
+ {
+ snprintf(msg, sizeof_msg,
+ "Failed to load state from \"%s\".", path);
+ return;
+
+ }
+
+ if (settings->state_slot < 0)
+ snprintf(msg, sizeof_msg,
+ "Loaded state from slot #-1 (auto).");
+ else
+ snprintf(msg, sizeof_msg,
+ "Loaded state from slot #%d.", settings->state_slot);
+}
+
+static void event_main_state(unsigned cmd)
+{
+ char path[PATH_MAX_LENGTH], msg[PATH_MAX_LENGTH];
+ global_t *global = global_get_ptr();
+ settings_t *settings = config_get_ptr();
+
+ if (settings->state_slot > 0)
+ snprintf(path, sizeof(path), "%s%d",
+ global->savestate_name, settings->state_slot);
+ else if (settings->state_slot < 0)
+ snprintf(path, sizeof(path), "%s.auto",
+ global->savestate_name);
+ else
+ strlcpy(path, global->savestate_name, sizeof(path));
+
+ if (pretro_serialize_size())
+ {
+ if (cmd == EVENT_CMD_SAVE_STATE)
+ event_save_state(path, msg, sizeof(msg));
+ else if (cmd == EVENT_CMD_LOAD_STATE)
+ event_load_state(path, msg, sizeof(msg));
+ }
+ else
+ strlcpy(msg, "Core does not support save states.", sizeof(msg));
+
+ rarch_main_msg_queue_push(msg, 2, 180, true);
+ RARCH_LOG("%s\n", msg);
+}
+
+static bool event_update_system_info(struct retro_system_info *_info,
+ bool *load_no_content)
+{
+ settings_t *settings = config_get_ptr();
+ global_t *global = global_get_ptr();
+
+#if defined(HAVE_DYNAMIC)
+ if (!(*settings->libretro))
+ return false;
+
+ libretro_get_system_info(settings->libretro, _info,
+ load_no_content);
+#endif
+ if (!global->core_info)
+ return false;
+
+ if (!core_info_list_get_info(global->core_info,
+ global->core_info_current, settings->libretro))
+ return false;
+
+ return true;
+}
+
+/**
+ * rarch_main_command:
+ * @cmd : Event command index.
+ *
+ * Performs RetroArch event command with index @cmd.
+ *
+ * Returns: true (1) on success, otherwise false (0).
+ **/
+bool rarch_main_command(unsigned cmd)
+{
+ unsigned i = 0;
+ bool boolean = false;
+ runloop_t *runloop = rarch_main_get_ptr();
+ driver_t *driver = driver_get_ptr();
+ global_t *global = global_get_ptr();
+ settings_t *settings = config_get_ptr();
+
+ (void)i;
+
+ switch (cmd)
+ {
+ case EVENT_CMD_LOAD_CONTENT_PERSIST:
+#ifdef HAVE_DYNAMIC
+ rarch_main_command(EVENT_CMD_LOAD_CORE);
+#endif
+ rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
+ break;
+ case EVENT_CMD_LOAD_CONTENT:
+#ifdef HAVE_DYNAMIC
+ rarch_main_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->fullpath);
+ rarch_main_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:
+ rarch_main_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:
+ rarch_main_command(EVENT_CMD_LOAD_CORE_PERSIST);
+#ifndef HAVE_DYNAMIC
+ rarch_main_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)
+ rarch_main_command(EVENT_CMD_REINIT);
+
+ global->pending.windowed_scale = 0;
+ break;
+ case EVENT_CMD_MENU_TOGGLE:
+ if (runloop->is_menu)
+ rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
+ else
+ rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING);
+ break;
+ case EVENT_CMD_CONTROLLERS_INIT:
+ event_init_controllers();
+ break;
+ case EVENT_CMD_RESET:
+ RARCH_LOG(RETRO_LOG_RESETTING_CONTENT);
+ rarch_main_msg_queue_push("Reset.", 1, 120, true);
+ pretro_reset();
+
+ /* bSNES since v073r01 resets controllers to JOYPAD
+ * after a reset, so just enforce it here. */
+ rarch_main_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_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->fullpath = '\0';
+
+ rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
+ global->system.shutdown = false;
+ }
+ break;
+ case EVENT_CMD_UNLOAD_CORE:
+ rarch_main_command(EVENT_CMD_PREPARE_DUMMY);
+#ifdef HAVE_DYNAMIC
+ libretro_free_system_info(&global->menu.info);
+#endif
+ break;
+ case EVENT_CMD_QUIT:
+ rarch_main_set_state(RARCH_ACTION_STATE_QUIT);
+ break;
+ case EVENT_CMD_REINIT:
+ driver->video_cache_context =
+ global->system.hw_render_callback.cache_context;
+ driver->video_cache_context_ack = false;
+ rarch_main_command(EVENT_CMD_RESET_CONTEXT);
+ driver->video_cache_context = false;
+
+ /* Poll input to avoid possibly stale data to corrupt things. */
+ input_driver_poll();
+
+#ifdef HAVE_MENU
+ runloop->frames.video.current.menu.framebuf.dirty = true;
+ if (runloop->is_menu)
+ rarch_main_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:
+ rarch_main_command(EVENT_CMD_CHEATS_DEINIT);
+ event_init_cheats();
+ break;
+ case EVENT_CMD_REMAPPING_DEINIT:
+ break;
+ case EVENT_CMD_REMAPPING_INIT:
+ rarch_main_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:
+ init_rewind();
+ break;
+ case EVENT_CMD_REWIND_TOGGLE:
+ if (settings->rewind_enable)
+ rarch_main_command(EVENT_CMD_REWIND_INIT);
+ else
+ rarch_main_command(EVENT_CMD_REWIND_DEINIT);
+ break;
+ case EVENT_CMD_AUTOSAVE_DEINIT:
+#ifdef HAVE_THREADS
+ event_deinit_autosave();
+#endif
+ break;
+ case EVENT_CMD_AUTOSAVE_INIT:
+ rarch_main_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 ?
+ "Audio muted." : "Audio unmuted.";
+
+ if (!audio_driver_mute_toggle())
+ {
+ RARCH_ERR("Failed to unmute audio.\n");
+ 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
+ if (driver->overlay)
+ input_overlay_free(driver->overlay);
+ driver->overlay = NULL;
+
+ memset(&driver->overlay_state, 0, sizeof(driver->overlay_state));
+#endif
+ break;
+ case EVENT_CMD_OVERLAY_INIT:
+ rarch_main_command(EVENT_CMD_OVERLAY_DEINIT);
+#ifdef HAVE_OVERLAY
+ if (driver->osk_enable)
+ {
+ if (!*settings->osk.overlay)
+ break;
+ }
+ else
+ {
+ if (!*settings->input.overlay)
+ break;
+ }
+
+ driver->overlay = input_overlay_new(driver->osk_enable ? settings->osk.overlay : settings->input.overlay,
+ driver->osk_enable ? settings->osk.enable : settings->input.overlay_enable,
+ settings->input.overlay_opacity, settings->input.overlay_scale);
+ if (!driver->overlay)
+ RARCH_ERR("Failed to load overlay.\n");
+#endif
+ break;
+ case EVENT_CMD_OVERLAY_NEXT:
+#ifdef HAVE_OVERLAY
+ input_overlay_next(driver->overlay, settings->input.overlay_opacity);
+#endif
+ break;
+ case EVENT_CMD_DSP_FILTER_DEINIT:
+ if (!global)
+ break;
+
+ if (global->audio_data.dsp)
+ rarch_dsp_filter_free(global->audio_data.dsp);
+ global->audio_data.dsp = NULL;
+ break;
+ case EVENT_CMD_DSP_FILTER_INIT:
+ rarch_main_command(EVENT_CMD_DSP_FILTER_DEINIT);
+ if (!*settings->audio.dsp_plugin)
+ break;
+
+ global->audio_data.dsp = rarch_dsp_filter_new(
+ settings->audio.dsp_plugin, global->audio_data.in_rate);
+ if (!global->audio_data.dsp)
+ RARCH_ERR("[DSP]: Failed to initialize DSP filter \"%s\".\n",
+ 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:
+ rarch_main_command(EVENT_CMD_HISTORY_DEINIT);
+ if (!recording_init())
+ return false;
+ break;
+ case EVENT_CMD_HISTORY_DEINIT:
+ if (g_defaults.history)
+ content_playlist_free(g_defaults.history);
+ g_defaults.history = NULL;
+ break;
+ case EVENT_CMD_HISTORY_INIT:
+ rarch_main_command(EVENT_CMD_HISTORY_DEINIT);
+ if (!settings->history_list_enable)
+ return false;
+ RARCH_LOG("Loading history file: [%s].\n", 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)
+ core_info_list_free(global->core_info);
+ global->core_info = NULL;
+ break;
+ case EVENT_CMD_DATA_RUNLOOP_FREE:
+ rarch_main_data_free();
+ break;
+ case EVENT_CMD_CORE_INFO_INIT:
+ rarch_main_command(EVENT_CMD_CORE_INFO_DEINIT);
+
+ if (*settings->libretro_directory)
+ global->core_info = core_info_list_new(settings->libretro_directory);
+ break;
+ case EVENT_CMD_CORE_DEINIT:
+ event_deinit_core(true);
+ 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(driver->overlay,
+ settings->input.overlay_scale);
+#endif
+ break;
+ case EVENT_CMD_OVERLAY_SET_ALPHA_MOD:
+#ifdef HAVE_OVERLAY
+ input_overlay_set_alpha_mod(driver->overlay,
+ 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:
+ rarch_main_command(EVENT_CMD_DRIVERS_DEINIT);
+ rarch_main_command(EVENT_CMD_DRIVERS_INIT);
+ break;
+ case EVENT_CMD_QUIT_RETROARCH:
+ rarch_main_set_state(RARCH_ACTION_STATE_FORCE_QUIT);
+ break;
+ case EVENT_CMD_RESUME:
+ rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
+ break;
+ case EVENT_CMD_RESTART_RETROARCH:
+#if defined(GEKKO) && defined(HW_RVL)
+ fill_pathname_join(global->fullpath, g_defaults.core_dir,
+ SALAMANDER_FILE,
+ sizeof(global->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:
+ if (runloop->is_paused)
+ {
+ RARCH_LOG("Paused.\n");
+ rarch_main_command(EVENT_CMD_AUDIO_STOP);
+
+ if (settings->video.black_frame_insertion)
+ rarch_render_cached_frame();
+ }
+ else
+ {
+ RARCH_LOG("Unpaused.\n");
+ rarch_main_command(EVENT_CMD_AUDIO_START);
+ }
+ break;
+ case EVENT_CMD_PAUSE_TOGGLE:
+ runloop->is_paused = !runloop->is_paused;
+ rarch_main_command(EVENT_CMD_PAUSE_CHECKS);
+ break;
+ case EVENT_CMD_UNPAUSE:
+ runloop->is_paused = false;
+ rarch_main_command(EVENT_CMD_PAUSE_CHECKS);
+ break;
+ case EVENT_CMD_PAUSE:
+ runloop->is_paused = true;
+ rarch_main_command(EVENT_CMD_PAUSE_CHECKS);
+ break;
+ case EVENT_CMD_MENU_PAUSE_LIBRETRO:
+ if (runloop->is_menu)
+ {
+ if (settings->menu.pause_libretro)
+ rarch_main_command(EVENT_CMD_AUDIO_STOP);
+ else
+ rarch_main_command(EVENT_CMD_AUDIO_START);
+ }
+ else
+ {
+ if (settings->menu.pause_libretro)
+ rarch_main_command(EVENT_CMD_AUDIO_START);
+ }
+ 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:
+ rarch_main_command(EVENT_CMD_SHADER_DIR_DEINIT);
+
+ if (!*settings->video.shader_dir)
+ return false;
+
+ global->shader_dir.list = dir_list_new(settings->video.shader_dir,
+ "cg|cgp|glsl|glslp", false);
+
+ if (!global->shader_dir.list || global->shader_dir.list->size == 0)
+ {
+ rarch_main_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("Found shader \"%s\"\n",
+ 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->use_sram = global->use_sram && !global->sram_save_disable
+#ifdef HAVE_NETPLAY
+ && (!driver->netplay_data || !global->netplay_is_client)
+#endif
+ ;
+
+ if (!global->use_sram)
+ RARCH_LOG("SRAM will not be saved.\n");
+
+ if (global->use_sram)
+ rarch_main_command(EVENT_CMD_AUTOSAVE_INIT);
+ break;
+ case EVENT_CMD_MSG_QUEUE_DEINIT:
+ rarch_main_msg_queue_free();
+ break;
+ case EVENT_CMD_MSG_QUEUE_INIT:
+ rarch_main_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:
+ rarch_main_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:
+ rarch_main_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;
+ rarch_main_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:
+ rarch_main_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)
+ fclose(global->log_file);
+ global->log_file = NULL;
+ break;
+ case EVENT_CMD_DISK_EJECT_TOGGLE:
+ if (global->system.disk_control.get_num_images)
+ {
+ const struct retro_disk_control_callback *control =
+ (const struct retro_disk_control_callback*)
+ &global->system.disk_control;
+
+ if (control)
+ event_check_disk_eject(control);
+ }
+ else
+ rarch_main_msg_queue_push("Core does not support Disk Options.", 1, 120, true);
+ break;
+ case EVENT_CMD_DISK_NEXT:
+ if (global->system.disk_control.get_num_images)
+ {
+ const struct retro_disk_control_callback *control =
+ (const struct retro_disk_control_callback*)
+ &global->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("Core does not support Disk Options.", 1, 120, true);
+ break;
+ case EVENT_CMD_DISK_PREV:
+ if (global->system.disk_control.get_num_images)
+ {
+ const struct retro_disk_control_callback *control =
+ (const struct retro_disk_control_callback*)
+ &global->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("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("Grab mouse state: %s.\n",
+ 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;
+ }
+
+ return true;
+}
diff --git a/command_event.h b/command_event.h
index 2943de3f7c..95dbd7c060 100644
--- a/command_event.h
+++ b/command_event.h
@@ -1,5 +1,4 @@
/* RetroArch - A frontend for libretro.
- * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2015 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
@@ -19,7 +18,6 @@
#include
#include
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/griffin/griffin.c b/griffin/griffin.c
index c4da0161ae..db43a6e9df 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -733,6 +733,8 @@ MENU
#include "../command.c"
#endif
+#include "../command_event.c"
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/retroarch.c b/retroarch.c
index d6bbcba931..ac9a16ed12 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -799,294 +799,6 @@ static void parse_input(int argc, char *argv[])
sizeof(global->savestate_dir));
}
-/**
- * init_controllers:
- *
- * Initialize libretro controllers.
- **/
-static void init_controllers(void)
-{
- unsigned i;
- settings_t *settings = config_get_ptr();
- global_t *global = global_get_ptr();
-
- for (i = 0; i < MAX_USERS; i++)
- {
- const char *ident = NULL;
- const struct retro_controller_description *desc = NULL;
- unsigned device = settings->input.libretro_device[i];
-
- if (i < global->system.num_ports)
- desc = libretro_find_controller_description(
- &global->system.ports[i], device);
-
- if (desc)
- ident = desc->desc;
-
- if (!ident)
- {
- /* If we're trying to connect a completely unknown device,
- * revert back to JOYPAD. */
-
- if (device != RETRO_DEVICE_JOYPAD && device != RETRO_DEVICE_NONE)
- {
- /* Do not fix settings->input.libretro_device[i],
- * because any use of dummy core will reset this,
- * which is not a good idea. */
- RARCH_WARN("Input device ID %u is unknown to this libretro implementation. Using RETRO_DEVICE_JOYPAD.\n", device);
- device = RETRO_DEVICE_JOYPAD;
- }
- ident = "Joypad";
- }
-
- switch (device)
- {
- case RETRO_DEVICE_NONE:
- RARCH_LOG("Disconnecting device from port %u.\n", i + 1);
- pretro_set_controller_port_device(i, device);
- break;
- case RETRO_DEVICE_JOYPAD:
- break;
- default:
- /* Some cores do not properly range check port argument.
- * This is broken behavior of course, but avoid breaking
- * cores needlessly. */
- RARCH_LOG("Connecting %s (ID: %u) to port %u.\n", ident,
- device, i + 1);
- pretro_set_controller_port_device(i, device);
- break;
- }
- }
-}
-
-static bool load_save_files(void)
-{
- unsigned i;
- global_t *global = global_get_ptr();
-
- if (!global->savefiles || global->sram_load_disable)
- return false;
-
- for (i = 0; i < global->savefiles->size; i++)
- load_ram_file(global->savefiles->elems[i].data,
- global->savefiles->elems[i].attr.i);
-
- return true;
-}
-
-static void save_files(void)
-{
- unsigned i;
- global_t *global = global_get_ptr();
-
- if (!global->savefiles || !global->use_sram)
- return;
-
- for (i = 0; i < global->savefiles->size; i++)
- {
- unsigned type = global->savefiles->elems[i].attr.i;
- const char *path = global->savefiles->elems[i].data;
- RARCH_LOG("Saving RAM type #%u to \"%s\".\n", type, path);
- save_ram_file(path, type);
- }
-}
-
-static void init_remapping(void)
-{
- settings_t *settings = config_get_ptr();
-
- if (!settings->input.remap_binds_enable)
- return;
-
- input_remapping_load_file(settings->input.remapping_path);
-}
-
-static void init_cheats(void)
-{
- bool allow_cheats = true;
- driver_t *driver = driver_get_ptr();
- global_t *global = global_get_ptr();
-
- (void)driver;
-
-#ifdef HAVE_NETPLAY
- allow_cheats &= !driver->netplay_data;
-#endif
- allow_cheats &= !global->bsv.movie;
-
- if (!allow_cheats)
- return;
-
- /* TODO/FIXME - add some stuff here. */
-}
-
-static void 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("Failed to load movie file: \"%s\".\n",
- global->bsv.movie_start_path);
- rarch_fail(1, "init_movie()");
- }
-
- global->bsv.movie_playback = true;
- rarch_main_msg_queue_push("Starting movie playback.", 2, 180, false);
- RARCH_LOG("Starting movie playback.\n");
- settings->rewind_granularity = 1;
- }
- else if (global->bsv.movie_start_recording)
- {
- char msg[PATH_MAX_LENGTH];
- snprintf(msg, sizeof(msg), "Starting movie record to \"%s\".",
- 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("Failed to start movie record.", 1, 180, true);
- RARCH_ERR("Failed to start movie record.\n");
- return;
- }
-
- rarch_main_msg_queue_push(msg, 1, 180, true);
- RARCH_LOG("Starting movie record to \"%s\".\n",
- global->bsv.movie_start_path);
- settings->rewind_granularity = 1;
- }
-}
-
-#ifdef HAVE_COMMAND
-static void init_command(void)
-{
- driver_t *driver = driver_get_ptr();
- settings_t *settings = config_get_ptr();
-
- if (!settings->stdin_cmd_enable && !settings->network_cmd_enable)
- return;
-
- if (settings->stdin_cmd_enable && driver->stdin_claimed)
- {
- RARCH_WARN("stdin command interface is desired, but input driver has already claimed stdin.\n"
- "Cannot use this command interface.\n");
- }
-
- if (!(driver->command = rarch_cmd_new(settings->stdin_cmd_enable
- && !driver->stdin_claimed,
- settings->network_cmd_enable, settings->network_cmd_port)))
- RARCH_ERR("Failed to initialize command interface.\n");
-}
-#endif
-
-#if defined(HAVE_THREADS)
-static void init_autosave(void)
-{
- unsigned i;
- settings_t *settings = config_get_ptr();
- global_t *global = global_get_ptr();
-
- if (settings->autosave_interval < 1 || !global->savefiles)
- return;
-
- if (!(global->autosave = (autosave_t**)calloc(global->savefiles->size,
- sizeof(*global->autosave))))
- return;
-
- global->num_autosave = global->savefiles->size;
-
- for (i = 0; i < global->savefiles->size; i++)
- {
- const char *path = global->savefiles->elems[i].data;
- unsigned type = global->savefiles->elems[i].attr.i;
-
- if (pretro_get_memory_size(type) <= 0)
- continue;
-
- global->autosave[i] = autosave_new(path,
- pretro_get_memory_data(type),
- pretro_get_memory_size(type),
- settings->autosave_interval);
-
- if (!global->autosave[i])
- RARCH_WARN(RETRO_LOG_INIT_AUTOSAVE_FAILED);
- }
-}
-
-static void deinit_autosave(void)
-{
- unsigned i;
- global_t *global = global_get_ptr();
-
- for (i = 0; i < global->num_autosave; i++)
- autosave_free(global->autosave[i]);
-
- if (global->autosave)
- free(global->autosave);
- global->autosave = NULL;
-
- global->num_autosave = 0;
-}
-#endif
-
-static void set_savestate_auto_index(void)
-{
- char state_dir[PATH_MAX_LENGTH], state_base[PATH_MAX_LENGTH];
- size_t i;
- struct string_list *dir_list = NULL;
- unsigned max_idx = 0;
- settings_t *settings = config_get_ptr();
- global_t *global = global_get_ptr();
-
- if (!settings->savestate_auto_index)
- return;
-
- /* Find the file in the same directory as global->savestate_name
- * with the largest numeral suffix.
- *
- * E.g. /foo/path/content.state, will try to find
- * /foo/path/content.state%d, where %d is the largest number available.
- */
-
- fill_pathname_basedir(state_dir, global->savestate_name,
- sizeof(state_dir));
- fill_pathname_base(state_base, global->savestate_name,
- sizeof(state_base));
-
- if (!(dir_list = dir_list_new(state_dir, NULL, false)))
- return;
-
- for (i = 0; i < dir_list->size; i++)
- {
- unsigned idx;
- char elem_base[PATH_MAX_LENGTH];
- const char *end = NULL;
- const char *dir_elem = dir_list->elems[i].data;
-
- fill_pathname_base(elem_base, dir_elem, sizeof(elem_base));
-
- if (strstr(elem_base, state_base) != elem_base)
- continue;
-
- end = dir_elem + strlen(dir_elem);
- while ((end > dir_elem) && isdigit(end[-1]))
- end--;
-
- idx = strtoul(end, NULL, 0);
- if (idx > max_idx)
- max_idx = idx;
- }
-
- dir_list_free(dir_list);
-
- settings->state_slot = max_idx;
- RARCH_LOG("Found last state slot: #%d\n", settings->state_slot);
-}
-
static void rarch_init_savefile_paths(void)
{
global_t *global = global_get_ptr();
@@ -1172,7 +884,7 @@ static void rarch_init_savefile_paths(void)
}
}
-static void fill_pathnames(void)
+void rarch_fill_pathnames(void)
{
global_t *global = global_get_ptr();
@@ -1194,145 +906,6 @@ static void fill_pathnames(void)
sizeof(global->ips_name));
}
-static void load_auto_state(void)
-{
- bool ret;
- char msg[PATH_MAX_LENGTH];
- char savestate_name_auto[PATH_MAX_LENGTH];
- settings_t *settings = config_get_ptr();
- global_t *global = global_get_ptr();
-
-#ifdef HAVE_NETPLAY
- if (global->netplay_enable && !global->netplay_is_spectate)
- return;
-#endif
-
- if (!settings->savestate_auto_load)
- return;
-
- fill_pathname_noext(savestate_name_auto, global->savestate_name,
- ".auto", sizeof(savestate_name_auto));
-
- if (!path_file_exists(savestate_name_auto))
- return;
-
- ret = load_state(savestate_name_auto);
-
- RARCH_LOG("Found auto savestate in: %s\n", savestate_name_auto);
-
- snprintf(msg, sizeof(msg), "Auto-loading savestate from \"%s\" %s.",
- savestate_name_auto, ret ? "succeeded" : "failed");
- rarch_main_msg_queue_push(msg, 1, 180, false);
- RARCH_LOG("%s\n", msg);
-}
-
-static bool save_auto_state(void)
-{
- bool ret;
- char savestate_name_auto[PATH_MAX_LENGTH];
- settings_t *settings = config_get_ptr();
- global_t *global = global_get_ptr();
-
- if (!settings->savestate_auto_save || global->libretro_dummy ||
- global->libretro_no_content)
- return false;
-
- fill_pathname_noext(savestate_name_auto, global->savestate_name,
- ".auto", sizeof(savestate_name_auto));
-
- ret = save_state(savestate_name_auto);
- RARCH_LOG("Auto save state to \"%s\" %s.\n", savestate_name_auto, ret ?
- "succeeded" : "failed");
-
- return true;
-}
-
-/**
- * rarch_load_state
- * @path : Path to state.
- * @msg : Message.
- * @sizeof_msg : Size of @msg.
- *
- * Loads a state with path being @path.
- **/
-static void rarch_load_state(const char *path,
- char *msg, size_t sizeof_msg)
-{
- settings_t *settings = config_get_ptr();
-
- if (!load_state(path))
- {
- snprintf(msg, sizeof_msg,
- "Failed to load state from \"%s\".", path);
- return;
-
- }
-
- if (settings->state_slot < 0)
- snprintf(msg, sizeof_msg,
- "Loaded state from slot #-1 (auto).");
- else
- snprintf(msg, sizeof_msg,
- "Loaded state from slot #%d.", settings->state_slot);
-}
-
-/**
- * rarch_save_state
- * @path : Path to state.
- * @msg : Message.
- * @sizeof_msg : Size of @msg.
- *
- * Saves a state with path being @path.
- **/
-static void rarch_save_state(const char *path,
- char *msg, size_t sizeof_msg)
-{
- settings_t *settings = config_get_ptr();
-
- if (!save_state(path))
- {
- snprintf(msg, sizeof_msg,
- "Failed to save state to \"%s\".", path);
- return;
- }
-
- if (settings->state_slot < 0)
- snprintf(msg, sizeof_msg,
- "Saved state to slot #-1 (auto).");
- else
- snprintf(msg, sizeof_msg,
- "Saved state to slot #%d.", settings->state_slot);
-}
-
-static void main_state(unsigned cmd)
-{
- char path[PATH_MAX_LENGTH], msg[PATH_MAX_LENGTH];
- global_t *global = global_get_ptr();
- settings_t *settings = config_get_ptr();
-
- if (settings->state_slot > 0)
- snprintf(path, sizeof(path), "%s%d",
- global->savestate_name, settings->state_slot);
- else if (settings->state_slot < 0)
- snprintf(path, sizeof(path), "%s.auto",
- global->savestate_name);
- else
- strlcpy(path, global->savestate_name, sizeof(path));
-
- if (pretro_serialize_size())
- {
- if (cmd == EVENT_CMD_SAVE_STATE)
- rarch_save_state(path, msg, sizeof(msg));
- else if (cmd == EVENT_CMD_LOAD_STATE)
- rarch_load_state(path, msg, sizeof(msg));
- }
- else
- strlcpy(msg, "Core does not support save states.", sizeof(msg));
-
- rarch_main_msg_queue_push(msg, 2, 180, true);
- RARCH_LOG("%s\n", msg);
-}
-
/**
* rarch_disk_control_append_image:
* @path : Path to disk image.
@@ -1373,7 +946,7 @@ void rarch_disk_control_append_image(const char *path)
* started out in a single disk case, and that this way
* of doing it makes the most sense. */
set_paths(path);
- fill_pathnames();
+ rarch_fill_pathnames();
}
rarch_main_command(EVENT_CMD_AUTOSAVE_INIT);
@@ -1476,67 +1049,6 @@ void rarch_disk_control_set_index(unsigned idx)
}
}
-/**
- * check_disk_eject:
- * @control : Handle to disk control handle.
- *
- * Perform disk eject (Core Disk Options).
- **/
-static void check_disk_eject(
- const struct retro_disk_control_callback *control)
-{
- bool new_state = !control->get_eject_state();
- rarch_disk_control_set_eject(new_state, true);
-}
-
-/**
- * check_disk_next:
- * @control : Handle to disk control handle.
- *
- * Perform disk cycle to next index action (Core Disk Options).
- **/
-static void check_disk_next(
- const struct retro_disk_control_callback *control)
-{
- unsigned num_disks = control->get_num_images();
- unsigned current = control->get_image_index();
- bool disk_next_enable = num_disks && num_disks != UINT_MAX;
-
- if (!disk_next_enable)
- {
- RARCH_ERR("Got invalid disk index from libretro.\n");
- return;
- }
-
- if (current < num_disks - 1)
- current++;
- rarch_disk_control_set_index(current);
-}
-
-/**
- * check_disk_prev:
- * @control : Handle to disk control handle.
- *
- * Perform disk cycle to previous index action (Core Disk Options).
- **/
-static void check_disk_prev(
- const struct retro_disk_control_callback *control)
-{
- unsigned num_disks = control->get_num_images();
- unsigned current = control->get_image_index();
- bool disk_prev_enable = num_disks && num_disks != UINT_MAX;
-
- if (!disk_prev_enable)
- {
- RARCH_ERR("Got invalid disk index from libretro.\n");
- return;
- }
-
- if (current > 0)
- current--;
- rarch_disk_control_set_index(current);
-}
-
static bool init_state(void)
{
driver_t *driver = driver_get_ptr();
@@ -1549,27 +1061,6 @@ static bool init_state(void)
return true;
}
-/**
- * free_temporary_content:
- *
- * Frees temporary content handle.
- **/
-static void free_temporary_content(void)
-{
- unsigned i;
- global_t *global = global_get_ptr();
-
- for (i = 0; i < global->temporary_content->size; i++)
- {
- const char *path = global->temporary_content->elems[i].data;
-
- RARCH_LOG("Removing temporary content file: %s.\n", path);
- if (remove(path) < 0)
- RARCH_ERR("Failed to remove temporary file: %s.\n", path);
- }
- string_list_free(global->temporary_content);
-}
-
static void main_clear_state_drivers(void)
{
global_t *global = global_get_ptr();
@@ -1675,7 +1166,7 @@ static void init_system_info(void)
}
/*
- * verify_api_version:
+ * rarch_verify_api_version:
*
* Compare libretro core API version against API version
* used by RetroArch.
@@ -1683,7 +1174,7 @@ static void init_system_info(void)
* TODO - when libretro v2 gets added, allow for switching
* between libretro version backend dynamically.
**/
-static void verify_api_version(void)
+void rarch_verify_api_version(void)
{
RARCH_LOG("Version of libretro API: %u\n", pretro_api_version());
@@ -1726,12 +1217,12 @@ static void validate_cpu_features(void)
}
/**
- * init_system_av_info:
+ * rarch_init_system_av_info:
*
* Initialize system A/V information by calling the libretro core's
* get_system_av_info function.
**/
-static void init_system_av_info(void)
+void rarch_init_system_av_info(void)
{
runloop_t *runloop = rarch_main_get_ptr();
global_t *global = global_get_ptr();
@@ -1740,85 +1231,6 @@ static void init_system_av_info(void)
runloop->frames.limit.last_time = rarch_get_time_usec();
}
-static void deinit_core(bool reinit)
-{
-
- global_t *global = global_get_ptr();
-
- pretro_unload_game();
- pretro_deinit();
-
- if (reinit)
- rarch_main_command(EVENT_CMD_DRIVERS_DEINIT);
-
- if(global->overrides_active)
- {
- config_unload_override();
- global->overrides_active = false;
- }
- pretro_set_environment(rarch_environment_cb);
- uninit_libretro_sym();
-}
-
-static bool init_content(void)
-{
- global_t *global = global_get_ptr();
-
- /* No content to be loaded for dummy core,
- * just successfully exit. */
- if (global->libretro_dummy)
- return true;
-
- if (!global->libretro_no_content)
- fill_pathnames();
-
- if (!init_content_file())
- return false;
-
- if (global->libretro_no_content)
- return true;
-
- set_savestate_auto_index();
-
- if (load_save_files())
- RARCH_LOG("Skipping SRAM load.\n");
-
- load_auto_state();
- rarch_main_command(EVENT_CMD_BSV_MOVIE_INIT);
- rarch_main_command(EVENT_CMD_NETPLAY_INIT);
-
- return true;
-}
-
-static bool init_core(void)
-{
- driver_t *driver = driver_get_ptr();
- global_t *global = global_get_ptr();
-
- if (config_load_override())
- global->overrides_active = true;
- else
- global->overrides_active = false;
-
- pretro_set_environment(rarch_environment_cb);
-
- config_load_remap();
-
- verify_api_version();
- pretro_init();
-
- global->use_sram = !global->libretro_dummy &&
- !global->libretro_no_content;
-
- if (!init_content())
- return false;
-
- retro_init_libretro_cbs(&driver->retro_ctx);
- init_system_av_info();
-
- return true;
-}
-
/**
* rarch_main_init:
* @argc : Count of (commandline) arguments.
@@ -2049,839 +1461,6 @@ void rarch_main_set_state(unsigned cmd)
}
}
-/**
- * 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 save_core_config(void)
-{
- char config_dir[PATH_MAX_LENGTH], config_name[PATH_MAX_LENGTH],
- config_path[PATH_MAX_LENGTH], msg[PATH_MAX_LENGTH];
- bool ret = false;
- bool found_path = 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->config_path) /* Fallback */
- fill_pathname_basedir(config_dir, global->config_path,
- sizeof(config_dir));
- else
- {
- const char *message = "Config directory not set. Cannot save new config.";
- rarch_main_msg_queue_push(message, 1, 180, true);
- RARCH_ERR("%s\n", message);
- 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];
-
- 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));
- }
-
- if ((ret = config_save_file(config_path)))
- {
- strlcpy(global->config_path, config_path,
- sizeof(global->config_path));
- 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);
-
- return ret;
-}
-
-static bool rarch_update_system_info(struct retro_system_info *_info,
- bool *load_no_content)
-{
- settings_t *settings = config_get_ptr();
- global_t *global = global_get_ptr();
-
-#if defined(HAVE_DYNAMIC)
- if (!(*settings->libretro))
- return false;
-
- libretro_get_system_info(settings->libretro, _info,
- load_no_content);
-#endif
- if (!global->core_info)
- return false;
-
- if (!core_info_list_get_info(global->core_info,
- global->core_info_current, settings->libretro))
- return false;
-
- return true;
-}
-
-/**
- * set_volume:
- * @gain : amount of gain to be applied to current volume level.
- *
- * Adjusts the current audio volume level.
- *
- **/
-static void set_volume(float gain)
-{
- char msg[PATH_MAX_LENGTH];
- settings_t *settings = config_get_ptr();
- global_t *global = global_get_ptr();
-
- settings->audio.volume += gain;
- settings->audio.volume = max(settings->audio.volume, -80.0f);
- settings->audio.volume = min(settings->audio.volume, 12.0f);
-
- snprintf(msg, sizeof(msg), "Volume: %.1f dB", settings->audio.volume);
- rarch_main_msg_queue_push(msg, 1, 180, true);
- RARCH_LOG("%s\n", msg);
-
- global->audio_data.volume_gain = db_to_gain(settings->audio.volume);
-}
-
-/**
- * rarch_main_command:
- * @cmd : Command index.
- *
- * Performs RetroArch command with index @cmd.
- *
- * Returns: true (1) on success, otherwise false (0).
- **/
-bool rarch_main_command(unsigned cmd)
-{
- unsigned i = 0;
- bool boolean = false;
- runloop_t *runloop = rarch_main_get_ptr();
- driver_t *driver = driver_get_ptr();
- global_t *global = global_get_ptr();
- settings_t *settings = config_get_ptr();
-
- (void)i;
-
- switch (cmd)
- {
- case EVENT_CMD_LOAD_CONTENT_PERSIST:
-#ifdef HAVE_DYNAMIC
- rarch_main_command(EVENT_CMD_LOAD_CORE);
-#endif
- rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
- break;
- case EVENT_CMD_LOAD_CONTENT:
-#ifdef HAVE_DYNAMIC
- rarch_main_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->fullpath);
- rarch_main_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:
- rarch_main_command(EVENT_CMD_LOAD_CORE_DEINIT);
- {
-#ifdef HAVE_MENU
- menu_handle_t *menu = menu_driver_get_ptr();
- if (menu)
- rarch_update_system_info(&global->menu.info,
- &menu->load_no_content);
-#endif
- }
- break;
- case EVENT_CMD_LOAD_CORE:
- rarch_main_command(EVENT_CMD_LOAD_CORE_PERSIST);
-#ifndef HAVE_DYNAMIC
- rarch_main_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
- 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)
- rarch_main_command(EVENT_CMD_REINIT);
-
- global->pending.windowed_scale = 0;
- break;
- case EVENT_CMD_MENU_TOGGLE:
- if (runloop->is_menu)
- rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
- else
- rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING);
- break;
- case EVENT_CMD_CONTROLLERS_INIT:
- init_controllers();
- break;
- case EVENT_CMD_RESET:
- RARCH_LOG(RETRO_LOG_RESETTING_CONTENT);
- rarch_main_msg_queue_push("Reset.", 1, 120, true);
- pretro_reset();
-
- /* bSNES since v073r01 resets controllers to JOYPAD
- * after a reset, so just enforce it here. */
- rarch_main_command(EVENT_CMD_CONTROLLERS_INIT);
- break;
- case EVENT_CMD_SAVE_STATE:
- if (settings->savestate_auto_index)
- settings->state_slot++;
-
- main_state(cmd);
- 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->fullpath = '\0';
-
- rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
- global->system.shutdown = false;
- }
- break;
- case EVENT_CMD_UNLOAD_CORE:
- rarch_main_command(EVENT_CMD_PREPARE_DUMMY);
-#ifdef HAVE_DYNAMIC
- libretro_free_system_info(&global->menu.info);
-#endif
- break;
- case EVENT_CMD_QUIT:
- rarch_main_set_state(RARCH_ACTION_STATE_QUIT);
- break;
- case EVENT_CMD_REINIT:
- driver->video_cache_context =
- global->system.hw_render_callback.cache_context;
- driver->video_cache_context_ack = false;
- rarch_main_command(EVENT_CMD_RESET_CONTEXT);
- driver->video_cache_context = false;
-
- /* Poll input to avoid possibly stale data to corrupt things. */
- input_driver_poll();
-
-#ifdef HAVE_MENU
- runloop->frames.video.current.menu.framebuf.dirty = true;
- if (runloop->is_menu)
- rarch_main_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:
- rarch_main_command(EVENT_CMD_CHEATS_DEINIT);
- init_cheats();
- break;
- case EVENT_CMD_REMAPPING_DEINIT:
- break;
- case EVENT_CMD_REMAPPING_INIT:
- rarch_main_command(EVENT_CMD_REMAPPING_DEINIT);
- 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:
- init_rewind();
- break;
- case EVENT_CMD_REWIND_TOGGLE:
- if (settings->rewind_enable)
- rarch_main_command(EVENT_CMD_REWIND_INIT);
- else
- rarch_main_command(EVENT_CMD_REWIND_DEINIT);
- break;
- case EVENT_CMD_AUTOSAVE_DEINIT:
-#ifdef HAVE_THREADS
- deinit_autosave();
-#endif
- break;
- case EVENT_CMD_AUTOSAVE_INIT:
- rarch_main_command(EVENT_CMD_AUTOSAVE_DEINIT);
-#ifdef HAVE_THREADS
- init_autosave();
-#endif
- break;
- case EVENT_CMD_AUTOSAVE_STATE:
- 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 ?
- "Audio muted." : "Audio unmuted.";
-
- if (!audio_driver_mute_toggle())
- {
- RARCH_ERR("Failed to unmute audio.\n");
- 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
- if (driver->overlay)
- input_overlay_free(driver->overlay);
- driver->overlay = NULL;
-
- memset(&driver->overlay_state, 0, sizeof(driver->overlay_state));
-#endif
- break;
- case EVENT_CMD_OVERLAY_INIT:
- rarch_main_command(EVENT_CMD_OVERLAY_DEINIT);
-#ifdef HAVE_OVERLAY
- if (driver->osk_enable)
- {
- if (!*settings->osk.overlay)
- break;
- }
- else
- {
- if (!*settings->input.overlay)
- break;
- }
-
- driver->overlay = input_overlay_new(driver->osk_enable ? settings->osk.overlay : settings->input.overlay,
- driver->osk_enable ? settings->osk.enable : settings->input.overlay_enable,
- settings->input.overlay_opacity, settings->input.overlay_scale);
- if (!driver->overlay)
- RARCH_ERR("Failed to load overlay.\n");
-#endif
- break;
- case EVENT_CMD_OVERLAY_NEXT:
-#ifdef HAVE_OVERLAY
- input_overlay_next(driver->overlay, settings->input.overlay_opacity);
-#endif
- break;
- case EVENT_CMD_DSP_FILTER_DEINIT:
- if (!global)
- break;
-
- if (global->audio_data.dsp)
- rarch_dsp_filter_free(global->audio_data.dsp);
- global->audio_data.dsp = NULL;
- break;
- case EVENT_CMD_DSP_FILTER_INIT:
- rarch_main_command(EVENT_CMD_DSP_FILTER_DEINIT);
- if (!*settings->audio.dsp_plugin)
- break;
-
- global->audio_data.dsp = rarch_dsp_filter_new(
- settings->audio.dsp_plugin, global->audio_data.in_rate);
- if (!global->audio_data.dsp)
- RARCH_ERR("[DSP]: Failed to initialize DSP filter \"%s\".\n",
- 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:
- rarch_main_command(EVENT_CMD_HISTORY_DEINIT);
- if (!recording_init())
- return false;
- break;
- case EVENT_CMD_HISTORY_DEINIT:
- if (g_defaults.history)
- content_playlist_free(g_defaults.history);
- g_defaults.history = NULL;
- break;
- case EVENT_CMD_HISTORY_INIT:
- rarch_main_command(EVENT_CMD_HISTORY_DEINIT);
- if (!settings->history_list_enable)
- return false;
- RARCH_LOG("Loading history file: [%s].\n", 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)
- core_info_list_free(global->core_info);
- global->core_info = NULL;
- break;
- case EVENT_CMD_DATA_RUNLOOP_FREE:
- rarch_main_data_free();
- break;
- case EVENT_CMD_CORE_INFO_INIT:
- rarch_main_command(EVENT_CMD_CORE_INFO_DEINIT);
-
- if (*settings->libretro_directory)
- global->core_info = core_info_list_new(settings->libretro_directory);
- break;
- case EVENT_CMD_CORE_DEINIT:
- deinit_core(true);
- break;
- case EVENT_CMD_CORE_INIT:
- if (!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(driver->overlay,
- settings->input.overlay_scale);
-#endif
- break;
- case EVENT_CMD_OVERLAY_SET_ALPHA_MOD:
-#ifdef HAVE_OVERLAY
- input_overlay_set_alpha_mod(driver->overlay,
- 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:
- rarch_main_command(EVENT_CMD_DRIVERS_DEINIT);
- rarch_main_command(EVENT_CMD_DRIVERS_INIT);
- break;
- case EVENT_CMD_QUIT_RETROARCH:
- rarch_main_set_state(RARCH_ACTION_STATE_FORCE_QUIT);
- break;
- case EVENT_CMD_RESUME:
- rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
- break;
- case EVENT_CMD_RESTART_RETROARCH:
-#if defined(GEKKO) && defined(HW_RVL)
- fill_pathname_join(global->fullpath, g_defaults.core_dir,
- SALAMANDER_FILE,
- sizeof(global->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 (!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:
- if (runloop->is_paused)
- {
- RARCH_LOG("Paused.\n");
- rarch_main_command(EVENT_CMD_AUDIO_STOP);
-
- if (settings->video.black_frame_insertion)
- rarch_render_cached_frame();
- }
- else
- {
- RARCH_LOG("Unpaused.\n");
- rarch_main_command(EVENT_CMD_AUDIO_START);
- }
- break;
- case EVENT_CMD_PAUSE_TOGGLE:
- runloop->is_paused = !runloop->is_paused;
- rarch_main_command(EVENT_CMD_PAUSE_CHECKS);
- break;
- case EVENT_CMD_UNPAUSE:
- runloop->is_paused = false;
- rarch_main_command(EVENT_CMD_PAUSE_CHECKS);
- break;
- case EVENT_CMD_PAUSE:
- runloop->is_paused = true;
- rarch_main_command(EVENT_CMD_PAUSE_CHECKS);
- break;
- case EVENT_CMD_MENU_PAUSE_LIBRETRO:
- if (runloop->is_menu)
- {
- if (settings->menu.pause_libretro)
- rarch_main_command(EVENT_CMD_AUDIO_STOP);
- else
- rarch_main_command(EVENT_CMD_AUDIO_START);
- }
- else
- {
- if (settings->menu.pause_libretro)
- rarch_main_command(EVENT_CMD_AUDIO_START);
- }
- 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:
- rarch_main_command(EVENT_CMD_SHADER_DIR_DEINIT);
-
- if (!*settings->video.shader_dir)
- return false;
-
- global->shader_dir.list = dir_list_new(settings->video.shader_dir,
- "cg|cgp|glsl|glslp", false);
-
- if (!global->shader_dir.list || global->shader_dir.list->size == 0)
- {
- rarch_main_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("Found shader \"%s\"\n",
- global->shader_dir.list->elems[i].data);
- break;
- case EVENT_CMD_SAVEFILES:
- 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->use_sram = global->use_sram && !global->sram_save_disable
-#ifdef HAVE_NETPLAY
- && (!driver->netplay_data || !global->netplay_is_client)
-#endif
- ;
-
- if (!global->use_sram)
- RARCH_LOG("SRAM will not be saved.\n");
-
- if (global->use_sram)
- rarch_main_command(EVENT_CMD_AUTOSAVE_INIT);
- break;
- case EVENT_CMD_MSG_QUEUE_DEINIT:
- rarch_main_msg_queue_free();
- break;
- case EVENT_CMD_MSG_QUEUE_INIT:
- rarch_main_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:
- rarch_main_command(EVENT_CMD_BSV_MOVIE_DEINIT);
- 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:
- rarch_main_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;
- rarch_main_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:
- rarch_main_command(EVENT_CMD_COMMAND_DEINIT);
-
-#ifdef HAVE_COMMAND
- init_command();
-#endif
- break;
- case EVENT_CMD_TEMPORARY_CONTENT_DEINIT:
- if (!global)
- break;
-
- if (global->temporary_content)
- 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)
- fclose(global->log_file);
- global->log_file = NULL;
- break;
- case EVENT_CMD_DISK_EJECT_TOGGLE:
- if (global->system.disk_control.get_num_images)
- {
- const struct retro_disk_control_callback *control =
- (const struct retro_disk_control_callback*)
- &global->system.disk_control;
-
- if (control)
- check_disk_eject(control);
- }
- else
- rarch_main_msg_queue_push("Core does not support Disk Options.", 1, 120, true);
- break;
- case EVENT_CMD_DISK_NEXT:
- if (global->system.disk_control.get_num_images)
- {
- const struct retro_disk_control_callback *control =
- (const struct retro_disk_control_callback*)
- &global->system.disk_control;
-
- if (!control)
- return false;
-
- if (!control->get_eject_state())
- return false;
-
- check_disk_next(control);
- }
- else
- rarch_main_msg_queue_push("Core does not support Disk Options.", 1, 120, true);
- break;
- case EVENT_CMD_DISK_PREV:
- if (global->system.disk_control.get_num_images)
- {
- const struct retro_disk_control_callback *control =
- (const struct retro_disk_control_callback*)
- &global->system.disk_control;
-
- if (!control)
- return false;
-
- if (!control->get_eject_state())
- return false;
-
- check_disk_prev(control);
- }
- else
- rarch_main_msg_queue_push("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("Grab mouse state: %s.\n",
- 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:
- set_volume(0.5f);
- break;
- case EVENT_CMD_VOLUME_DOWN:
- set_volume(-0.5f);
- break;
- }
-
- return true;
-}
-
/**
* rarch_main_deinit:
*
diff --git a/retroarch.h b/retroarch.h
index a448b5a757..60052eb378 100644
--- a/retroarch.h
+++ b/retroarch.h
@@ -208,6 +208,27 @@ int rarch_defer_core(core_info_list_t *data,
const char *dir, const char *path, const char *menu_label,
char *deferred_path, size_t sizeof_deferred_path);
+void rarch_fill_pathnames(void);
+
+/*
+ * rarch_verify_api_version:
+ *
+ * Compare libretro core API version against API version
+ * used by RetroArch.
+ *
+ * TODO - when libretro v2 gets added, allow for switching
+ * between libretro version backend dynamically.
+ **/
+void rarch_verify_api_version(void);
+
+/**
+ * rarch_init_system_av_info:
+ *
+ * Initialize system A/V information by calling the libretro core's
+ * get_system_av_info function.
+ **/
+void rarch_init_system_av_info(void);
+
#ifdef __cplusplus
}
#endif