1 /*  RetroArch - A frontend for libretro.
2  *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3  *  Copyright (C) 2011-2016 - Daniel De Matteis
4  *  Copyright (C) 2021      - David G.F.
5  *
6  *  RetroArch is free software: you can redistribute it and/or modify it under the terms
7  *  of the GNU General Public License as published by the Free Software Found-
8  *  ation, either version 3 of the License, or (at your option) any later version.
9  *
10  *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  *  PURPOSE.  See the GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along with RetroArch.
15  *  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef COMMAND_H__
19 #define COMMAND_H__
20 
21 #include <stdint.h>
22 
23 #include <boolean.h>
24 #include <retro_common_api.h>
25 
26 #include "retroarch.h"
27 #include "input/input_defines.h"
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 RETRO_BEGIN_DECLS
34 
35 #define MAX_CMD_DRIVERS              3
36 #define DEFAULT_NETWORK_CMD_PORT 55355
37 
38 struct cmd_map
39 {
40    const char *str;
41    unsigned id;
42 };
43 
44 struct command_handler;
45 
46 typedef void (*command_poller_t)(struct command_handler *cmd);
47 typedef void (*command_replier_t)(struct command_handler *cmd, const char * data, size_t len);
48 typedef void (*command_destructor_t)(struct command_handler *cmd);
49 
50 struct command_handler
51 {
52    /* Interface to poll the driver */
53    command_poller_t poll;
54    /* Interface to reply */
55    command_replier_t replier;
56    /* Interface to delete the underlying command */
57    command_destructor_t destroy;
58    /* Underlying command storage */
59    void *userptr;
60    /* State received */
61    bool state[RARCH_BIND_LIST_END];
62 };
63 
64 typedef struct command_handler command_t;
65 
66 enum event_command
67 {
68    CMD_EVENT_NONE = 0,
69    /* Resets RetroArch. */
70    CMD_EVENT_RESET,
71    CMD_EVENT_SET_PER_GAME_RESOLUTION,
72    CMD_EVENT_SET_FRAME_LIMIT,
73    /* Loads core. */
74    CMD_EVENT_LOAD_CORE,
75    CMD_EVENT_LOAD_CORE_PERSIST,
76    CMD_EVENT_UNLOAD_CORE,
77    CMD_EVENT_CLOSE_CONTENT,
78    CMD_EVENT_LOAD_STATE,
79    /* Swaps the current state with what's on the undo load buffer */
80    CMD_EVENT_UNDO_LOAD_STATE,
81    /* Rewrites a savestate on disk */
82    CMD_EVENT_UNDO_SAVE_STATE,
83    CMD_EVENT_SAVE_STATE,
84    CMD_EVENT_SAVE_STATE_DECREMENT,
85    CMD_EVENT_SAVE_STATE_INCREMENT,
86    /* Takes screenshot. */
87    CMD_EVENT_TAKE_SCREENSHOT,
88    /* Quits RetroArch. */
89    CMD_EVENT_QUIT,
90    /* Reinitialize all drivers. */
91    CMD_EVENT_REINIT_FROM_TOGGLE,
92    /* Reinitialize all drivers. */
93    CMD_EVENT_REINIT,
94    /* Toggles cheevos hardcore mode. */
95    CMD_EVENT_CHEEVOS_HARDCORE_MODE_TOGGLE,
96    /* Deinitialize rewind. */
97    CMD_EVENT_REWIND_DEINIT,
98    /* Initializes rewind. */
99    CMD_EVENT_REWIND_INIT,
100    /* Toggles rewind. */
101    CMD_EVENT_REWIND_TOGGLE,
102    /* Initializes autosave. */
103    CMD_EVENT_AUTOSAVE_INIT,
104    /* Stops audio. */
105    CMD_EVENT_AUDIO_STOP,
106    /* Starts audio. */
107    CMD_EVENT_AUDIO_START,
108    /* Mutes audio. */
109    CMD_EVENT_AUDIO_MUTE_TOGGLE,
110    /* Toggles FPS counter. */
111    CMD_EVENT_FPS_TOGGLE,
112    /* Gathers diagnostic info about the system and RetroArch configuration, then sends it to our servers. */
113    CMD_EVENT_SEND_DEBUG_INFO,
114    /* Toggles netplay hosting. */
115    CMD_EVENT_NETPLAY_HOST_TOGGLE,
116    /* Initializes overlay. */
117    CMD_EVENT_OVERLAY_INIT,
118    /* Deinitializes overlay. */
119    CMD_EVENT_OVERLAY_DEINIT,
120    /* Sets current scale factor for overlay. */
121    CMD_EVENT_OVERLAY_SET_SCALE_FACTOR,
122    /* Sets current alpha modulation for overlay. */
123    CMD_EVENT_OVERLAY_SET_ALPHA_MOD,
124    /* Cycle to next overlay. */
125    CMD_EVENT_OVERLAY_NEXT,
126    /* Deinitializes overlay. */
127    CMD_EVENT_DSP_FILTER_INIT,
128    /* Initializes recording system. */
129    CMD_EVENT_RECORD_INIT,
130    /* Deinitializes recording system. */
131    CMD_EVENT_RECORD_DEINIT,
132    /* Deinitializes history playlist. */
133    CMD_EVENT_HISTORY_DEINIT,
134    /* Initializes history playlist. */
135    CMD_EVENT_HISTORY_INIT,
136    /* Deinitializes core information. */
137    CMD_EVENT_CORE_INFO_DEINIT,
138    /* Initializes core information. */
139    CMD_EVENT_CORE_INFO_INIT,
140    /* Deinitializes core. */
141    CMD_EVENT_CORE_DEINIT,
142    /* Initializes core. */
143    CMD_EVENT_CORE_INIT,
144    /* Apply video state changes. */
145    CMD_EVENT_VIDEO_APPLY_STATE_CHANGES,
146    /* Set video blocking state. */
147    CMD_EVENT_VIDEO_SET_BLOCKING_STATE,
148    /* Sets current aspect ratio index. */
149    CMD_EVENT_VIDEO_SET_ASPECT_RATIO,
150    /* Restarts RetroArch. */
151    CMD_EVENT_RESTART_RETROARCH,
152    /* Shutdown the OS */
153    CMD_EVENT_SHUTDOWN,
154    /* Reboot the OS */
155    CMD_EVENT_REBOOT,
156    /* Resume RetroArch when in menu. */
157    CMD_EVENT_RESUME,
158    /* Add a playlist entry to favorites. */
159    CMD_EVENT_ADD_TO_FAVORITES,
160    /* Reset playlist entry associated core to DETECT */
161    CMD_EVENT_RESET_CORE_ASSOCIATION,
162    /* Toggles pause. */
163    CMD_EVENT_PAUSE_TOGGLE,
164    /* Pauses RetroArch. */
165    CMD_EVENT_UNPAUSE,
166    /* Unpauses retroArch. */
167    CMD_EVENT_PAUSE,
168    CMD_EVENT_MENU_RESET_TO_DEFAULT_CONFIG,
169    CMD_EVENT_MENU_SAVE_CURRENT_CONFIG,
170    CMD_EVENT_MENU_SAVE_CURRENT_CONFIG_OVERRIDE_CORE,
171    CMD_EVENT_MENU_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR,
172    CMD_EVENT_MENU_SAVE_CURRENT_CONFIG_OVERRIDE_GAME,
173    CMD_EVENT_MENU_SAVE_CONFIG,
174    CMD_EVENT_MENU_PAUSE_LIBRETRO,
175    /* Toggles menu on/off. */
176    CMD_EVENT_MENU_TOGGLE,
177    /* Applies shader changes. */
178    CMD_EVENT_SHADERS_APPLY_CHANGES,
179    /* A new shader preset has been loaded */
180    CMD_EVENT_SHADER_PRESET_LOADED,
181    /* Apply cheats. */
182    CMD_EVENT_CHEATS_APPLY,
183    /* Initializes network system. */
184    CMD_EVENT_NETWORK_INIT,
185    /* Initializes netplay system with a string or no host specified. */
186    CMD_EVENT_NETPLAY_INIT,
187    /* Initializes netplay system with a direct host specified. */
188    CMD_EVENT_NETPLAY_INIT_DIRECT,
189    /* Initializes netplay system with a direct host specified after loading content. */
190    CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
191    /* Deinitializes netplay system. */
192    CMD_EVENT_NETPLAY_DEINIT,
193    /* Switch between netplay gaming and watching. */
194    CMD_EVENT_NETPLAY_GAME_WATCH,
195    /* Start hosting netplay. */
196    CMD_EVENT_NETPLAY_ENABLE_HOST,
197    /* Disconnect from the netplay host. */
198    CMD_EVENT_NETPLAY_DISCONNECT,
199    /* Reinitializes audio driver. */
200    CMD_EVENT_AUDIO_REINIT,
201    /* Resizes windowed scale. Will reinitialize video driver. */
202    CMD_EVENT_RESIZE_WINDOWED_SCALE,
203    /* Toggles disk eject. */
204    CMD_EVENT_DISK_EJECT_TOGGLE,
205    /* Cycle to next disk. */
206    CMD_EVENT_DISK_NEXT,
207    /* Cycle to previous disk. */
208    CMD_EVENT_DISK_PREV,
209    /* Switch to specified disk index */
210    CMD_EVENT_DISK_INDEX,
211    /* Appends disk image to disk image list. */
212    CMD_EVENT_DISK_APPEND_IMAGE,
213    /* Stops rumbling. */
214    CMD_EVENT_RUMBLE_STOP,
215    /* Toggles mouse grab. */
216    CMD_EVENT_GRAB_MOUSE_TOGGLE,
217    /* Toggles game focus. */
218    CMD_EVENT_GAME_FOCUS_TOGGLE,
219    /* Toggles desktop menu. */
220    CMD_EVENT_UI_COMPANION_TOGGLE,
221    /* Toggles fullscreen mode. */
222    CMD_EVENT_FULLSCREEN_TOGGLE,
223    CMD_EVENT_VOLUME_UP,
224    CMD_EVENT_VOLUME_DOWN,
225    CMD_EVENT_MIXER_VOLUME_UP,
226    CMD_EVENT_MIXER_VOLUME_DOWN,
227    CMD_EVENT_DISCORD_INIT,
228    CMD_EVENT_DISCORD_UPDATE,
229    CMD_EVENT_OSK_TOGGLE,
230    CMD_EVENT_RECORDING_TOGGLE,
231    CMD_EVENT_STREAMING_TOGGLE,
232    CMD_EVENT_RUNAHEAD_TOGGLE,
233    CMD_EVENT_AI_SERVICE_TOGGLE,
234    CMD_EVENT_BSV_RECORDING_TOGGLE,
235    CMD_EVENT_SHADER_NEXT,
236    CMD_EVENT_SHADER_PREV,
237    CMD_EVENT_CHEAT_INDEX_PLUS,
238    CMD_EVENT_CHEAT_INDEX_MINUS,
239    CMD_EVENT_CHEAT_TOGGLE,
240    CMD_EVENT_AI_SERVICE_CALL,
241    CMD_EVENT_SAVE_FILES,
242    CMD_EVENT_CONTROLLER_INIT
243 };
244 
245 typedef struct command_handle
246 {
247    command_t *handle;
248    unsigned id;
249 } command_handle_t;
250 
251 enum cmd_source_t
252 {
253    CMD_NONE = 0,
254    CMD_STDIN,
255    CMD_NETWORK
256 };
257 
258 struct rarch_state;
259 
260 /**
261  * command_event:
262  * @cmd                  : Command index.
263  *
264  * Performs RetroArch command with index @cmd.
265  *
266  * Returns: true (1) on success, otherwise false (0).
267  **/
268 bool command_event(enum event_command action, void *data);
269 
270 /* Constructors for the supported drivers */
271 command_t* command_network_new(uint16_t port);
272 command_t* command_stdin_new(void);
273 command_t* command_uds_new(void);
274 
275 bool command_network_send(const char *cmd_);
276 
277 /* These forward declarations need to be declared before
278  * the global state is declared */
279 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
280 bool command_set_shader(command_t *cmd, const char *arg);
281 #endif
282 #if defined(HAVE_COMMAND)
283 bool command_version(command_t *cmd, const char* arg);
284 bool command_get_status(command_t *cmd, const char* arg);
285 bool command_get_config_param(command_t *cmd, const char* arg);
286 bool command_show_osd_msg(command_t *cmd, const char* arg);
287 #ifdef HAVE_CHEEVOS
288 bool command_read_ram(command_t *cmd, const char *arg);
289 bool command_write_ram(command_t *cmd, const char *arg);
290 #endif
291 bool command_read_memory(command_t *cmd, const char *arg);
292 bool command_write_memory(command_t *cmd, const char *arg);
293 
294 struct cmd_action_map
295 {
296    const char *str;
297    bool (*action)(command_t* cmd, const char *arg);
298    const char *arg_desc;
299 };
300 
301 static const struct cmd_action_map action_map[] = {
302 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
303    { "SET_SHADER",       command_set_shader,       "<shader path>" },
304 #endif
305    { "VERSION",          command_version,          "No argument"},
306    { "GET_STATUS",       command_get_status,       "No argument" },
307    { "GET_CONFIG_PARAM", command_get_config_param, "<param name>" },
308    { "SHOW_MSG",         command_show_osd_msg,     "No argument" },
309 #if defined(HAVE_CHEEVOS)
310    /* These functions use achievement addresses and only work if a game with achievements is
311     * loaded. READ_CORE_MEMORY and WRITE_CORE_MEMORY are preferred and use system addresses. */
312    { "READ_CORE_RAM",    command_read_ram,         "<address> <number of bytes>" },
313    { "WRITE_CORE_RAM",   command_write_ram,        "<address> <byte1> <byte2> ..." },
314 #endif
315    { "READ_CORE_MEMORY", command_read_memory,      "<address> <number of bytes>" },
316    { "WRITE_CORE_MEMORY",command_write_memory,     "<address> <byte1> <byte2> ..." },
317 };
318 
319 static const struct cmd_map map[] = {
320    { "FAST_FORWARD",           RARCH_FAST_FORWARD_KEY },
321    { "FAST_FORWARD_HOLD",      RARCH_FAST_FORWARD_HOLD_KEY },
322    { "SLOWMOTION",             RARCH_SLOWMOTION_KEY },
323    { "SLOWMOTION_HOLD",        RARCH_SLOWMOTION_HOLD_KEY },
324    { "LOAD_STATE",             RARCH_LOAD_STATE_KEY },
325    { "SAVE_STATE",             RARCH_SAVE_STATE_KEY },
326    { "FULLSCREEN_TOGGLE",      RARCH_FULLSCREEN_TOGGLE_KEY },
327    { "CLOSE_CONTENT",          RARCH_CLOSE_CONTENT_KEY },
328    { "QUIT",                   RARCH_QUIT_KEY },
329    { "STATE_SLOT_PLUS",        RARCH_STATE_SLOT_PLUS },
330    { "STATE_SLOT_MINUS",       RARCH_STATE_SLOT_MINUS },
331    { "REWIND",                 RARCH_REWIND },
332    { "BSV_RECORD_TOGGLE",      RARCH_BSV_RECORD_TOGGLE },
333    { "PAUSE_TOGGLE",           RARCH_PAUSE_TOGGLE },
334    { "FRAMEADVANCE",           RARCH_FRAMEADVANCE },
335    { "RESET",                  RARCH_RESET },
336    { "SHADER_NEXT",            RARCH_SHADER_NEXT },
337    { "SHADER_PREV",            RARCH_SHADER_PREV },
338    { "CHEAT_INDEX_PLUS",       RARCH_CHEAT_INDEX_PLUS },
339    { "CHEAT_INDEX_MINUS",      RARCH_CHEAT_INDEX_MINUS },
340    { "CHEAT_TOGGLE",           RARCH_CHEAT_TOGGLE },
341    { "SCREENSHOT",             RARCH_SCREENSHOT },
342    { "MUTE",                   RARCH_MUTE },
343    { "OSK",                    RARCH_OSK },
344    { "FPS_TOGGLE",             RARCH_FPS_TOGGLE },
345    { "SEND_DEBUG_INFO",        RARCH_SEND_DEBUG_INFO },
346    { "NETPLAY_HOST_TOGGLE",    RARCH_NETPLAY_HOST_TOGGLE },
347    { "NETPLAY_GAME_WATCH",     RARCH_NETPLAY_GAME_WATCH },
348    { "VOLUME_UP",              RARCH_VOLUME_UP },
349    { "VOLUME_DOWN",            RARCH_VOLUME_DOWN },
350    { "OVERLAY_NEXT",           RARCH_OVERLAY_NEXT },
351    { "DISK_EJECT_TOGGLE",      RARCH_DISK_EJECT_TOGGLE },
352    { "DISK_NEXT",              RARCH_DISK_NEXT },
353    { "DISK_PREV",              RARCH_DISK_PREV },
354    { "GRAB_MOUSE_TOGGLE",      RARCH_GRAB_MOUSE_TOGGLE },
355    { "UI_COMPANION_TOGGLE",    RARCH_UI_COMPANION_TOGGLE },
356    { "GAME_FOCUS_TOGGLE",      RARCH_GAME_FOCUS_TOGGLE },
357    { "MENU_TOGGLE",            RARCH_MENU_TOGGLE },
358    { "RECORDING_TOGGLE",       RARCH_RECORDING_TOGGLE },
359    { "STREAMING_TOGGLE",       RARCH_STREAMING_TOGGLE },
360    { "RUNAHEAD_TOGGLE",        RARCH_RUNAHEAD_TOGGLE },
361    { "MENU_UP",                RETRO_DEVICE_ID_JOYPAD_UP },
362    { "MENU_DOWN",              RETRO_DEVICE_ID_JOYPAD_DOWN },
363    { "MENU_LEFT",              RETRO_DEVICE_ID_JOYPAD_LEFT },
364    { "MENU_RIGHT",             RETRO_DEVICE_ID_JOYPAD_RIGHT },
365    { "MENU_A",                 RETRO_DEVICE_ID_JOYPAD_A },
366    { "MENU_B",                 RETRO_DEVICE_ID_JOYPAD_B },
367    { "AI_SERVICE",             RARCH_AI_SERVICE },
368 };
369 #endif
370 
371 RETRO_END_DECLS
372 
373 #endif
374