Repository navigation
Expand file tree
/
Copy pathcommand.h
More file actions
1445 lines (1351 loc) · 68.5 KB
/
Copy pathcommand.h
File metadata and controls
1445 lines (1351 loc) · 68.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_H__
#define COMMAND_H__
#include <stdint.h>
#include <boolean.h>
#include <retro_common_api.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <streams/interface_stream.h>
#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,
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 <option> on|off */
bool command_get_option(command_t *cmd, const char *arg);
bool command_set_option(command_t *cmd, const char *arg);
#ifdef HAVE_MCP
/* GET_LOG [since] */
bool command_get_log(command_t *cmd, const char *arg);
#endif
/* RUN_FRAMES <count>. The runloop calls: tick after a frame a job ran;
* free_frame after one with no job; between before a frame, with the
* core off the stack, for a STEPS checkpoint; cancel when the content
* closes. forget ends a queued STEPS once the state it was planned
* from is gone: a state loaded, a reset, a close. */
#define COMMAND_RUN_FRAMES_MAX 36000
bool command_run_frames(command_t *cmd, const char *arg);
void command_run_frames_tick(void);
void command_run_frames_between(void);
#ifdef HAVE_MENU
/* MENU: the runloop hands action the menu's own action for a frame,
* before the menu runs it, and calls iterated once it has. */
unsigned command_menu_action(unsigned action);
void command_menu_iterated(void);
void command_menu_closed(void);
#endif
void command_run_frames_cancel(const char *why);
void command_run_frames_forget(void);
/* Achievements in hardcore mode are the player's own, as they forbid
* rewind and cheats: tools_refused is why an assistant's tool calls are
* refused now, or NULL; hardcore_entered stops what one left running -
* a frame job, a queue, held input - as hardcore mode takes effect. */
const char *command_tools_refused(void);
void command_hardcore_entered(void);
/* On the main thread each frame, before commands are read: what other
* threads left for it, and a MENU request whose menu closed. */
void command_frame_start(void);
void command_run_frames_free_frame(void);
/* SET_INPUT <player> <control> <value> / RELEASE_INPUT [player], and
* GET_INPUT [player] to look without changing anything. */
bool command_set_input(command_t *cmd, const char *arg);
bool command_release_input(command_t *cmd, const char *arg);
bool command_get_input(command_t *cmd, const char *arg);
/* The most frames a request runs, which a structured interface lowers
* to nine seconds of the content's frames to answer inside its
* ten-second reply deadline. PRESS keeps to it everywhere, since it
* holds input for every frame it runs. */
#define COMMAND_FRAMES_REPLY_MAX 600
/* PRESS <player> <control> <frames> [until <condition>]: hold, run and
* let go, then run on until the condition holds, in one. */
bool command_press(command_t *cmd, const char *arg);
/* RUN_UNTIL <address>[:<address>] <condition> <value> [max frames]: run
* the content until a byte, or two read as one value, says to stop. The
* conditions it takes are command.c's, which is all that compares them. */
bool command_run_until(command_t *cmd, const char *arg);
/* STEPS <step>[; <step>...][|on]: run, press, until and checkpoint
* steps, and a stop, as one request; with on, queued behind those
* still running, answered at once. */
bool command_steps(command_t *cmd, const char *arg);
/* WATCH [<label> <address|off>]...: the bytes RUN_FRAMES, PRESS and
* RUN_UNTIL carry along with their own answer, looked up afresh each
* time. Cleared when content closes: the next content's addresses mean
* something else. */
bool command_watch(command_t *cmd, const char *arg);
void command_watch_clear(void);
/* GET_CORE_OPTION [key] / SET_CORE_OPTION <key> <value> */
bool command_get_core_option(command_t *cmd, const char *arg);
bool command_set_core_option(command_t *cmd, const char *arg);
/* Replies with a failure and why, and marks the reply as one. The text
* opens with @name and ERROR, as a deferred reply's does. */
void command_reply_error(command_t *cmd, const char *name,
const char *fmt, ...);
/* HELP [command]: the commands, their arguments and what they do. */
bool command_help(command_t *cmd, const char* arg);
/* Queries for clients that browse and launch content. */
bool command_list_cores(command_t *cmd, const char* arg);
bool command_list_playlists(command_t *cmd, const char* arg);
bool command_get_playlist(command_t *cmd, const char* arg);
/* Runs one command by name; see command.c. */
bool command_run(command_t *handle, const char *name, const char *arg);
/* True once a command has started a content load: requests an
* interface has yet to take wait for the next poll, which comes once
* the load is through. */
bool command_interfaces_held(void);
/* Every command, for interfaces that describe them to a client. */
const struct cmd_action_map *command_action_list(size_t *count);
const struct cmd_map *command_hotkey_list(size_t *count);
bool command_version(command_t *cmd, const char* arg);
bool command_get_status(command_t *cmd, const char* arg);
bool command_get_config_param(command_t *cmd, const char* arg);
bool command_show_osd_msg(command_t *cmd, const char* arg);
bool command_load_state_slot(command_t *cmd, const char* arg);
bool command_save_state_slot(command_t* cmd, const char* arg);
bool command_play_replay_slot(command_t *cmd, const char* arg);
bool command_seek_replay(command_t *cmd, const char *arg);
bool command_save_savefiles(command_t *cmd, const char* arg);
bool command_load_savefiles(command_t *cmd, const char* arg);
#ifdef HAVE_CHEEVOS
bool command_read_ram(command_t *cmd, const char *arg);
bool command_write_ram(command_t *cmd, const char *arg);
#endif
bool command_read_memory(command_t *cmd, const char *arg);
bool command_write_memory(command_t *cmd, const char *arg);
bool command_get_memory_map(command_t *cmd, const char *arg);
bool command_load_core(command_t *cmd, const char* arg);
bool command_start_core(command_t *cmd, const char* arg);
bool command_load_content(command_t *cmd, const char* arg);
bool command_close_content(command_t *cmd, const char* arg);
bool command_unload_core(command_t *cmd, const char* arg);
bool command_video_reinit(command_t *cmd, const char* arg);
bool command_audio_reinit(command_t *cmd, const char* arg);
bool command_drivers_reinit(command_t *cmd, const char* arg);
/* MENU <button>, DISK <action>, REINIT <driver>, STATE <action> <slot>,
* REPLAY <action> [slot|frame]: the hotkeys and commands of one family
* behind one name, as one tool. */
#define COMMAND_MENU_ACTIONS "show|open|close|select|up|down|left|right|a|b|type"
/* the entries MENU answers with at once */
#define COMMAND_MENU_PAGE 50
#define COMMAND_DISK_ACTIONS "eject|next|prev"
#define COMMAND_REINIT_DRIVERS "video|audio|all"
#define COMMAND_STATE_ACTIONS "save|load|checkpoint|rollback"
#define COMMAND_REPLAY_ACTIONS "play|seek|record|halt|checkpoint"
#define COMMAND_CORE_ACTIONS "load|start|unload"
#define COMMAND_INPUT_ACTIONS "set|release|show"
#define COMMAND_OPTION_ACTIONS "show|set"
bool command_menu(command_t *cmd, const char *arg);
bool command_disk(command_t *cmd, const char *arg);
bool command_reinit(command_t *cmd, const char *arg);
bool command_state(command_t *cmd, const char *arg);
/* CHECKPOINT_STATE and ROLLBACK_STATE: one state kept in memory for
* the content's life, which command_checkpoint_clear() drops. */
bool command_checkpoint_save(command_t *cmd, const char *arg);
/* RESET [on|off]: the hotkey's reset, paused after it with on. */
bool command_reset(command_t *cmd, const char *arg);
bool command_checkpoint_rollback(command_t *cmd, const char *arg);
void command_checkpoint_clear(void);
bool command_core(command_t *cmd, const char *arg);
bool command_replay(command_t *cmd, const char *arg);
/* INPUT, OPTION and CORE_OPTION: SET_INPUT, RELEASE_INPUT, GET_INPUT,
* GET_OPTION, SET_OPTION, GET_CORE_OPTION and SET_CORE_OPTION */
bool command_input(command_t *cmd, const char *arg);
bool command_option(command_t *cmd, const char *arg);
bool command_core_option(command_t *cmd, const char *arg);
/* The parameters of the commands that take any. Several commands take
* the same ones; what tells READ_CORE_RAM from READ_CORE_MEMORY is the
* command's own description, not its parameters'. */
static const struct cmd_param cmd_params_help[] = {
{ "command", "A command name. Left out, every command.",
CMD_PARAM_STRING, false, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_preset[] = {
{ "preset", "Path to a shader preset, absolute or under the shader "
"directory. Empty turns the shader off.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_option[] = {
{ "option", "An option name, as GET_OPTION with no argument lists.",
CMD_PARAM_STRING, false, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_option_set[] = {
{ "option", "An option name, as GET_OPTION with no argument lists.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ "state", "The state to put it in.",
CMD_PARAM_STRING, true, NULL, "on|off", NULL },
{ NULL }
};
#ifdef HAVE_MCP
static const struct cmd_param cmd_params_log[] = {
{ "since", "The first line wanted, as next gave it; 0 when left out.",
CMD_PARAM_INT, false, NULL, NULL, "0" },
{ NULL }
};
#endif
static const struct cmd_param cmd_params_run_frames[] = {
{ "count", "How many frames to run; ask again to run more.", CMD_PARAM_INT, true, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_input[] = {
{ "player", "The player, from 1.", CMD_PARAM_INT, true, NULL, NULL, NULL },
/* No enum: a combination is not one of the names, and a client that
* held the schema to one would refuse to send it. */
{ "control", "A RetroPad button or stick axis, or several joined by "
"\"+\" to hold together: b, y, select, start, up, down, left, "
"right, a, x, l, r, l2, r2, l3, r3, left_x, left_y, right_x, "
"right_y. \"right+a\" runs and jumps in one request.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ "value", "1 holds a button and 0 lets it go; an axis takes -32768 "
"to 32767, 0 letting it go.", CMD_PARAM_INT, true, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_input_family[] = {
{ "action", "set holds or lets go of controls; release lets go of all "
"a player holds; show reads it.", CMD_PARAM_STRING, true, NULL,
COMMAND_INPUT_ACTIONS, NULL },
{ "player", "From 1. Left out, release frees every player and show "
"reads the first.", CMD_PARAM_INT, false, NULL, NULL, NULL },
/* No enum: a combination is not one of the names, and a client that
* held the schema to one would refuse to send it. */
{ "control", "For set: a button or stick axis, or several joined by "
"\"+\": b, y, select, start, up, down, left, right, a, x, l, r, l2, "
"r2, l3, r3, left_x, left_y, right_x, right_y.",
CMD_PARAM_STRING, false, NULL, NULL, NULL },
{ "value", "For set: 1 holds a button, 0 lets go; an axis takes "
"-32768 to 32767.", CMD_PARAM_INT, false, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_option_family[] = {
{ "action", "show one option, or all; set one.", CMD_PARAM_STRING,
true, NULL, COMMAND_OPTION_ACTIONS, NULL },
{ "option", "An option name, as show lists it.", CMD_PARAM_STRING,
false, NULL, NULL, NULL },
{ "state", "For set.", CMD_PARAM_STRING, false, NULL, "on|off", NULL },
{ NULL }
};
static const struct cmd_param cmd_params_core_option_family[] = {
{ "action", "show the core's options, or one with the values it "
"takes; set one.", CMD_PARAM_STRING, true, NULL,
COMMAND_OPTION_ACTIONS, NULL },
{ "option", "A key, as show lists it.", CMD_PARAM_STRING, false, NULL,
NULL, NULL },
{ "value", "For set: one of the values show lists for the key.",
CMD_PARAM_STRING, false, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_watch[] = {
{ "watches", "Label and hexadecimal address pairs, as GET_MEMORY_MAP "
"gives them: \"x 86 mode 770\"; \"x 6d:86\" reads two bytes as one "
"value. A label watched again is replaced; off as its address stops "
"it. 16 at most.",
CMD_PARAM_STRING, false, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_until[] = {
{ "address", "Hexadecimal, as GET_MEMORY_MAP gives it; high:low "
"(6d:86) reads two bytes as one value; & 0x40 after it compares "
"only those bits.", CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ "condition", "How it compares with the value.",
CMD_PARAM_STRING, true, NULL, "==|!=|<|>|<=|>=", NULL },
{ "value", "0 to 255, or 65535 for high:low.",
CMD_PARAM_INT, true, NULL, NULL, NULL },
{ "frames", "Frames to wait at most; a request's nine seconds when "
"left out.", CMD_PARAM_INT, false, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_press[] = {
{ "player", "From 1.", CMD_PARAM_INT, true, NULL, NULL, NULL },
{ "control", "Buttons as INPUT names them, joined by \"+\": "
"\"right+a\" runs and jumps.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ "frames", "Frames to hold them: a tap is 2 to 4. Right after a "
"press it lets go for a frame first.",
CMD_PARAM_INT, true, NULL, NULL, NULL },
{ "until", "Then run until this holds, as RUN_UNTIL's: \"1d == 0\" "
"lands a jump.",
CMD_PARAM_STRING, false, " until ", NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_steps[] = {
{ "steps", "In order, by \";\": run <frames>, press <player> <controls> "
"<frames>, until <condition> as RUN_UNTIL's, checkpoint, and up to "
"four stop <condition> that end it: \"until 86 >= 200; "
"press 1 a 20; until 1d == 0; stop e == 11\". 32 at most. A press "
"after a press lets go for a frame first.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ "queue", "on: answer now, run after those queued, pause when all "
"have (idle: ms since). After a queued list ends the next reply says "
"how (previous), and a queued call drops its steps (discarded). "
"Empty steps asks; a call not queued ends the queue.",
CMD_PARAM_STRING, false, "|", "on|off", NULL },
{ NULL }
};
static const struct cmd_param cmd_params_input_release[] = {
{ "player", "The player, from 1; every player when left out.",
CMD_PARAM_INT, false, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_input_get[] = {
{ "player", "The player, from 1; the first when left out.",
CMD_PARAM_INT, false, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_core_option[] = {
{ "option", "A core option key, as GET_CORE_OPTION with no argument "
"lists it.", CMD_PARAM_STRING, false, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_core_option_set[] = {
{ "option", "A core option key, as GET_CORE_OPTION with no argument "
"lists it.", CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ "value", "One of the values GET_CORE_OPTION with the key lists.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_config[] = {
{ "parameter", "A configuration setting's name.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_playlist[] = {
{ "playlist", "A playlist name as LIST_PLAYLISTS gives it, \".lpl\" "
"and all.", CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ "first", "The entry to start at; the first when left out.",
CMD_PARAM_INT, false, NULL, NULL, "0" },
{ NULL }
};
#if defined(HAVE_SCREENSHOTS) && defined(HAVE_RPNG)
static const struct cmd_param cmd_params_get_frame[] = {
{ "size", "The longest side at most, 64 to 640; 320 when left out.",
CMD_PARAM_INT, false, NULL, NULL, "320" },
{ NULL }
};
#endif
static const struct cmd_param cmd_params_message[] = {
{ "message", "The text.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_read[] = {
{ "address", "The address to read from, in hexadecimal.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ "bytes", "How many.",
CMD_PARAM_INT, true, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_write[] = {
{ "address", "The address to write to, in hexadecimal.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ "bytes", "The bytes to write, in hexadecimal, separated by spaces.",
CMD_PARAM_STRING, true, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_slot[] = {
{ "slot", "The slot number.", CMD_PARAM_INT, true, NULL, NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_menu[] = {
{ "action", "select moves to index; left and right change a value, a "
"confirms, b goes back, type answers a keyboard.",
CMD_PARAM_STRING, true, NULL, COMMAND_MENU_ACTIONS, NULL },
{ "text", "For type: the text, typed and confirmed.",
CMD_PARAM_STRING, false, NULL, NULL, NULL },
{ "index", "An entry: select, left, right and a act on it.",
CMD_PARAM_INT, false, NULL, NULL, NULL },
{ "from", "The first entry listed; else the page with the selection.",
CMD_PARAM_INT, false, " from ", NULL, NULL },
{ NULL }
};
static const struct cmd_param cmd_params_disk[] = {
{ "action", "eject ejects or inserts it.", CMD_PARAM_STRING, true,
NULL, COMMAND_DISK_ACTIONS, NULL },
{ NULL }
};