/* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2016 - Daniel De Matteis * Copyright (C) 2021 - David G.F. * * 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 . */ #ifndef COMMAND_H__ #define COMMAND_H__ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "tasks/task_notify.h" #include "retroarch_types.h" #include "input/input_defines.h" #include "configuration.h" #define MAX_CMD_DRIVERS 4 #define DEFAULT_NETWORK_CMD_PORT 55355 RETRO_BEGIN_DECLS enum event_command { CMD_SPECIAL = -1, CMD_EVENT_NONE = 0, /* Resets RetroArch. */ CMD_EVENT_RESET, CMD_EVENT_SET_PER_GAME_RESOLUTION, CMD_EVENT_SET_FRAME_LIMIT, /* Loads core. */ CMD_EVENT_LOAD_CORE, CMD_EVENT_LOAD_CORE_PERSIST, #if defined(HAVE_RUNAHEAD) && (defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB)) CMD_EVENT_LOAD_SECOND_CORE, #endif CMD_EVENT_UNLOAD_CORE, /* Closes content. */ CMD_EVENT_CLOSE_CONTENT, /* Swaps the current state with what's on the undo load buffer. */ CMD_EVENT_UNDO_LOAD_STATE, /* Rewrites a savestate on disk. */ CMD_EVENT_UNDO_SAVE_STATE, /* Save state hotkeys. */ CMD_EVENT_LOAD_STATE, CMD_EVENT_SAVE_STATE, CMD_EVENT_SAVE_STATE_DECREMENT, CMD_EVENT_SAVE_STATE_INCREMENT, /* Replay hotkeys. RECORD_REPLAY and the checkpoint events take a * task_notify_t, told when their work is through, or NULL. */ CMD_EVENT_PLAY_REPLAY, CMD_EVENT_RECORD_REPLAY, CMD_EVENT_HALT_REPLAY, CMD_EVENT_SAVE_REPLAY_CHECKPOINT, CMD_EVENT_PREV_REPLAY_CHECKPOINT, CMD_EVENT_NEXT_REPLAY_CHECKPOINT, CMD_EVENT_REPLAY_DECREMENT, CMD_EVENT_REPLAY_INCREMENT, /* Save state actions. */ CMD_EVENT_SAVE_STATE_TO_RAM, CMD_EVENT_LOAD_STATE_FROM_RAM, CMD_EVENT_RAM_STATE_TO_FILE, /* Takes screenshot. */ CMD_EVENT_TAKE_SCREENSHOT, /* Quits RetroArch. */ CMD_EVENT_QUIT, /* Reinitialize all drivers. */ CMD_EVENT_REINIT_FROM_TOGGLE, /* Re-evaluate the on-screen notification (gfx_widgets) system to * match current settings, without a full driver reinit. */ CMD_EVENT_OSD_NOTIFICATION_TOGGLE, /* Reinitialize all drivers. */ CMD_EVENT_REINIT, /* Toggles cheevos hardcore mode. */ CMD_EVENT_CHEEVOS_HARDCORE_MODE_TOGGLE, /* Deinitialize rewind. */ CMD_EVENT_REWIND_DEINIT, /* Initializes rewind. */ CMD_EVENT_REWIND_INIT, /* Reinitializes rewind (primarily if the state size changes). */ CMD_EVENT_REWIND_REINIT, /* Toggles rewind. */ CMD_EVENT_REWIND_TOGGLE, /* Initializes autosave. */ CMD_EVENT_AUTOSAVE_INIT, /* Stops audio. */ CMD_EVENT_AUDIO_STOP, /* Starts audio. */ CMD_EVENT_AUDIO_START, /* Mutes audio. */ CMD_EVENT_AUDIO_MUTE_TOGGLE, /* Volume adjustments. */ CMD_EVENT_VOLUME_UP, CMD_EVENT_VOLUME_DOWN, CMD_EVENT_MIXER_VOLUME_UP, CMD_EVENT_MIXER_VOLUME_DOWN, /* Toggles Video Filter*/ CMD_VIDEO_FILTER_TOGGLE, /* Toggles FPS counter. */ CMD_EVENT_FPS_TOGGLE, /* Toggles statistics display. */ CMD_EVENT_STATISTICS_TOGGLE, /* Initializes video filter. */ CMD_EVENT_VIDEO_FILTER_INIT, /* Initializes overlay. */ CMD_EVENT_OVERLAY_INIT, /* Frees or caches overlay. */ CMD_EVENT_OVERLAY_UNLOAD, /* Sets current scale factor for overlay. */ CMD_EVENT_OVERLAY_SET_SCALE_FACTOR, /* Sets current alpha modulation for overlay. */ CMD_EVENT_OVERLAY_SET_ALPHA_MOD, /* Sets diagonal sensitivities of overlay eightway areas. */ CMD_EVENT_OVERLAY_SET_EIGHTWAY_DIAGONAL_SENSITIVITY, /* Deinitializes overlay. */ CMD_EVENT_DSP_FILTER_INIT, /* Initializes recording system. */ CMD_EVENT_RECORD_INIT, /* Deinitializes recording system. */ CMD_EVENT_RECORD_DEINIT, /* Deinitializes history playlist. */ CMD_EVENT_HISTORY_DEINIT, /* Initializes history playlist. */ CMD_EVENT_HISTORY_INIT, /* Deinitializes core information. */ CMD_EVENT_CORE_INFO_DEINIT, /* Initializes core information. */ CMD_EVENT_CORE_INFO_INIT, /* Deinitializes core. */ CMD_EVENT_CORE_DEINIT, /* Initializes core. */ CMD_EVENT_CORE_INIT, /* Apply video state changes. */ CMD_EVENT_VIDEO_APPLY_STATE_CHANGES, /* Set video blocking state. */ CMD_EVENT_VIDEO_SET_BLOCKING_STATE, /* Sets current aspect ratio index. */ CMD_EVENT_VIDEO_SET_ASPECT_RATIO, /* Restarts RetroArch. */ CMD_EVENT_RESTART_RETROARCH, #ifdef HAVE_CLOUDSYNC /* Trigger cloud sync */ CMD_EVENT_CLOUD_SYNC, /* Resolve cloud sync conflicts by keeping local files */ CMD_EVENT_CLOUD_SYNC_RESOLVE_KEEP_LOCAL, /* Resolve cloud sync conflicts by keeping server files */ CMD_EVENT_CLOUD_SYNC_RESOLVE_KEEP_SERVER, #endif /* Shutdown the OS */ CMD_EVENT_SHUTDOWN, /* Reboot the OS */ CMD_EVENT_REBOOT, /* Resume RetroArch when in menu. */ CMD_EVENT_RESUME, /* Add a playlist entry to favorites. */ CMD_EVENT_ADD_TO_FAVORITES, /* Reset playlist entry associated core to DETECT */ CMD_EVENT_RESET_CORE_ASSOCIATION, /* Toggles pause. */ CMD_EVENT_PAUSE_TOGGLE, /* Pauses RetroArch. */ CMD_EVENT_MENU_PAUSE_LIBRETRO, CMD_EVENT_PAUSE, /* Unpauses RetroArch. */ CMD_EVENT_UNPAUSE, /* Toggles menu on/off. */ CMD_EVENT_MENU_TOGGLE, /* Configuration saving. */ CMD_EVENT_MENU_RESET_TO_DEFAULT_CONFIG, CMD_EVENT_MENU_SAVE_CONFIG, /* Starts the first-run asset downloads. */ CMD_EVENT_MENU_FIRST_RUN_DOWNLOAD, CMD_EVENT_MENU_SAVE_AS_CONFIG, CMD_EVENT_MENU_SAVE_MAIN_CONFIG, CMD_EVENT_MENU_SAVE_CURRENT_CONFIG, CMD_EVENT_MENU_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, CMD_EVENT_MENU_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, CMD_EVENT_MENU_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, CMD_EVENT_MENU_REMOVE_CURRENT_CONFIG_OVERRIDE_CORE, CMD_EVENT_MENU_REMOVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR, CMD_EVENT_MENU_REMOVE_CURRENT_CONFIG_OVERRIDE_GAME, /* Applies shader changes. */ CMD_EVENT_SHADERS_APPLY_CHANGES, /* A new shader preset has been loaded */ CMD_EVENT_SHADER_PRESET_LOADED, /* Shader hotkeys. */ CMD_EVENT_SHADER_NEXT, CMD_EVENT_SHADER_PREV, CMD_EVENT_SHADER_TOGGLE, /* Apply cheats. */ CMD_EVENT_CHEATS_APPLY, /* The codec compressed saves are written with, from the setting. */ CMD_EVENT_SAVE_COMPRESSION_CODEC_APPLY, /* Cheat hotkeys. */ CMD_EVENT_CHEAT_TOGGLE, CMD_EVENT_CHEAT_INDEX_PLUS, CMD_EVENT_CHEAT_INDEX_MINUS, /* Initializes network system. */ CMD_EVENT_NETWORK_INIT, /* Initializes netplay system with a string or no host specified. */ CMD_EVENT_NETPLAY_INIT, /* Initializes netplay system with a direct host specified. */ CMD_EVENT_NETPLAY_INIT_DIRECT, /* Initializes netplay system with a direct host specified after loading content. */ CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED, /* Deinitializes netplay system. */ CMD_EVENT_NETPLAY_DEINIT, /* Switch between netplay gaming and watching. */ CMD_EVENT_NETPLAY_GAME_WATCH, /* Open a netplay chat input menu. */ CMD_EVENT_NETPLAY_PLAYER_CHAT, /* Toggle chat fading. */ CMD_EVENT_NETPLAY_FADE_CHAT_TOGGLE, /* Start hosting netplay. */ CMD_EVENT_NETPLAY_ENABLE_HOST, /* Disconnect from the netplay host. */ CMD_EVENT_NETPLAY_DISCONNECT, /* Toggle ping counter. */ CMD_EVENT_NETPLAY_PING_TOGGLE, /* Toggles netplay hosting. */ CMD_EVENT_NETPLAY_HOST_TOGGLE, /* Reinitializes audio driver. */ CMD_EVENT_AUDIO_REINIT, /* Resizes the window to the queued scale. */ CMD_EVENT_RESIZE_WINDOWED_SCALE, /* Applies the configured windowed scale. */ CMD_EVENT_APPLY_WINDOWED_SCALE, /* Toggles disk eject. */ CMD_EVENT_DISK_EJECT_TOGGLE, /* Cycle to next disk. */ CMD_EVENT_DISK_NEXT, /* Cycle to previous disk. */ CMD_EVENT_DISK_PREV, /* Switch to specified disk index */ CMD_EVENT_DISK_INDEX, /* Appends disk image to disk image list. */ CMD_EVENT_DISK_APPEND_IMAGE, /* Stops rumbling. */ CMD_EVENT_RUMBLE_STOP, /* Toggles turbo fire. */ CMD_EVENT_TURBO_FIRE_TOGGLE, /* Toggles mouse grab. */ CMD_EVENT_GRAB_MOUSE_TOGGLE, /* Toggles game focus. */ CMD_EVENT_GAME_FOCUS_TOGGLE, /* Toggles desktop menu. */ CMD_EVENT_UI_COMPANION_TOGGLE, /* Toggles fullscreen mode. */ CMD_EVENT_FULLSCREEN_TOGGLE, CMD_EVENT_FULLSCREEN_APPLY, /* Toggle recording. */ CMD_EVENT_RECORDING_TOGGLE, /* Toggle streaming. */ CMD_EVENT_STREAMING_TOGGLE, /* Toggle Run-Ahead. */ CMD_EVENT_RUNAHEAD_TOGGLE, /* Toggle Preemtive Frames. */ CMD_EVENT_PREEMPT_TOGGLE, /* Deinitialize or Reinitialize Preemptive Frames. */ CMD_EVENT_PREEMPT_UPDATE, /* Force Preemptive Frames to refill its state buffer. */ CMD_EVENT_PREEMPT_RESET_BUFFER, /* Toggle VRR runloop. */ CMD_EVENT_VRR_RUNLOOP_TOGGLE, /* Place the headset's screens in front of where it looks now. */ CMD_EVENT_HEADSET_RECENTER, /* Switch the headset's Laser Pointer between Off and its last mode. */ CMD_EVENT_LASER_POINTER_TOGGLE, /* Cycle what a core is told the headset displays: immersive, stereoscopic, flat. */ CMD_EVENT_HEADSET_VIEW_TOGGLE, /* Start or stop moving the headset's screens with its controllers. */ CMD_EVENT_HEADSET_EDIT_SCREENS, /* AI service. */ CMD_EVENT_AI_SERVICE_TOGGLE, CMD_EVENT_AI_SERVICE_CALL, /* Misc. */ CMD_EVENT_SAVE_FILES, CMD_EVENT_LOAD_FILES, CMD_EVENT_CONTROLLER_INIT, CMD_EVENT_DISCORD_INIT, CMD_EVENT_PRESENCE_UPDATE, /* camera_allow changed: a running camera the user just disallowed * is stopped here, so the frame path tests only its frame_work bit */ CMD_EVENT_CAMERA_ALLOW_APPLY, CMD_EVENT_OVERLAY_NEXT, CMD_EVENT_OSK_TOGGLE, CMD_EVENT_RELOAD_CONFIG, #ifdef HAVE_MICROPHONE /* Stops all enabled microphones. */ CMD_EVENT_MICROPHONE_STOP, /* Starts all enabled microphones */ CMD_EVENT_MICROPHONE_START, /* Reinitializes microphone driver. */ CMD_EVENT_MICROPHONE_REINIT, #endif /* Add a playlist entry to another playlist. */ CMD_EVENT_ADD_TO_PLAYLIST }; enum cmd_source_t { CMD_NONE = 0, CMD_STDIN, CMD_NETWORK }; /* What a command does, for interfaces that describe the commands to a * client: HELP, and tool annotations for clients that ask before they * run anything. */ enum cmd_info_flags { /* Only reports; changes nothing. */ CMD_INFO_READ_ONLY = (1 << 0), /* May lose unsaved progress or data, or loads code from a path: * quits, resets, loads or overwrites states and saves, writes core * memory, loads or unloads cores and content. */ CMD_INFO_DESTRUCTIVE = (1 << 1), /* A line command that is not offered as a tool: another command * covers it or takes its value outright, or it steps a selection * nothing reports. It stays a command on every line interface. */ CMD_INFO_NO_TOOL = (1 << 2) }; /* A hotkey command: sending it presses the hotkey for one frame. */ struct cmd_map { const char *str; unsigned id; const char *desc; unsigned flags; /* enum cmd_info_flags */ }; struct command_handler; typedef void (*command_poller_t)(struct command_handler *cmd); typedef void (*command_replier_t)(struct command_handler *cmd, const char * data, size_t len); typedef void (*command_destructor_t)(struct command_handler *cmd); typedef void *(*command_reply_dest_t)(struct command_handler *cmd); typedef void (*command_reply_to_t)(struct command_handler *cmd, void *dest, const char *data, size_t len); /* As reply_to, with an image alongside the text: @image is base64 of * @mime */ typedef void (*command_reply_image_to_t)(struct command_handler *cmd, void *dest, const char *text, size_t len, const char *mime, const char *image, size_t image_len); struct command_handler { /* Interface to poll the driver */ command_poller_t poll; /* Interface to reply */ command_replier_t replier; /* Where the reply to the command being handled goes, for a reply * sent after the handler has returned: a heap copy, released with * free(). NULL on an interface whose replies all go one way. */ command_reply_dest_t reply_dest; /* Sends to a destination reply_dest returned. */ command_reply_to_t reply_to; /* Sends a reply carrying an image, where the interface can; NULL on * the others, which are sent the text alone */ command_reply_image_to_t reply_image_to; /* Interface to delete the underlying command */ command_destructor_t destroy; /* Underlying command storage */ void *userptr; /* State received */ bool state[RARCH_BIND_LIST_END]; /* Requests are structured (MCP), not lines: given the replies a * line-based client never had */ bool structured; /* The reply being sent reports a failure, for the interface sending * it to read: what a line client reads as text a structured one is * told outright. Set beside the reply by whatever answers - a * command, a deferred reply, command_reply_error() - and cleared * when a command starts and once the reply is away. */ bool error; }; typedef struct command_handler command_t; typedef struct command_handle { command_t *handle; unsigned id; } command_handle_t; struct rarch_state; /** * command_event: * @cmd : Command index. * * Performs RetroArch command with index @cmd. * * Returns: true (1) on success, otherwise false (0). **/ bool command_event(enum event_command action, void *data); /* @action, with @arg (or NULL) as its int argument, carried out on the * main thread when it next retires finished tasks: for a thread that * is not the main one - the video thread - asking for what only the * main thread may do, such as starting the drivers again. Callable * from any thread. False if it could not be asked for. */ bool command_event_later(enum event_command action, const int *arg); /* Constructors for the supported drivers */ #ifdef HAVE_NETWORK_CMD /* bind_address may be NULL or empty to listen on every interface, or an * IPv4 address such as "127.0.0.1" to restrict the interface to it. */ command_t* command_network_new(uint16_t port, const char *bind_address); bool command_network_send(const char *cmd_); #endif #ifdef HAVE_STDIN_CMD command_t* command_stdin_new(void); #endif #ifdef HAVE_LAKKA command_t* command_uds_new(void); #endif #ifdef __EMSCRIPTEN__ command_t* command_emscripten_new(void); #endif void command_event_set_mixer_volume( settings_t *settings, float gain); bool command_event_resize_windowed_scale(settings_t *settings, unsigned window_scale); size_t command_event_save_auto_state(void); /** * event_set_volume: * @gain : amount of gain to be applied to current volume level. * * Adjusts the current audio volume level. * **/ void command_event_set_volume( settings_t *settings, float gain, bool widgets_active, bool audio_driver_mute_enable); /** * command_event_init_controllers: * * Initialize libretro controllers. **/ void command_event_init_controllers(rarch_system_info_t *info, settings_t *settings, unsigned num_active_users); bool command_event_load_entry_state(settings_t *settings); bool command_event_load_auto_state(void); void command_event_set_savestate_auto_index( settings_t *settings); int command_event_get_next_savestate_auto_index( settings_t *settings); void command_event_set_replay_auto_index( settings_t *settings); void command_event_set_replay_garbage_collect( unsigned max_to_keep, bool show_hidden_files ); #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) bool command_set_shader(command_t *cmd, const char *arg); #endif #ifdef HAVE_CHEATS void command_event_init_cheats( bool apply_cheats_after_load, const char *path_cheat_db, void *bsv_movie_data); #endif #if defined(HAVE_COMMAND) enum cmd_param_type { /* text, as the command takes it */ CMD_PARAM_STRING = 0, /* a whole number; a structured client sends a JSON number */ CMD_PARAM_INT }; /* One of a command's parameters, for interfaces that take a request * apart rather than a line: a tool schema is generated from these, and * what a client sends by name is put back together into the line the * handlers read. * * A space joins them in that line, and nothing precedes the first, so * @lead is only for a command whose own form uses something else - * LOAD_CONTENT's "|" - and a command's grammar is described here * instead of being parsed by hand at both ends. @values, where set, is the "|"-separated set the * parameter accepts, which the schema offers as an enum. * * @def stands in for an optional parameter the client left out, so the * line form says it rather than leaving the handler to guess: what * GET_PLAYLIST reads as a trailing entry number cannot be told from a * playlist whose name ends in one, and a default settles it. * * An array of these ends with a row whose @name is NULL. */ struct cmd_param { const char *name; const char *desc; enum cmd_param_type type; bool required; const char *lead; const char *values; const char *def; }; /* One column of a reply that is rows: the name a field on the line is * given by an interface that answers in fields rather than in text. */ struct cmd_column { const char *name; const char *desc; }; /* A line among a reply's rows that is not one of them: a word, and a * number ending the line. "MORE 200" says a list was cut short and where to * resume, "NEXT 48" where GET_LOG reached, "SKIPPED 12" how many log * lines were gone before the first it could give. * * @flag is a field the word alone sets true, for a word that can come * without a number - a bare "MORE", from a reply with no resume point. * @name is the field its number is answered as. Either may be NULL. * @first is a word that opens the reply instead of closing it. @text * makes the rest of the line, on whichever line it comes, the field's * text: "MESSAGE Press again to quit" rather than a number. */ struct cmd_trailer { const char *word; const char *flag; const char *name; const char *desc; bool first; bool text; }; /* The shape of a reply that is rows of named columns - the lines of * tab-separated fields the lists and GET_PLAYLIST answer with - so an * interface can hand a client the same reply taken apart rather than * leaving every client to split the text. * * @slack is the one column whose field may hold a tab itself, a game's * name among them: the columns before it are read from the start of the * line and those after it from the end, so that tab takes the slack * instead of shifting the row. * * A line the command opens with its own name - "LIST_CORES none", * "GET_PLAYLIST ERROR ..." - is not a row, and neither is one of * @trailers, which may be that same line: "RUN_FRAMES 3". * * @required is how many of the columns every row has, where a reply * ends short of them: GET_CORE_OPTION gives an option's key, value and * description, and the values it takes only when asked for that option * by key. Zero means every column, which is what the rest answer. * * @columns ends with a row whose @name is NULL, @trailers - when there * are any - with one whose @word is. @columns itself is NULL for a * reply whose lines are prose and whose trailers are all a client * wants: GET_LOG's answer is the log, and the line it reached. */ struct cmd_rows { const struct cmd_column *columns; const struct cmd_trailer *trailers; unsigned slack; unsigned required; /* Set, the reply is one record rather than rows: the line the * command opens with its own name, split into @columns by these * characters in turn - the last column takes what is left - and * answered as fields of their own. */ const char *seps; /* The reply may carry a "PREVIOUS ..." line: how a queued STEPS no * reply has told of ended. */ bool previous; }; /* A command with its own handler; @arg_desc names the argument, or * "No argument", and @params describes it for a structured client, or * is NULL on one that takes none. @rows is the shape of its reply where * that reply is rows, and NULL where it is prose. */ struct cmd_action_map { const char *str; bool (*action)(command_t* cmd, const char *arg); const char *arg_desc; const char *desc; unsigned flags; /* enum cmd_info_flags */ const struct cmd_param *params; const struct cmd_rows *rows; }; #if defined(HAVE_SCREENSHOTS) && defined(HAVE_RPNG) /* GET_FRAME [size]: the frame on screen, as image content where the * interface carries one; a PNG, built in memory */ #define COMMAND_FRAME_SIZE 320 #define COMMAND_FRAME_SIZE_MIN 64 #define COMMAND_FRAME_SIZE_MAX 640 bool command_get_frame(command_t *cmd, const char *arg); #endif /* GET_OPTION [option] / SET_OPTION