1 /* RetroArch - A frontend for libretro.
2 * Copyright (C) 2011-2017 - Daniel De Matteis
3 * Copyright (C) 2016-2019 - Brad Parker
4 * Copyright (C) 2016-2019 - Andrés Suárez
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 #include <compat/strl.h>
19 #include <array/rbuf.h>
20 #include <file/file_path.h>
21 #include <retro_assert.h>
22 #include <string/stdstring.h>
23 #include <streams/file_stream.h>
24 #include <lists/string_list.h>
25
26 #ifdef HAVE_CONFIG_H
27 #include "../../config.h"
28 #endif
29
30 #include <vfs/vfs_implementation.h>
31 #ifdef HAVE_CDROM
32 #include <vfs/vfs_implementation_cdrom.h>
33 #endif
34
35 #ifdef HAVE_DISCORD
36 #include "../../network/discord.h"
37 #endif
38
39 #include "../../config.def.h"
40 #include "../../config.def.keybinds.h"
41 #include "../../wifi/wifi_driver.h"
42 #include "../../driver.h"
43
44 #include "../menu_driver.h"
45 #include "../menu_cbs.h"
46 #include "../menu_entries.h"
47 #include "../menu_setting.h"
48 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
49 #include "../menu_shader.h"
50 #endif
51 #include "../menu_dialog.h"
52 #include "../menu_input_bind_dialog.h"
53 #include "../menu_input.h"
54
55 #include "../../core.h"
56 #include "../../configuration.h"
57 #include "../../core_info.h"
58 #include "../../frontend/frontend_driver.h"
59 #include "../../defaults.h"
60 #include "../../core_option_manager.h"
61 #ifdef HAVE_CHEATS
62 #include "../../cheat_manager.h"
63 #endif
64 #ifdef HAVE_AUDIOMIXER
65 #include "../../tasks/task_audio_mixer.h"
66 #endif
67 #include "../../tasks/task_content.h"
68 #include "../../tasks/task_file_transfer.h"
69 #include "../../tasks/tasks_internal.h"
70 #include "../../input/input_remapping.h"
71 #include "../../paths.h"
72 #include "../../playlist.h"
73 #include "../../retroarch.h"
74 #include "../../verbosity.h"
75 #include "../../lakka.h"
76 #include "../../bluetooth/bluetooth_driver.h"
77 #include "../../gfx/video_display_server.h"
78 #include "../../manual_content_scan.h"
79
80 #include <net/net_http.h>
81
82 #ifdef HAVE_NETWORKING
83 #include "../../network/netplay/netplay.h"
84 #include "../../network/netplay/netplay_discovery.h"
85 #include "../../wifi/wifi_driver.h"
86 #endif
87
88 #ifdef __WINRT__
89 #include "../../uwp/uwp_func.h"
90 #endif
91
92 #if defined(ANDROID)
93 #include "../../file_path_special.h"
94 #include "../../play_feature_delivery/play_feature_delivery.h"
95 #endif
96
97 enum
98 {
99 ACTION_OK_LOAD_PRESET = 0,
100 ACTION_OK_LOAD_SHADER_PASS,
101 ACTION_OK_LOAD_STREAM_CONFIGFILE,
102 ACTION_OK_LOAD_RECORD_CONFIGFILE,
103 ACTION_OK_LOAD_REMAPPING_FILE,
104 ACTION_OK_LOAD_CHEAT_FILE,
105 ACTION_OK_SUBSYSTEM_ADD,
106 ACTION_OK_LOAD_CONFIG_FILE,
107 ACTION_OK_LOAD_CORE,
108 ACTION_OK_LOAD_WALLPAPER,
109 ACTION_OK_SET_PATH,
110 ACTION_OK_SET_PATH_AUDIO_FILTER,
111 ACTION_OK_SET_PATH_VIDEO_FILTER,
112 ACTION_OK_SET_PATH_OVERLAY,
113 #ifdef HAVE_VIDEO_LAYOUT
114 ACTION_OK_SET_PATH_VIDEO_LAYOUT,
115 #endif
116 ACTION_OK_SET_PATH_VIDEO_FONT,
117 ACTION_OK_SET_DIRECTORY,
118 ACTION_OK_SHOW_WIMP,
119 ACTION_OK_LOAD_CHEAT_FILE_APPEND,
120 ACTION_OK_LOAD_RGUI_MENU_THEME_PRESET,
121 ACTION_OK_SET_MANUAL_CONTENT_SCAN_DAT_FILE
122 };
123
124 enum
125 {
126 ACTION_OK_REMAP_FILE_SAVE_CORE = 0,
127 ACTION_OK_REMAP_FILE_SAVE_CONTENT_DIR,
128 ACTION_OK_REMAP_FILE_SAVE_GAME,
129 ACTION_OK_REMAP_FILE_REMOVE_CORE,
130 ACTION_OK_REMAP_FILE_REMOVE_CONTENT_DIR,
131 ACTION_OK_REMAP_FILE_REMOVE_GAME
132 };
133
134 #ifndef BIND_ACTION_OK
135 #define BIND_ACTION_OK(cbs, name) (cbs)->action_ok = (name)
136 #endif
137
138 #ifdef HAVE_NETWORKING
139
140 #ifndef INET6_ADDRSTRLEN
141 #define INET6_ADDRSTRLEN 46
142 #endif
143
144 #endif
145
146 #define ACTION_OK_DL_LBL(a, b) \
147 info.directory_ptr = idx; \
148 info.type = type; \
149 info_path = path; \
150 info_label = msg_hash_to_str(a); \
151 info.enum_idx = a; \
152 dl_type = b;
153
154
155 #define DEFAULT_ACTION_OK_SET(funcname, _id, _flush) \
156 static int (funcname)(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) \
157 { \
158 return generic_action_ok(path, label, type, idx, entry_idx, _id, _flush); \
159 }
160
161
162 #define DEFAULT_ACTION_DIALOG_START(funcname, _label, _idx, _cb) \
163 static int (funcname)(const char *path, const char *label_setting, unsigned type, size_t idx, size_t entry_idx) \
164 { \
165 menu_input_ctx_line_t line; \
166 line.label = _label; \
167 line.label_setting = label_setting; \
168 line.type = type; \
169 line.idx = (_idx); \
170 line.cb = _cb; \
171 if (!menu_input_dialog_start(&line)) \
172 return -1; \
173 return 0; \
174 }
175
176
177 #define DEFAULT_ACTION_OK_START_BUILTIN_CORE(funcname, _id) \
178 static int (funcname)(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) \
179 { \
180 content_ctx_info_t content_info; \
181 content_info.argc = 0; \
182 content_info.argv = NULL; \
183 content_info.args = NULL; \
184 content_info.environ_get = NULL; \
185 if (!task_push_start_builtin_core(&content_info, _id, NULL, NULL)) \
186 return -1; \
187 return 0; \
188 }
189
190 #define DEFAULT_ACTION_OK_LIST(funcname, _id) \
191 static int (funcname)(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) \
192 { \
193 return generic_action_ok_network(path, label, type, idx, entry_idx, _id); \
194 }
195
196 #define DEFAULT_ACTION_OK_DOWNLOAD(funcname, _id) \
197 static int (funcname)(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) \
198 { \
199 return action_ok_download_generic(path, label, NULL, type, idx, entry_idx,_id); \
200 }
201
202 #define DEFAULT_ACTION_OK_CMD_FUNC(func_name, cmd) \
203 int (func_name)(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) \
204 { \
205 return generic_action_ok_command(cmd); \
206 }
207
208 #define DEFAULT_ACTION_OK_FUNC(func_name, lbl) \
209 int (func_name)(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) \
210 { \
211 return generic_action_ok_displaylist_push(path, NULL, label, type, idx, entry_idx, lbl); \
212 }
213
214 #define DEFAULT_ACTION_OK_DL_PUSH(funcname, _fbid, _id, _path) \
215 static int (funcname)(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) \
216 { \
217 settings_t *settings = config_get_ptr(); \
218 (void)settings; \
219 filebrowser_set_type(_fbid); \
220 return generic_action_ok_displaylist_push(path, _path, label, type, idx, entry_idx, _id); \
221 }
222
223 #define DEFAULT_ACTION_OK_HELP(funcname, _id, _id2) \
224 static int (funcname)(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) \
225 { \
226 return generic_action_ok_help(path, label, type, idx, entry_idx, _id, _id2); \
227 }
228
229 #ifdef HAVE_NETWORKING
230 #ifdef HAVE_LAKKA
lakka_get_project(void)231 static char *lakka_get_project(void)
232 {
233 size_t len;
234 static char lakka_project[128];
235 FILE *command_file = popen("cat /etc/release | cut -d - -f 1", "r");
236
237 fgets(lakka_project, sizeof(lakka_project), command_file);
238 len = strlen(lakka_project);
239
240 if (len > 0 && lakka_project[len-1] == '\n')
241 lakka_project[--len] = '\0';
242
243 pclose(command_file);
244 return lakka_project;
245 }
246 #endif
247 #endif
248
action_ok_dl_to_enum(unsigned lbl)249 static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl)
250 {
251 switch (lbl)
252 {
253 case ACTION_OK_DL_REMAPPINGS_PORT_LIST:
254 return MENU_ENUM_LABEL_DEFERRED_REMAPPINGS_PORT_LIST;
255 case ACTION_OK_DL_DROPDOWN_BOX_LIST_SHADER_PARAMETER:
256 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PARAMETER;
257 case ACTION_OK_DL_DROPDOWN_BOX_LIST_SHADER_PRESET_PARAMETER:
258 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PRESET_PARAMETER;
259 case ACTION_OK_DL_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES:
260 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES;
261 case ACTION_OK_DL_DROPDOWN_BOX_LIST:
262 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST;
263 case ACTION_OK_DL_DROPDOWN_BOX_LIST_SPECIAL:
264 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL;
265 case ACTION_OK_DL_DROPDOWN_BOX_LIST_RESOLUTION:
266 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION;
267 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE:
268 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE;
269 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE:
270 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE;
271 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE:
272 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE;
273 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
274 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE;
275 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE:
276 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE;
277 case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
278 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME;
279 case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME:
280 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME;
281 case ACTION_OK_DL_DROPDOWN_BOX_LIST_DISK_INDEX:
282 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX;
283 case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DEVICE_TYPE:
284 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DEVICE_TYPE;
285 case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DEVICE_INDEX:
286 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DEVICE_INDEX;
287 case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION:
288 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION;
289 case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD:
290 return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD;
291 case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST:
292 return MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST;
293 case ACTION_OK_DL_ACCOUNTS_LIST:
294 return MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_LIST;
295 case ACTION_OK_DL_ACHIEVEMENTS_HARDCORE_PAUSE_LIST:
296 return MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_LIST;
297 case ACTION_OK_DL_INPUT_SETTINGS_LIST:
298 return MENU_ENUM_LABEL_DEFERRED_INPUT_SETTINGS_LIST;
299 case ACTION_OK_DL_INPUT_MENU_SETTINGS_LIST:
300 return MENU_ENUM_LABEL_DEFERRED_INPUT_MENU_SETTINGS_LIST;
301 case ACTION_OK_DL_INPUT_TURBO_FIRE_SETTINGS_LIST:
302 return MENU_ENUM_LABEL_DEFERRED_INPUT_TURBO_FIRE_SETTINGS_LIST;
303 case ACTION_OK_DL_INPUT_HAPTIC_FEEDBACK_SETTINGS_LIST:
304 return MENU_ENUM_LABEL_DEFERRED_INPUT_HAPTIC_FEEDBACK_SETTINGS_LIST;
305 case ACTION_OK_DL_LATENCY_SETTINGS_LIST:
306 return MENU_ENUM_LABEL_DEFERRED_LATENCY_SETTINGS_LIST;
307 case ACTION_OK_DL_DRIVER_SETTINGS_LIST:
308 return MENU_ENUM_LABEL_DEFERRED_DRIVER_SETTINGS_LIST;
309 case ACTION_OK_DL_CORE_SETTINGS_LIST:
310 return MENU_ENUM_LABEL_DEFERRED_CORE_SETTINGS_LIST;
311 case ACTION_OK_DL_CORE_INFORMATION_LIST:
312 return MENU_ENUM_LABEL_DEFERRED_CORE_INFORMATION_LIST;
313 case ACTION_OK_DL_CORE_RESTORE_BACKUP_LIST:
314 return MENU_ENUM_LABEL_DEFERRED_CORE_RESTORE_BACKUP_LIST;
315 case ACTION_OK_DL_CORE_DELETE_BACKUP_LIST:
316 return MENU_ENUM_LABEL_DEFERRED_CORE_DELETE_BACKUP_LIST;
317 case ACTION_OK_DL_VIDEO_SETTINGS_LIST:
318 return MENU_ENUM_LABEL_DEFERRED_VIDEO_SETTINGS_LIST;
319 case ACTION_OK_DL_VIDEO_SYNCHRONIZATION_SETTINGS_LIST:
320 return MENU_ENUM_LABEL_DEFERRED_VIDEO_SYNCHRONIZATION_SETTINGS_LIST;
321 case ACTION_OK_DL_VIDEO_FULLSCREEN_MODE_SETTINGS_LIST:
322 return MENU_ENUM_LABEL_DEFERRED_VIDEO_FULLSCREEN_MODE_SETTINGS_LIST;
323 case ACTION_OK_DL_VIDEO_WINDOWED_MODE_SETTINGS_LIST:
324 return MENU_ENUM_LABEL_DEFERRED_VIDEO_WINDOWED_MODE_SETTINGS_LIST;
325 case ACTION_OK_DL_VIDEO_SCALING_SETTINGS_LIST:
326 return MENU_ENUM_LABEL_DEFERRED_VIDEO_SCALING_SETTINGS_LIST;
327 case ACTION_OK_DL_VIDEO_OUTPUT_SETTINGS_LIST:
328 return MENU_ENUM_LABEL_DEFERRED_VIDEO_OUTPUT_SETTINGS_LIST;
329 case ACTION_OK_DL_CRT_SWITCHRES_SETTINGS_LIST:
330 return MENU_ENUM_LABEL_DEFERRED_CRT_SWITCHRES_SETTINGS_LIST;
331 case ACTION_OK_DL_CONFIGURATION_SETTINGS_LIST:
332 return MENU_ENUM_LABEL_DEFERRED_CONFIGURATION_SETTINGS_LIST;
333 case ACTION_OK_DL_SAVING_SETTINGS_LIST:
334 return MENU_ENUM_LABEL_DEFERRED_SAVING_SETTINGS_LIST;
335 case ACTION_OK_DL_LOGGING_SETTINGS_LIST:
336 return MENU_ENUM_LABEL_DEFERRED_LOGGING_SETTINGS_LIST;
337 case ACTION_OK_DL_FRAME_THROTTLE_SETTINGS_LIST:
338 return MENU_ENUM_LABEL_DEFERRED_FRAME_THROTTLE_SETTINGS_LIST;
339 case ACTION_OK_DL_FRAME_TIME_COUNTER_SETTINGS_LIST:
340 return MENU_ENUM_LABEL_DEFERRED_FRAME_TIME_COUNTER_SETTINGS_LIST;
341 case ACTION_OK_DL_REWIND_SETTINGS_LIST:
342 return MENU_ENUM_LABEL_DEFERRED_REWIND_SETTINGS_LIST;
343 case ACTION_OK_DL_CHEAT_DETAILS_SETTINGS_LIST:
344 return MENU_ENUM_LABEL_DEFERRED_CHEAT_DETAILS_SETTINGS_LIST;
345 case ACTION_OK_DL_CHEAT_SEARCH_SETTINGS_LIST:
346 return MENU_ENUM_LABEL_DEFERRED_CHEAT_SEARCH_SETTINGS_LIST;
347 case ACTION_OK_DL_ONSCREEN_DISPLAY_SETTINGS_LIST:
348 return MENU_ENUM_LABEL_DEFERRED_ONSCREEN_DISPLAY_SETTINGS_LIST;
349 case ACTION_OK_DL_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST:
350 return MENU_ENUM_LABEL_DEFERRED_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST;
351 case ACTION_OK_DL_ONSCREEN_NOTIFICATIONS_VIEWS_SETTINGS_LIST:
352 return MENU_ENUM_LABEL_DEFERRED_ONSCREEN_NOTIFICATIONS_VIEWS_SETTINGS_LIST;
353 case ACTION_OK_DL_ONSCREEN_OVERLAY_SETTINGS_LIST:
354 return MENU_ENUM_LABEL_DEFERRED_ONSCREEN_OVERLAY_SETTINGS_LIST;
355 #ifdef HAVE_VIDEO_LAYOUT
356 case ACTION_OK_DL_ONSCREEN_VIDEO_LAYOUT_SETTINGS_LIST:
357 return MENU_ENUM_LABEL_DEFERRED_ONSCREEN_VIDEO_LAYOUT_SETTINGS_LIST;
358 #endif
359 case ACTION_OK_DL_MENU_SETTINGS_LIST:
360 return MENU_ENUM_LABEL_DEFERRED_MENU_SETTINGS_LIST;
361 case ACTION_OK_DL_MENU_VIEWS_SETTINGS_LIST:
362 return MENU_ENUM_LABEL_DEFERRED_MENU_VIEWS_SETTINGS_LIST;
363 case ACTION_OK_DL_SETTINGS_VIEWS_SETTINGS_LIST:
364 return MENU_ENUM_LABEL_DEFERRED_SETTINGS_VIEWS_SETTINGS_LIST;
365 case ACTION_OK_DL_QUICK_MENU_VIEWS_SETTINGS_LIST:
366 return MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_VIEWS_SETTINGS_LIST;
367 case ACTION_OK_DL_QUICK_MENU_OVERRIDE_OPTIONS_LIST:
368 return MENU_ENUM_LABEL_DEFERRED_QUICK_MENU_OVERRIDE_OPTIONS;
369 case ACTION_OK_DL_USER_INTERFACE_SETTINGS_LIST:
370 return MENU_ENUM_LABEL_DEFERRED_USER_INTERFACE_SETTINGS_LIST;
371 case ACTION_OK_DL_AI_SERVICE_SETTINGS_LIST:
372 return MENU_ENUM_LABEL_DEFERRED_AI_SERVICE_SETTINGS_LIST;
373 case ACTION_OK_DL_ACCESSIBILITY_SETTINGS_LIST:
374 return MENU_ENUM_LABEL_DEFERRED_ACCESSIBILITY_SETTINGS_LIST;
375 case ACTION_OK_DL_POWER_MANAGEMENT_SETTINGS_LIST:
376 return MENU_ENUM_LABEL_DEFERRED_POWER_MANAGEMENT_SETTINGS_LIST;
377 case ACTION_OK_DL_CPU_PERFPOWER_SETTINGS_LIST:
378 return MENU_ENUM_LABEL_DEFERRED_CPU_PERFPOWER_LIST;
379 case ACTION_OK_DL_CPU_POLICY_SETTINGS_LIST:
380 return MENU_ENUM_LABEL_DEFERRED_CPU_POLICY_ENTRY;
381 case ACTION_OK_DL_MENU_SOUNDS_LIST:
382 return MENU_ENUM_LABEL_DEFERRED_MENU_SOUNDS_LIST;
383 case ACTION_OK_DL_MENU_FILE_BROWSER_SETTINGS_LIST:
384 return MENU_ENUM_LABEL_DEFERRED_MENU_FILE_BROWSER_SETTINGS_LIST;
385 case ACTION_OK_DL_RETRO_ACHIEVEMENTS_SETTINGS_LIST:
386 return MENU_ENUM_LABEL_DEFERRED_RETRO_ACHIEVEMENTS_SETTINGS_LIST;
387 case ACTION_OK_DL_UPDATER_SETTINGS_LIST:
388 return MENU_ENUM_LABEL_DEFERRED_UPDATER_SETTINGS_LIST;
389 case ACTION_OK_DL_NETWORK_HOSTING_SETTINGS_LIST:
390 return MENU_ENUM_LABEL_DEFERRED_NETWORK_HOSTING_SETTINGS_LIST;
391 case ACTION_OK_DL_SUBSYSTEM_SETTINGS_LIST:
392 return MENU_ENUM_LABEL_DEFERRED_SUBSYSTEM_SETTINGS_LIST;
393 case ACTION_OK_DL_NETWORK_SETTINGS_LIST:
394 return MENU_ENUM_LABEL_DEFERRED_NETWORK_SETTINGS_LIST;
395 case ACTION_OK_DL_BLUETOOTH_SETTINGS_LIST:
396 return MENU_ENUM_LABEL_DEFERRED_BLUETOOTH_SETTINGS_LIST;
397 case ACTION_OK_DL_WIFI_SETTINGS_LIST:
398 return MENU_ENUM_LABEL_DEFERRED_WIFI_SETTINGS_LIST;
399 case ACTION_OK_DL_WIFI_NETWORKS_LIST:
400 return MENU_ENUM_LABEL_DEFERRED_WIFI_NETWORKS_LIST;
401 case ACTION_OK_DL_NETPLAY:
402 return MENU_ENUM_LABEL_DEFERRED_NETPLAY;
403 case ACTION_OK_DL_NETPLAY_LAN_SCAN_SETTINGS_LIST:
404 return MENU_ENUM_LABEL_DEFERRED_NETPLAY_LAN_SCAN_SETTINGS_LIST;
405 case ACTION_OK_DL_LAKKA_SERVICES_LIST:
406 return MENU_ENUM_LABEL_DEFERRED_LAKKA_SERVICES_LIST;
407 case ACTION_OK_DL_USER_SETTINGS_LIST:
408 return MENU_ENUM_LABEL_DEFERRED_USER_SETTINGS_LIST;
409 case ACTION_OK_DL_DIRECTORY_SETTINGS_LIST:
410 return MENU_ENUM_LABEL_DEFERRED_DIRECTORY_SETTINGS_LIST;
411 case ACTION_OK_DL_PRIVACY_SETTINGS_LIST:
412 return MENU_ENUM_LABEL_DEFERRED_PRIVACY_SETTINGS_LIST;
413 case ACTION_OK_DL_MIDI_SETTINGS_LIST:
414 return MENU_ENUM_LABEL_DEFERRED_MIDI_SETTINGS_LIST;
415 case ACTION_OK_DL_AUDIO_SETTINGS_LIST:
416 return MENU_ENUM_LABEL_DEFERRED_AUDIO_SETTINGS_LIST;
417 case ACTION_OK_DL_AUDIO_OUTPUT_SETTINGS_LIST:
418 return MENU_ENUM_LABEL_DEFERRED_AUDIO_OUTPUT_SETTINGS_LIST;
419 case ACTION_OK_DL_AUDIO_RESAMPLER_SETTINGS_LIST:
420 return MENU_ENUM_LABEL_DEFERRED_AUDIO_RESAMPLER_SETTINGS_LIST;
421 case ACTION_OK_DL_AUDIO_SYNCHRONIZATION_SETTINGS_LIST:
422 return MENU_ENUM_LABEL_DEFERRED_AUDIO_SYNCHRONIZATION_SETTINGS_LIST;
423 case ACTION_OK_DL_AUDIO_MIXER_SETTINGS_LIST:
424 return MENU_ENUM_LABEL_DEFERRED_AUDIO_MIXER_SETTINGS_LIST;
425 case ACTION_OK_DL_INPUT_HOTKEY_BINDS_LIST:
426 return MENU_ENUM_LABEL_DEFERRED_INPUT_HOTKEY_BINDS_LIST;
427 case ACTION_OK_DL_RECORDING_SETTINGS_LIST:
428 return MENU_ENUM_LABEL_DEFERRED_RECORDING_SETTINGS_LIST;
429 case ACTION_OK_DL_PLAYLIST_SETTINGS_LIST:
430 return MENU_ENUM_LABEL_DEFERRED_PLAYLIST_SETTINGS_LIST;
431 case ACTION_OK_DL_PLAYLIST_MANAGER_LIST:
432 return MENU_ENUM_LABEL_DEFERRED_PLAYLIST_MANAGER_LIST;
433 case ACTION_OK_DL_PLAYLIST_MANAGER_SETTINGS:
434 return MENU_ENUM_LABEL_DEFERRED_PLAYLIST_MANAGER_SETTINGS;
435 case ACTION_OK_DL_ACCOUNTS_CHEEVOS_LIST:
436 return MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_CHEEVOS_LIST;
437 case ACTION_OK_DL_ACCOUNTS_TWITCH_LIST:
438 return MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_TWITCH_LIST;
439 case ACTION_OK_DL_ACCOUNTS_FACEBOOK_LIST:
440 return MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_FACEBOOK_LIST;
441 case ACTION_OK_DL_DUMP_DISC_LIST:
442 return MENU_ENUM_LABEL_DEFERRED_DUMP_DISC_LIST;
443 case ACTION_OK_DL_LOAD_DISC_LIST:
444 return MENU_ENUM_LABEL_DEFERRED_LOAD_DISC_LIST;
445 case ACTION_OK_DL_ACCOUNTS_YOUTUBE_LIST:
446 return MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_YOUTUBE_LIST;
447 case ACTION_OK_DL_PLAYLIST_COLLECTION:
448 return MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST;
449 case ACTION_OK_DL_FAVORITES_LIST:
450 return MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST;
451 case ACTION_OK_DL_BROWSE_URL_LIST:
452 return MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_LIST;
453 case ACTION_OK_DL_MUSIC_LIST:
454 return MENU_ENUM_LABEL_DEFERRED_MUSIC_LIST;
455 case ACTION_OK_DL_IMAGES_LIST:
456 return MENU_ENUM_LABEL_DEFERRED_IMAGES_LIST;
457 case ACTION_OK_DL_CDROM_INFO_DETAIL_LIST:
458 return MENU_ENUM_LABEL_DEFERRED_CDROM_INFO_LIST;
459 case ACTION_OK_DL_SHADER_PRESET_SAVE:
460 return MENU_ENUM_LABEL_DEFERRED_VIDEO_SHADER_PRESET_SAVE_LIST;
461 case ACTION_OK_DL_SHADER_PRESET_REMOVE:
462 return MENU_ENUM_LABEL_DEFERRED_VIDEO_SHADER_PRESET_REMOVE_LIST;
463 case ACTION_OK_DL_MANUAL_CONTENT_SCAN_LIST:
464 return MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST;
465 case ACTION_OK_DL_CORE_MANAGER_LIST:
466 return MENU_ENUM_LABEL_DEFERRED_CORE_MANAGER_LIST;
467 case ACTION_OK_DL_CORE_OPTION_OVERRIDE_LIST:
468 return MENU_ENUM_LABEL_DEFERRED_CORE_OPTION_OVERRIDE_LIST;
469 default:
470 break;
471 }
472
473 return MSG_UNKNOWN;
474 }
475
action_ok_get_file_browser_start_path(const char * current_path,const char * default_path,char * start_path,size_t start_path_len,bool set_pending)476 static void action_ok_get_file_browser_start_path(
477 const char *current_path, const char *default_path,
478 char *start_path, size_t start_path_len,
479 bool set_pending)
480 {
481 const char *pending_selection = NULL;
482 bool current_path_valid = false;
483
484 if (!start_path || (start_path_len < 1))
485 return;
486
487 /* Parse current path */
488 if (!string_is_empty(current_path))
489 {
490 /* Start path is the parent directory of
491 * the current path */
492 fill_pathname_parent_dir(start_path, current_path,
493 start_path_len);
494
495 /* 'Pending selection' is the basename of
496 * the current path - either a file name
497 * or a directory name */
498 pending_selection = path_basename(current_path);
499
500 /* Check if current path is valid */
501 if (path_is_directory(start_path) &&
502 !string_is_empty(pending_selection))
503 current_path_valid = true;
504 }
505
506 /* If current path is invalid, use default path */
507 if (!current_path_valid)
508 {
509 if (string_is_empty(default_path) ||
510 !path_is_directory(default_path))
511 {
512 start_path[0] = '\0';
513 return;
514 }
515
516 strlcpy(start_path, default_path, start_path_len);
517 return;
518 }
519 /* Current path is valid - set pending selection,
520 * if required */
521 else if (set_pending)
522 menu_driver_set_pending_selection(pending_selection);
523 }
524
generic_action_ok_displaylist_push(const char * path,const char * new_path,const char * label,unsigned type,size_t idx,size_t entry_idx,unsigned action_type)525 int generic_action_ok_displaylist_push(const char *path,
526 const char *new_path,
527 const char *label, unsigned type, size_t idx, size_t entry_idx,
528 unsigned action_type)
529 {
530 menu_displaylist_info_t info;
531 char tmp[PATH_MAX_LENGTH];
532 char parent_dir[PATH_MAX_LENGTH];
533 enum menu_displaylist_ctl_state dl_type = DISPLAYLIST_NONE;
534 const char *menu_label = NULL;
535 const char *menu_path = NULL;
536 const char *content_path = NULL;
537 const char *info_label = NULL;
538 const char *info_path = NULL;
539 menu_handle_t *menu = menu_driver_get_ptr();
540 settings_t *settings = config_get_ptr();
541 const char *menu_ident = menu_driver_ident();
542 file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(0);
543 #ifdef HAVE_AUDIOMIXER
544 bool audio_enable_menu = settings->bools.audio_enable_menu;
545 bool audio_enable_menu_ok = settings->bools.audio_enable_menu_ok;
546 #endif
547 const char *dir_menu_content = settings->paths.directory_menu_content;
548 const char *dir_libretro = settings->paths.directory_libretro;
549
550 if (!menu || string_is_equal(menu_ident, "null"))
551 {
552 menu_displaylist_info_free(&info);
553 return menu_cbs_exit();
554 }
555
556 #ifdef HAVE_AUDIOMIXER
557 if (audio_enable_menu && audio_enable_menu_ok)
558 audio_driver_mixer_play_menu_sound(AUDIO_MIXER_SYSTEM_SLOT_OK);
559 #endif
560
561 menu_displaylist_info_init(&info);
562
563 info.list = menu_stack;
564
565 tmp[0] = parent_dir[0] = '\0';
566
567 menu_entries_get_last_stack(&menu_path, &menu_label, NULL, NULL, NULL);
568
569 switch (action_type)
570 {
571 case ACTION_OK_DL_BROWSE_URL_START:
572 info.type = type;
573 info.directory_ptr = idx;
574 info_path = NULL;
575 info_label = msg_hash_to_str(
576 MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_START);
577 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_START;
578 dl_type = DISPLAYLIST_GENERIC;
579 break;
580 case ACTION_OK_DL_VIDEO_LIST:
581 info.type = type;
582 info.directory_ptr = idx;
583 info_path = label;
584 info_label = msg_hash_to_str(
585 MENU_ENUM_LABEL_DEFERRED_VIDEO_LIST);
586 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_VIDEO_LIST;
587 dl_type = DISPLAYLIST_GENERIC;
588 break;
589 case ACTION_OK_DL_EXPLORE_LIST:
590 info.type = type;
591 info.directory_ptr = idx;
592 info_path = label;
593 info_label = msg_hash_to_str(
594 MENU_ENUM_LABEL_DEFERRED_EXPLORE_LIST);
595 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_EXPLORE_LIST;
596 dl_type = DISPLAYLIST_GENERIC;
597 break;
598 case ACTION_OK_DL_REMAPPINGS_PORT_LIST:
599 info.type = type;
600 info.directory_ptr = idx;
601 info.path = strdup(label);
602 info_label = msg_hash_to_str(
603 MENU_ENUM_LABEL_DEFERRED_REMAPPINGS_PORT_LIST);
604 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_REMAPPINGS_PORT_LIST;
605 dl_type = DISPLAYLIST_GENERIC;
606 break;
607 case ACTION_OK_DL_DROPDOWN_BOX_LIST:
608 info.type = type;
609 info.directory_ptr = idx;
610 info_path = path;
611 info_label = msg_hash_to_str(
612 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST);
613 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST;
614 dl_type = DISPLAYLIST_GENERIC;
615 break;
616 case ACTION_OK_DL_DROPDOWN_BOX_LIST_SPECIAL:
617 info.type = type;
618 info.directory_ptr = idx;
619 info_path = path;
620 info_label = msg_hash_to_str(
621 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL);
622 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL;
623 dl_type = DISPLAYLIST_GENERIC;
624 break;
625 case ACTION_OK_DL_DROPDOWN_BOX_LIST_SHADER_PARAMETER:
626 info.type = (unsigned)(MENU_SETTINGS_SHADER_PARAMETER_0 + idx);
627 info.directory_ptr = idx;
628 info_path = path;
629 info_label = msg_hash_to_str(
630 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PARAMETER);
631 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PARAMETER;
632 dl_type = DISPLAYLIST_GENERIC;
633 break;
634 case ACTION_OK_DL_DROPDOWN_BOX_LIST_SHADER_PRESET_PARAMETER:
635 info.type = type;
636 info.directory_ptr = idx;
637 info_path = path;
638 info_label = msg_hash_to_str(
639 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PRESET_PARAMETER);
640 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PRESET_PARAMETER;
641 dl_type = DISPLAYLIST_GENERIC;
642 break;
643 case ACTION_OK_DL_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES:
644 info.type = type;
645 info.directory_ptr = idx;
646 info_path = path;
647 info_label = msg_hash_to_str(
648 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES);
649 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES;
650 dl_type = DISPLAYLIST_GENERIC;
651 break;
652 case ACTION_OK_DL_DROPDOWN_BOX_LIST_RESOLUTION:
653 info.type = type;
654 info.directory_ptr = idx;
655 info_path = path;
656 info_label = msg_hash_to_str(
657 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION);
658 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION;
659 dl_type = DISPLAYLIST_GENERIC;
660 break;
661 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE:
662 info.type = type;
663 info.directory_ptr = idx;
664 info_path = path;
665 info_label = msg_hash_to_str(
666 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE);
667 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE;
668 dl_type = DISPLAYLIST_GENERIC;
669 break;
670 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE:
671 info.type = type;
672 info.directory_ptr = idx;
673 info_path = path;
674 info_label = msg_hash_to_str(
675 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE);
676 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE;
677 dl_type = DISPLAYLIST_GENERIC;
678 break;
679 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE:
680 info.type = type;
681 info.directory_ptr = idx;
682 info_path = path;
683 info_label = msg_hash_to_str(
684 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE);
685 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE;
686 dl_type = DISPLAYLIST_GENERIC;
687 break;
688 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
689 info.type = type;
690 info.directory_ptr = idx;
691 info_path = path;
692 info_label = msg_hash_to_str(
693 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE);
694 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE;
695 dl_type = DISPLAYLIST_GENERIC;
696 break;
697 case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE:
698 info.type = type;
699 info.directory_ptr = idx;
700 info_path = path;
701 info_label = msg_hash_to_str(
702 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE);
703 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE;
704 dl_type = DISPLAYLIST_GENERIC;
705 break;
706 case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
707 info.type = type;
708 info.directory_ptr = idx;
709 info_path = path;
710 info_label = msg_hash_to_str(
711 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME);
712 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME;
713 dl_type = DISPLAYLIST_GENERIC;
714 break;
715 case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME:
716 info.type = type;
717 info.directory_ptr = idx;
718 info_path = path;
719 info_label = msg_hash_to_str(
720 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME);
721 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME;
722 dl_type = DISPLAYLIST_GENERIC;
723 break;
724 case ACTION_OK_DL_DROPDOWN_BOX_LIST_DISK_INDEX:
725 info.type = type;
726 info.directory_ptr = idx;
727 info_path = path;
728 info_label = msg_hash_to_str(
729 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX);
730 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_DISK_INDEX;
731 dl_type = DISPLAYLIST_GENERIC;
732 break;
733 case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DEVICE_TYPE:
734 info.type = type;
735 info.directory_ptr = idx;
736 info_path = path;
737 info_label = msg_hash_to_str(
738 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DEVICE_TYPE);
739 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DEVICE_TYPE;
740 dl_type = DISPLAYLIST_GENERIC;
741 break;
742 case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DEVICE_INDEX:
743 info.type = type;
744 info.directory_ptr = idx;
745 info_path = path;
746 info_label = msg_hash_to_str(
747 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DEVICE_INDEX);
748 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DEVICE_INDEX;
749 dl_type = DISPLAYLIST_GENERIC;
750 break;
751 case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION:
752 info.type = type;
753 info.directory_ptr = idx;
754 info_path = path;
755 info_label = msg_hash_to_str(
756 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION);
757 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION;
758 dl_type = DISPLAYLIST_GENERIC;
759 break;
760 case ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD:
761 info.type = type;
762 info.directory_ptr = idx;
763 info_path = path;
764 info_label = msg_hash_to_str(
765 MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD);
766 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD;
767 dl_type = DISPLAYLIST_GENERIC;
768 break;
769 case ACTION_OK_DL_USER_BINDS_LIST:
770 info.type = type;
771 info.directory_ptr = idx;
772 info_path = label;
773 info_label = msg_hash_to_str(
774 MENU_ENUM_LABEL_DEFERRED_USER_BINDS_LIST);
775 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_USER_BINDS_LIST;
776 dl_type = DISPLAYLIST_GENERIC;
777 break;
778 case ACTION_OK_DL_MUSIC:
779 if (!string_is_empty(path))
780 strlcpy(menu->scratch_buf, path, sizeof(menu->scratch_buf));
781 if (!string_is_empty(menu_path))
782 strlcpy(menu->scratch2_buf, menu_path, sizeof(menu->scratch2_buf));
783
784 info_label = msg_hash_to_str(
785 MENU_ENUM_LABEL_DEFERRED_MUSIC);
786 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_MUSIC;
787 info_path = path;
788 info.type = type;
789 info.directory_ptr = idx;
790 dl_type = DISPLAYLIST_GENERIC;
791 break;
792 case ACTION_OK_DL_OPEN_ARCHIVE_DETECT_CORE:
793 if (menu)
794 {
795 menu_path = menu->scratch2_buf;
796 content_path = menu->scratch_buf;
797 }
798 if (content_path)
799 fill_pathname_join(menu->detect_content_path,
800 menu_path, content_path,
801 sizeof(menu->detect_content_path));
802
803 info_label = msg_hash_to_str(
804 MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN_DETECT_CORE);
805 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN_DETECT_CORE;
806 info_path = path;
807 info.type = type;
808 info.directory_ptr = idx;
809 dl_type = DISPLAYLIST_GENERIC;
810 break;
811 case ACTION_OK_DL_OPEN_ARCHIVE:
812 if (menu)
813 {
814 menu_path = menu->scratch2_buf;
815 content_path = menu->scratch_buf;
816 }
817 if (content_path)
818 fill_pathname_join(menu->detect_content_path,
819 menu_path, content_path,
820 sizeof(menu->detect_content_path));
821
822 info_label = msg_hash_to_str(
823 MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN);
824 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN;
825 info_path = path;
826 info.type = type;
827 info.directory_ptr = idx;
828 dl_type = DISPLAYLIST_GENERIC;
829 break;
830 case ACTION_OK_DL_HELP:
831 info_label = label;
832 dl_type = DISPLAYLIST_HELP;
833 menu_dialog_push_pending((enum menu_dialog_type)type);
834 break;
835 case ACTION_OK_DL_RPL_ENTRY:
836 strlcpy(menu->deferred_path, label, sizeof(menu->deferred_path));
837 info_label = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS);
838 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS;
839 info.directory_ptr = idx;
840 menu->rpl_entry_selection_ptr = (unsigned)entry_idx;
841 dl_type = DISPLAYLIST_GENERIC;
842 break;
843 case ACTION_OK_DL_AUDIO_DSP_PLUGIN:
844 filebrowser_clear_type();
845 info.directory_ptr = idx;
846 info_label = msg_hash_to_str(MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN);
847 info.enum_idx = MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN;
848 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
849
850 action_ok_get_file_browser_start_path(
851 settings->paths.path_audio_dsp_plugin,
852 settings->paths.directory_audio_filter,
853 parent_dir, sizeof(parent_dir), true);
854
855 info_path = parent_dir;
856 break;
857 case ACTION_OK_DL_VIDEO_FILTER:
858 filebrowser_clear_type();
859 info.directory_ptr = idx;
860 info_label = msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_FILTER);
861 info.enum_idx = MENU_ENUM_LABEL_VIDEO_FILTER;
862 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
863
864 action_ok_get_file_browser_start_path(
865 settings->paths.path_softfilter_plugin,
866 settings->paths.directory_video_filter,
867 parent_dir, sizeof(parent_dir), true);
868
869 info_path = parent_dir;
870 break;
871 case ACTION_OK_DL_OVERLAY_PRESET:
872 filebrowser_clear_type();
873 info.directory_ptr = idx;
874 info_label = msg_hash_to_str(MENU_ENUM_LABEL_OVERLAY_PRESET);
875 info.enum_idx = MENU_ENUM_LABEL_OVERLAY_PRESET;
876 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
877
878 action_ok_get_file_browser_start_path(
879 settings->paths.path_overlay,
880 settings->paths.directory_overlay,
881 parent_dir, sizeof(parent_dir), true);
882
883 info_path = parent_dir;
884 break;
885 #if defined(HAVE_VIDEO_LAYOUT)
886 case ACTION_OK_DL_VIDEO_LAYOUT:
887 filebrowser_clear_type();
888 info.directory_ptr = idx;
889 info_label = msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_LAYOUT_PATH);
890 info.enum_idx = MENU_ENUM_LABEL_VIDEO_LAYOUT_PATH;
891 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
892
893 action_ok_get_file_browser_start_path(
894 settings->paths.path_video_layout,
895 settings->paths.directory_video_layout,
896 parent_dir, sizeof(parent_dir), true);
897
898 info_path = parent_dir;
899 break;
900 #endif
901 case ACTION_OK_DL_VIDEO_FONT:
902 filebrowser_set_type(FILEBROWSER_SELECT_VIDEO_FONT);
903 info.directory_ptr = idx;
904 info_label = msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_FONT_PATH);
905 info.enum_idx = MENU_ENUM_LABEL_VIDEO_FONT_PATH;
906 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
907
908 action_ok_get_file_browser_start_path(
909 settings->paths.path_font,
910 NULL,
911 parent_dir, sizeof(parent_dir), true);
912
913 info_path = parent_dir;
914 break;
915 case ACTION_OK_DL_SHADER_PARAMETERS:
916 info.type = MENU_SETTING_ACTION;
917 info.directory_ptr = idx;
918 info_label = label;
919 dl_type = DISPLAYLIST_GENERIC;
920 break;
921 case ACTION_OK_DL_GENERIC:
922 if (path)
923 strlcpy(menu->deferred_path, path,
924 sizeof(menu->deferred_path));
925
926 info.type = type;
927 info.directory_ptr = idx;
928 info_label = label;
929 dl_type = DISPLAYLIST_GENERIC;
930 break;
931 case ACTION_OK_DL_FILE_BROWSER_SELECT_FILE:
932 if (path)
933 strlcpy(menu->deferred_path, path,
934 sizeof(menu->deferred_path));
935
936 info.type = type;
937 info.directory_ptr = idx;
938 info_label = label;
939 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
940 break;
941 case ACTION_OK_DL_FILE_BROWSER_SELECT_DIR:
942 if (path)
943 strlcpy(menu->deferred_path, path,
944 sizeof(menu->deferred_path));
945
946 info.type = type;
947 info.directory_ptr = idx;
948 info_label = label;
949 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_DIR;
950 break;
951 case ACTION_OK_DL_PUSH_DEFAULT:
952 info.type = type;
953 info.directory_ptr = idx;
954 info_path = label;
955 info_label = label;
956 dl_type = DISPLAYLIST_GENERIC;
957 break;
958 case ACTION_OK_DL_SHADER_PASS:
959 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
960 {
961 const char *shader_file_name = NULL;
962
963 filebrowser_clear_type();
964 info.type = type;
965 info.directory_ptr = idx;
966 info_label = label;
967 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
968
969 menu_driver_get_last_shader_pass_path(&info_path, &shader_file_name);
970 menu_driver_set_pending_selection(shader_file_name);
971 }
972 #endif
973 break;
974 case ACTION_OK_DL_SHADER_PRESET:
975 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
976 {
977 const char *shader_file_name = NULL;
978
979 filebrowser_clear_type();
980 info.type = type;
981 info.directory_ptr = idx;
982 info_label = label;
983 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
984
985 menu_driver_get_last_shader_preset_path(&info_path, &shader_file_name);
986 menu_driver_set_pending_selection(shader_file_name);
987 }
988 #endif
989 break;
990 case ACTION_OK_DL_CONTENT_LIST:
991 info.type = FILE_TYPE_DIRECTORY;
992 info.directory_ptr = idx;
993 info_path = new_path;
994 info_label = label;
995 dl_type = DISPLAYLIST_GENERIC;
996
997 /* If this is the 'Start Directory' content
998 * list, use last selected directory/file */
999 if ((type == MENU_SETTING_ACTION_FAVORITES_DIR) &&
1000 settings->bools.use_last_start_directory)
1001 {
1002 info_path = menu_driver_get_last_start_directory();
1003 menu_driver_set_pending_selection(menu_driver_get_last_start_file_name());
1004 }
1005
1006 break;
1007 case ACTION_OK_DL_SCAN_DIR_LIST:
1008 filebrowser_set_type(FILEBROWSER_SCAN_DIR);
1009 info.type = FILE_TYPE_DIRECTORY;
1010 info.directory_ptr = idx;
1011 info_path = new_path;
1012 info_label = label;
1013 dl_type = DISPLAYLIST_FILE_BROWSER_SCAN_DIR;
1014 break;
1015 case ACTION_OK_DL_MANUAL_SCAN_DIR_LIST:
1016 filebrowser_set_type(FILEBROWSER_MANUAL_SCAN_DIR);
1017 info.type = FILE_TYPE_DIRECTORY;
1018 info.directory_ptr = idx;
1019 info_label = label;
1020 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_DIR;
1021
1022 action_ok_get_file_browser_start_path(
1023 manual_content_scan_get_content_dir_ptr(),
1024 new_path, parent_dir, sizeof(parent_dir), true);
1025
1026 info_path = parent_dir;
1027 break;
1028 case ACTION_OK_DL_MANUAL_CONTENT_SCAN_DAT_FILE:
1029 filebrowser_clear_type();
1030 info.type = type;
1031 info.directory_ptr = idx;
1032 info_label = label;
1033 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
1034
1035 action_ok_get_file_browser_start_path(
1036 manual_content_scan_get_dat_file_path_ptr(),
1037 dir_menu_content, parent_dir, sizeof(parent_dir), true);
1038
1039 info_path = parent_dir;
1040 break;
1041 case ACTION_OK_DL_REMAP_FILE:
1042 {
1043 struct retro_system_info *system = runloop_get_libretro_system_info();
1044 const char *core_name = system ? system->library_name : NULL;
1045
1046 if (!string_is_empty(core_name) && !string_is_empty(settings->paths.directory_input_remapping))
1047 {
1048 fill_pathname_join(tmp,
1049 settings->paths.directory_input_remapping, core_name, sizeof(tmp));
1050 if (!path_is_directory(tmp))
1051 tmp[0] = '\0';
1052 }
1053
1054 filebrowser_clear_type();
1055 info.type = type;
1056 info.directory_ptr = idx;
1057 info_path = !string_is_empty(tmp) ? tmp : settings->paths.directory_input_remapping;
1058 info_label = label;
1059 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
1060 }
1061 break;
1062 case ACTION_OK_DL_STREAM_CONFIGFILE:
1063 {
1064 global_t *global = global_get_ptr();
1065 info.type = type;
1066 info.directory_ptr = idx;
1067 info_path = global->record.config_dir;
1068 info_label = label;
1069 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
1070 }
1071 break;
1072 case ACTION_OK_DL_RECORD_CONFIGFILE:
1073 filebrowser_clear_type();
1074 {
1075 global_t *global = global_get_ptr();
1076 info.type = type;
1077 info.directory_ptr = idx;
1078 info_path = global->record.config_dir;
1079 info_label = label;
1080 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
1081 }
1082 break;
1083 case ACTION_OK_DL_DISK_IMAGE_APPEND_LIST:
1084 {
1085 filebrowser_clear_type();
1086 strlcpy(tmp, path_get(RARCH_PATH_CONTENT), sizeof(tmp));
1087 path_basedir(tmp);
1088
1089 info.type = type;
1090 info.directory_ptr = idx;
1091 info_path = !string_is_empty(tmp) ? tmp : dir_menu_content;
1092 info_label = label;
1093 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
1094 }
1095 break;
1096 case ACTION_OK_DL_SUBSYSTEM_ADD_LIST:
1097 {
1098 filebrowser_clear_type();
1099 if (content_get_subsystem_rom_id() > 0)
1100 strlcpy(tmp, content_get_subsystem_rom(content_get_subsystem_rom_id() - 1), sizeof(tmp));
1101 else
1102 strlcpy(tmp, path_get(RARCH_PATH_CONTENT), sizeof(tmp));
1103 path_basedir(tmp);
1104
1105 if (content_get_subsystem() != type - MENU_SETTINGS_SUBSYSTEM_ADD)
1106 content_clear_subsystem();
1107 content_set_subsystem(type - MENU_SETTINGS_SUBSYSTEM_ADD);
1108 filebrowser_set_type(FILEBROWSER_SELECT_FILE_SUBSYSTEM);
1109 info.type = type;
1110 info.directory_ptr = idx;
1111 info_path = !string_is_empty(tmp) ? tmp : dir_menu_content;
1112 info_label = label;
1113 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
1114 }
1115 break;
1116 case ACTION_OK_DL_SUBSYSTEM_LOAD:
1117 {
1118 content_ctx_info_t content_info = {0};
1119 filebrowser_clear_type();
1120 task_push_load_subsystem_with_core_from_menu(
1121 NULL, &content_info,
1122 CORE_TYPE_PLAIN, NULL, NULL);
1123 }
1124 break;
1125 case ACTION_OK_DL_CHEAT_FILE:
1126 case ACTION_OK_DL_CHEAT_FILE_APPEND:
1127 #ifdef HAVE_CHEATS
1128 filebrowser_clear_type();
1129 info.type = type;
1130 info.directory_ptr = idx;
1131 info_path = settings->paths.path_cheat_database;
1132 info_label = label;
1133 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
1134 #endif
1135 break;
1136 case ACTION_OK_DL_RGUI_MENU_THEME_PRESET:
1137 {
1138 char rgui_assets_dir[PATH_MAX_LENGTH];
1139 rgui_assets_dir[0] = '\0';
1140
1141 filebrowser_clear_type();
1142 info.type = type;
1143 info.directory_ptr = idx;
1144 info_label = label;
1145 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
1146
1147 fill_pathname_join(rgui_assets_dir,
1148 settings->paths.directory_assets, "rgui",
1149 sizeof(rgui_assets_dir));
1150
1151 action_ok_get_file_browser_start_path(
1152 settings->paths.path_rgui_theme_preset,
1153 rgui_assets_dir,
1154 parent_dir, sizeof(parent_dir), true);
1155
1156 info_path = parent_dir;
1157 }
1158 break;
1159 case ACTION_OK_DL_CORE_LIST:
1160 filebrowser_clear_type();
1161 info.type = type;
1162 info.directory_ptr = idx;
1163 info_path = dir_libretro;
1164 info_label = label;
1165 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_CORE;
1166 break;
1167 case ACTION_OK_DL_SIDELOAD_CORE_LIST:
1168 filebrowser_clear_type();
1169 info.type = type;
1170 info.directory_ptr = idx;
1171 info_path = settings->paths.directory_core_assets;
1172 info_label = label;
1173 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_FILE;
1174 break;
1175 case ACTION_OK_DL_CONTENT_COLLECTION_LIST:
1176 info.type = type;
1177 info.directory_ptr = idx;
1178 info_path = settings->paths.directory_playlist;
1179 info_label = label;
1180 dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_COLLECTION;
1181 break;
1182 case ACTION_OK_DL_RDB_ENTRY:
1183 filebrowser_clear_type();
1184 fill_pathname_join_delim(tmp,
1185 msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RDB_ENTRY_DETAIL),
1186 path, '|', sizeof(tmp));
1187
1188 info.directory_ptr = idx;
1189 info_path = label;
1190 info_label = tmp;
1191 dl_type = DISPLAYLIST_GENERIC;
1192 break;
1193 case ACTION_OK_DL_RDB_ENTRY_SUBMENU:
1194 info.directory_ptr = idx;
1195 info_label = label;
1196 info_path = path;
1197 dl_type = DISPLAYLIST_GENERIC;
1198 break;
1199 case ACTION_OK_DL_CONFIGURATIONS_LIST:
1200 info.type = type;
1201 info.directory_ptr = idx;
1202 if (string_is_empty(settings->paths.directory_menu_config))
1203 info_path = label;
1204 else
1205 info_path = settings->paths.directory_menu_config;
1206 info_label = label;
1207 dl_type = DISPLAYLIST_GENERIC;
1208 break;
1209 case ACTION_OK_DL_COMPRESSED_ARCHIVE_PUSH_DETECT_CORE:
1210 info.type = type;
1211 info.directory_ptr = idx;
1212 info_path = path;
1213 info_label = msg_hash_to_str(
1214 MENU_ENUM_LABEL_DEFERRED_ARCHIVE_ACTION_DETECT_CORE);
1215 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_ARCHIVE_ACTION_DETECT_CORE;
1216
1217 if (!string_is_empty(path))
1218 strlcpy(menu->scratch_buf, path, sizeof(menu->scratch_buf));
1219 if (!string_is_empty(menu_path))
1220 strlcpy(menu->scratch2_buf, menu_path, sizeof(menu->scratch2_buf));
1221 dl_type = DISPLAYLIST_GENERIC;
1222 break;
1223 case ACTION_OK_DL_COMPRESSED_ARCHIVE_PUSH:
1224 info.type = type;
1225 info.directory_ptr = idx;
1226 info_path = path;
1227 info_label = msg_hash_to_str(
1228 MENU_ENUM_LABEL_DEFERRED_ARCHIVE_ACTION);
1229 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_ARCHIVE_ACTION;
1230
1231 if (!string_is_empty(path))
1232 strlcpy(menu->scratch_buf, path, sizeof(menu->scratch_buf));
1233 if (!string_is_empty(menu_path))
1234 strlcpy(menu->scratch2_buf, menu_path, sizeof(menu->scratch2_buf));
1235 dl_type = DISPLAYLIST_GENERIC;
1236 break;
1237 case ACTION_OK_DL_PARENT_DIRECTORY_PUSH:
1238 parent_dir[0] = '\0';
1239
1240 if (path && menu_path)
1241 fill_pathname_join(tmp,
1242 menu_path, path, sizeof(tmp));
1243
1244 fill_pathname_parent_dir(parent_dir,
1245 tmp, sizeof(parent_dir));
1246 fill_pathname_parent_dir(parent_dir,
1247 parent_dir, sizeof(parent_dir));
1248
1249 info.type = type;
1250 info.directory_ptr = idx;
1251 info_path = parent_dir;
1252 info_label = menu_label;
1253 dl_type = DISPLAYLIST_GENERIC;
1254 break;
1255 case ACTION_OK_DL_DIRECTORY_PUSH:
1256 if (!string_is_empty(path))
1257 {
1258 if (!string_is_empty(menu_path))
1259 fill_pathname_join(
1260 tmp, menu_path, path, sizeof(tmp));
1261 else
1262 strlcpy(tmp, path, sizeof(tmp));
1263 }
1264
1265 info.type = type;
1266 info.directory_ptr = idx;
1267 info_path = tmp;
1268 info_label = menu_label;
1269 dl_type = DISPLAYLIST_GENERIC;
1270 break;
1271 case ACTION_OK_DL_DATABASE_MANAGER_LIST:
1272 {
1273 char lpl_basename[PATH_MAX_LENGTH];
1274 lpl_basename[0] = '\0';
1275 filebrowser_clear_type();
1276 fill_pathname_join(tmp,
1277 settings->paths.path_content_database,
1278 path, sizeof(tmp));
1279
1280 fill_pathname_base_noext(lpl_basename, path, sizeof(lpl_basename));
1281 menu_driver_set_thumbnail_system(lpl_basename, sizeof(lpl_basename));
1282
1283 info.directory_ptr = idx;
1284 info_path = tmp;
1285 info_label = msg_hash_to_str(
1286 MENU_ENUM_LABEL_DEFERRED_DATABASE_MANAGER_LIST);
1287 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DATABASE_MANAGER_LIST;
1288 dl_type = DISPLAYLIST_GENERIC;
1289 }
1290 break;
1291 case ACTION_OK_DL_CURSOR_MANAGER_LIST:
1292 filebrowser_clear_type();
1293 fill_pathname_join(tmp, settings->paths.directory_cursor,
1294 path, sizeof(tmp));
1295
1296 info.directory_ptr = idx;
1297 info_path = tmp;
1298 info_label = msg_hash_to_str(
1299 MENU_ENUM_LABEL_DEFERRED_CURSOR_MANAGER_LIST);
1300 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_CURSOR_MANAGER_LIST;
1301 dl_type = DISPLAYLIST_GENERIC;
1302 break;
1303 /* Pending clear */
1304 case ACTION_OK_DL_CORE_UPDATER_LIST:
1305 info.type = type;
1306 info.directory_ptr = idx;
1307 info_path = path;
1308 info_label = msg_hash_to_str(
1309 MENU_ENUM_LABEL_DEFERRED_CORE_UPDATER_LIST);
1310 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_CORE_UPDATER_LIST;
1311 dl_type = DISPLAYLIST_PENDING_CLEAR;
1312 break;
1313 case ACTION_OK_DL_THUMBNAILS_UPDATER_LIST:
1314 info.type = type;
1315 info.directory_ptr = idx;
1316 info_path = path;
1317 info_label = msg_hash_to_str(
1318 MENU_ENUM_LABEL_DEFERRED_THUMBNAILS_UPDATER_LIST);
1319 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_THUMBNAILS_UPDATER_LIST;
1320 dl_type = DISPLAYLIST_PENDING_CLEAR;
1321 break;
1322 case ACTION_OK_DL_PL_THUMBNAILS_UPDATER_LIST:
1323 info.type = type;
1324 info.directory_ptr = idx;
1325 info_path = path;
1326 info_label = msg_hash_to_str(
1327 MENU_ENUM_LABEL_DEFERRED_PL_THUMBNAILS_UPDATER_LIST);
1328 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_PL_THUMBNAILS_UPDATER_LIST;
1329 dl_type = DISPLAYLIST_PENDING_CLEAR;
1330 break;
1331 case ACTION_OK_DL_CORE_CONTENT_DIRS_LIST:
1332 info.type = type;
1333 info.directory_ptr = idx;
1334 info_path = path;
1335 info_label = msg_hash_to_str(
1336 MENU_ENUM_LABEL_DEFERRED_CORE_CONTENT_DIRS_LIST);
1337 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_CORE_CONTENT_DIRS_LIST;
1338 dl_type = DISPLAYLIST_PENDING_CLEAR;
1339 break;
1340 case ACTION_OK_DL_CORE_CONTENT_LIST:
1341 info.type = type;
1342 info.directory_ptr = idx;
1343 info_path = path;
1344 info_label = msg_hash_to_str(
1345 MENU_ENUM_LABEL_DEFERRED_CORE_CONTENT_LIST);
1346 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_CORE_CONTENT_LIST;
1347 dl_type = DISPLAYLIST_PENDING_CLEAR;
1348 break;
1349 case ACTION_OK_DL_LAKKA_LIST:
1350 info.type = type;
1351 info.directory_ptr = idx;
1352 info_path = path;
1353 info_label = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_LAKKA_LIST);
1354 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_LAKKA_LIST;
1355 dl_type = DISPLAYLIST_PENDING_CLEAR;
1356 break;
1357
1358 case ACTION_OK_DL_CORE_CONTENT_DIRS_SUBDIR_LIST:
1359 fill_pathname_join_delim(tmp, path, label, ';',
1360 sizeof(tmp));
1361 info.type = type;
1362 info.directory_ptr = idx;
1363 info_path = tmp;
1364 info_label = msg_hash_to_str(
1365 MENU_ENUM_LABEL_DEFERRED_CORE_CONTENT_DIRS_SUBDIR_LIST);
1366 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_CORE_CONTENT_DIRS_SUBDIR_LIST;
1367 dl_type = DISPLAYLIST_GENERIC;
1368 break;
1369 case ACTION_OK_DL_DEFERRED_CORE_LIST:
1370 info.directory_ptr = idx;
1371 info_path = dir_libretro;
1372 info_label = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CORE_LIST);
1373 info.enum_idx = MENU_ENUM_LABEL_DEFERRED_CORE_LIST;
1374 dl_type = DISPLAYLIST_GENERIC;
1375 break;
1376 case ACTION_OK_DL_DEFERRED_CORE_LIST_SET:
1377 info.directory_ptr = idx;
1378 menu->scratchpad.unsigned_var = (unsigned)idx;
1379 info_path = dir_libretro;
1380 info_label = msg_hash_to_str(
1381 MENU_ENUM_LABEL_DEFERRED_CORE_LIST_SET);
1382 info.enum_idx =
1383 MENU_ENUM_LABEL_DEFERRED_CORE_LIST_SET;
1384 dl_type = DISPLAYLIST_GENERIC;
1385 break;
1386 case ACTION_OK_DL_CHEAT_DETAILS_SETTINGS_LIST:
1387 #ifdef HAVE_CHEATS
1388 {
1389 rarch_setting_t *setting = NULL;
1390
1391 cheat_manager_copy_idx_to_working(type-MENU_SETTINGS_CHEAT_BEGIN);
1392 setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_IDX);
1393 if (setting)
1394 setting->max = cheat_manager_get_size()-1;
1395 setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_VALUE);
1396 if (setting)
1397 setting->max = cheat_manager_get_state_search_size(cheat_manager_state.working_cheat.memory_search_size);
1398 setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_RUMBLE_VALUE);
1399 if (setting)
1400 setting->max = cheat_manager_get_state_search_size(cheat_manager_state.working_cheat.memory_search_size);
1401 setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_ADDRESS_BIT_POSITION);
1402 if (setting)
1403 {
1404 int max_bit_position = cheat_manager_state.working_cheat.memory_search_size<3 ? 7 : 0;
1405 setting->max = max_bit_position;
1406 }
1407 setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_ADDRESS);
1408 if (setting)
1409 cheat_manager_state.browse_address = *setting->value.target.unsigned_integer;
1410 ACTION_OK_DL_LBL(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC);
1411 }
1412 #endif
1413 break;
1414 case ACTION_OK_DL_CHEAT_SEARCH_SETTINGS_LIST:
1415 #ifdef HAVE_CHEATS
1416 {
1417 rarch_setting_t *setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_SEARCH_EXACT);
1418 if (setting)
1419 setting->max = cheat_manager_get_state_search_size(cheat_manager_state.search_bit_size);
1420 setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_SEARCH_EQPLUS);
1421 if (setting)
1422 setting->max = cheat_manager_get_state_search_size(cheat_manager_state.search_bit_size);
1423 setting = menu_setting_find_enum(MENU_ENUM_LABEL_CHEAT_SEARCH_EQMINUS);
1424 if (setting)
1425 setting->max = cheat_manager_get_state_search_size(cheat_manager_state.search_bit_size);
1426 ACTION_OK_DL_LBL(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC);
1427 }
1428 #endif
1429 break;
1430 case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST:
1431 {
1432 unsigned player_no = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN;
1433 ACTION_OK_DL_LBL(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC);
1434 info.type = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_BEGIN + player_no;
1435 }
1436 break;
1437 case ACTION_OK_DL_ACCOUNTS_LIST:
1438 case ACTION_OK_DL_ACHIEVEMENTS_HARDCORE_PAUSE_LIST:
1439 case ACTION_OK_DL_INPUT_SETTINGS_LIST:
1440 case ACTION_OK_DL_INPUT_MENU_SETTINGS_LIST:
1441 case ACTION_OK_DL_INPUT_TURBO_FIRE_SETTINGS_LIST:
1442 case ACTION_OK_DL_INPUT_HAPTIC_FEEDBACK_SETTINGS_LIST:
1443 case ACTION_OK_DL_LATENCY_SETTINGS_LIST:
1444 case ACTION_OK_DL_DRIVER_SETTINGS_LIST:
1445 case ACTION_OK_DL_CORE_SETTINGS_LIST:
1446 case ACTION_OK_DL_CORE_INFORMATION_LIST:
1447 case ACTION_OK_DL_VIDEO_SETTINGS_LIST:
1448 case ACTION_OK_DL_VIDEO_SYNCHRONIZATION_SETTINGS_LIST:
1449 case ACTION_OK_DL_VIDEO_FULLSCREEN_MODE_SETTINGS_LIST:
1450 case ACTION_OK_DL_VIDEO_WINDOWED_MODE_SETTINGS_LIST:
1451 case ACTION_OK_DL_VIDEO_SCALING_SETTINGS_LIST:
1452 case ACTION_OK_DL_VIDEO_OUTPUT_SETTINGS_LIST:
1453 case ACTION_OK_DL_CRT_SWITCHRES_SETTINGS_LIST:
1454 case ACTION_OK_DL_CONFIGURATION_SETTINGS_LIST:
1455 case ACTION_OK_DL_SAVING_SETTINGS_LIST:
1456 case ACTION_OK_DL_LOGGING_SETTINGS_LIST:
1457 case ACTION_OK_DL_FRAME_THROTTLE_SETTINGS_LIST:
1458 case ACTION_OK_DL_FRAME_TIME_COUNTER_SETTINGS_LIST:
1459 case ACTION_OK_DL_REWIND_SETTINGS_LIST:
1460 case ACTION_OK_DL_ONSCREEN_DISPLAY_SETTINGS_LIST:
1461 case ACTION_OK_DL_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST:
1462 case ACTION_OK_DL_ONSCREEN_NOTIFICATIONS_VIEWS_SETTINGS_LIST:
1463 case ACTION_OK_DL_ONSCREEN_OVERLAY_SETTINGS_LIST:
1464 #ifdef HAVE_VIDEO_LAYOUT
1465 case ACTION_OK_DL_ONSCREEN_VIDEO_LAYOUT_SETTINGS_LIST:
1466 #endif
1467 case ACTION_OK_DL_MENU_SETTINGS_LIST:
1468 case ACTION_OK_DL_MENU_VIEWS_SETTINGS_LIST:
1469 case ACTION_OK_DL_SETTINGS_VIEWS_SETTINGS_LIST:
1470 case ACTION_OK_DL_QUICK_MENU_VIEWS_SETTINGS_LIST:
1471 case ACTION_OK_DL_QUICK_MENU_OVERRIDE_OPTIONS_LIST:
1472 case ACTION_OK_DL_USER_INTERFACE_SETTINGS_LIST:
1473 case ACTION_OK_DL_AI_SERVICE_SETTINGS_LIST:
1474 case ACTION_OK_DL_ACCESSIBILITY_SETTINGS_LIST:
1475 case ACTION_OK_DL_POWER_MANAGEMENT_SETTINGS_LIST:
1476 case ACTION_OK_DL_CPU_PERFPOWER_SETTINGS_LIST:
1477 case ACTION_OK_DL_CPU_POLICY_SETTINGS_LIST:
1478 case ACTION_OK_DL_MENU_SOUNDS_LIST:
1479 case ACTION_OK_DL_MENU_FILE_BROWSER_SETTINGS_LIST:
1480 case ACTION_OK_DL_RETRO_ACHIEVEMENTS_SETTINGS_LIST:
1481 case ACTION_OK_DL_UPDATER_SETTINGS_LIST:
1482 case ACTION_OK_DL_NETWORK_SETTINGS_LIST:
1483 case ACTION_OK_DL_NETWORK_HOSTING_SETTINGS_LIST:
1484 case ACTION_OK_DL_SUBSYSTEM_SETTINGS_LIST:
1485 case ACTION_OK_DL_BLUETOOTH_SETTINGS_LIST:
1486 case ACTION_OK_DL_WIFI_SETTINGS_LIST:
1487 case ACTION_OK_DL_WIFI_NETWORKS_LIST:
1488 case ACTION_OK_DL_NETPLAY:
1489 case ACTION_OK_DL_NETPLAY_LAN_SCAN_SETTINGS_LIST:
1490 case ACTION_OK_DL_LAKKA_SERVICES_LIST:
1491 case ACTION_OK_DL_USER_SETTINGS_LIST:
1492 case ACTION_OK_DL_DIRECTORY_SETTINGS_LIST:
1493 case ACTION_OK_DL_PRIVACY_SETTINGS_LIST:
1494 case ACTION_OK_DL_MIDI_SETTINGS_LIST:
1495 case ACTION_OK_DL_AUDIO_SETTINGS_LIST:
1496 case ACTION_OK_DL_AUDIO_SYNCHRONIZATION_SETTINGS_LIST:
1497 case ACTION_OK_DL_AUDIO_OUTPUT_SETTINGS_LIST:
1498 case ACTION_OK_DL_AUDIO_RESAMPLER_SETTINGS_LIST:
1499 case ACTION_OK_DL_AUDIO_MIXER_SETTINGS_LIST:
1500 case ACTION_OK_DL_INPUT_HOTKEY_BINDS_LIST:
1501 case ACTION_OK_DL_RECORDING_SETTINGS_LIST:
1502 case ACTION_OK_DL_PLAYLIST_SETTINGS_LIST:
1503 case ACTION_OK_DL_PLAYLIST_MANAGER_LIST:
1504 case ACTION_OK_DL_PLAYLIST_MANAGER_SETTINGS:
1505 case ACTION_OK_DL_ACCOUNTS_CHEEVOS_LIST:
1506 case ACTION_OK_DL_ACCOUNTS_YOUTUBE_LIST:
1507 case ACTION_OK_DL_ACCOUNTS_TWITCH_LIST:
1508 case ACTION_OK_DL_ACCOUNTS_FACEBOOK_LIST:
1509 case ACTION_OK_DL_PLAYLIST_COLLECTION:
1510 case ACTION_OK_DL_FAVORITES_LIST:
1511 case ACTION_OK_DL_BROWSE_URL_LIST:
1512 case ACTION_OK_DL_MUSIC_LIST:
1513 case ACTION_OK_DL_IMAGES_LIST:
1514 case ACTION_OK_DL_LOAD_DISC_LIST:
1515 case ACTION_OK_DL_DUMP_DISC_LIST:
1516 case ACTION_OK_DL_SHADER_PRESET_REMOVE:
1517 case ACTION_OK_DL_SHADER_PRESET_SAVE:
1518 case ACTION_OK_DL_CDROM_INFO_LIST:
1519 case ACTION_OK_DL_MANUAL_CONTENT_SCAN_LIST:
1520 case ACTION_OK_DL_CORE_MANAGER_LIST:
1521 case ACTION_OK_DL_CORE_OPTION_OVERRIDE_LIST:
1522 ACTION_OK_DL_LBL(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC);
1523 break;
1524 case ACTION_OK_DL_CDROM_INFO_DETAIL_LIST:
1525 case ACTION_OK_DL_CORE_RESTORE_BACKUP_LIST:
1526 case ACTION_OK_DL_CORE_DELETE_BACKUP_LIST:
1527 ACTION_OK_DL_LBL(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC);
1528 info_path = label;
1529 break;
1530 case ACTION_OK_DL_CONTENT_SETTINGS:
1531 info.list = menu_entries_get_selection_buf_ptr(0);
1532 info_path = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS);
1533 info_label = msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_SETTINGS);
1534 info.enum_idx = MENU_ENUM_LABEL_CONTENT_SETTINGS;
1535 menu_entries_append_enum(menu_stack, info_path, info_label,
1536 MENU_ENUM_LABEL_CONTENT_SETTINGS,
1537 0, 0, 0);
1538 dl_type = DISPLAYLIST_CONTENT_SETTINGS;
1539 break;
1540 }
1541
1542 if (info_label)
1543 info.label = strdup(info_label);
1544 if (info_path)
1545 info.path = strdup(info_path);
1546
1547 if (menu_displaylist_ctl(dl_type, &info, settings))
1548 {
1549 if (menu_displaylist_process(&info))
1550 {
1551 menu_displaylist_info_free(&info);
1552 return 0;
1553 }
1554 }
1555
1556 menu_displaylist_info_free(&info);
1557 return menu_cbs_exit();
1558 }
1559
1560 /**
1561 * menu_content_find_first_core:
1562 * @core_info : Core info list handle.
1563 * @dir : Directory. Gets joined with @path.
1564 * @path : Path. Gets joined with @dir.
1565 * @menu_label : Label identifier of menu setting.
1566 * @s : Deferred core path. Will be filled in
1567 * by function.
1568 * @len : Size of @s.
1569 *
1570 * Gets deferred core.
1571 *
1572 * Returns: false if there are multiple deferred cores and a
1573 * selection needs to be made from a list, otherwise
1574 * returns true and fills in @s with path to core.
1575 **/
menu_content_find_first_core(menu_content_ctx_defer_info_t * def_info,bool load_content_with_current_core,char * new_core_path,size_t len)1576 static bool menu_content_find_first_core(menu_content_ctx_defer_info_t *def_info,
1577 bool load_content_with_current_core,
1578 char *new_core_path, size_t len)
1579 {
1580 const core_info_t *info = NULL;
1581 size_t supported = 0;
1582 core_info_list_t *core_info = (core_info_list_t*)def_info->data;
1583 const char *default_info_dir = def_info->dir;
1584
1585 if (!string_is_empty(default_info_dir))
1586 {
1587 const char *default_info_path = def_info->path;
1588 size_t default_info_length = def_info->len;
1589
1590 if (!string_is_empty(default_info_path))
1591 fill_pathname_join(def_info->s,
1592 default_info_dir, default_info_path,
1593 default_info_length);
1594
1595 #ifdef HAVE_COMPRESSION
1596 if (path_is_compressed_file(default_info_dir))
1597 {
1598 size_t _len = strlen(default_info_dir);
1599 /* In case of a compressed archive, we have to join with a hash */
1600 /* We are going to write at the position of dir: */
1601 def_info->s[_len] = '#';
1602 }
1603 #endif
1604 }
1605
1606 if (core_info)
1607 core_info_list_get_supported_cores(core_info,
1608 def_info->s, &info,
1609 &supported);
1610
1611 /* We started the menu with 'Load Content', we are
1612 * going to use the current core to load this. */
1613 if (load_content_with_current_core)
1614 {
1615 core_info_get_current_core((core_info_t**)&info);
1616 if (info)
1617 {
1618 #if 0
1619 RARCH_LOG("[lobby] use the current core (%s) to load this content...\n",
1620 info->path);
1621 #endif
1622 supported = 1;
1623 }
1624 }
1625
1626 /* There are multiple deferred cores and a
1627 * selection needs to be made from a list, return 0. */
1628 if (supported != 1)
1629 return false;
1630
1631 if (info)
1632 strlcpy(new_core_path, info->path, len);
1633
1634 return true;
1635 }
1636
1637 #ifdef HAVE_LIBRETRODB
1638 void handle_dbscan_finished(retro_task_t *task,
1639 void *task_data, void *user_data, const char *err);
1640 #endif
1641
content_add_to_playlist(const char * path)1642 static void content_add_to_playlist(const char *path)
1643 {
1644 #if 0
1645 #ifdef HAVE_LIBRETRODB
1646 settings_t *settings = config_get_ptr();
1647 if (!settings || !settings->bools.automatically_add_content_to_playlist)
1648 return;
1649 task_push_dbscan(
1650 settings->paths.directory_playlist,
1651 settings->paths.path_content_database,
1652 path, false,
1653 settings->bools.show_hidden_files,
1654 handle_dbscan_finished);
1655 #endif
1656 #endif
1657 }
1658
file_load_with_detect_core_wrapper(enum msg_hash_enums enum_label_idx,size_t idx,size_t entry_idx,const char * path,const char * label,unsigned type,bool is_carchive)1659 static int file_load_with_detect_core_wrapper(
1660 enum msg_hash_enums enum_label_idx,
1661 size_t idx, size_t entry_idx,
1662 const char *path, const char *label,
1663 unsigned type, bool is_carchive)
1664 {
1665 int ret = 0;
1666 menu_handle_t *menu = menu_driver_get_ptr();
1667
1668 if (!menu)
1669 return menu_cbs_exit();
1670
1671 {
1672 menu_content_ctx_defer_info_t def_info;
1673 char menu_path_new[PATH_MAX_LENGTH];
1674 char new_core_path[PATH_MAX_LENGTH];
1675 const char *menu_path = NULL;
1676 const char *menu_label = NULL;
1677 core_info_list_t *list = NULL;
1678 new_core_path[0] = menu_path_new[0] = '\0';
1679
1680 menu_entries_get_last_stack(&menu_path, &menu_label, NULL, NULL, NULL);
1681
1682 if (!string_is_empty(menu_path))
1683 strlcpy(menu_path_new, menu_path, sizeof(menu_path_new));
1684
1685 if (string_is_equal(menu_label,
1686 msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN_DETECT_CORE)))
1687 fill_pathname_join(menu_path_new,
1688 menu->scratch2_buf, menu->scratch_buf, sizeof(menu_path_new));
1689 else if (string_is_equal(menu_label,
1690 msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN)))
1691 fill_pathname_join(menu_path_new,
1692 menu->scratch2_buf, menu->scratch_buf, sizeof(menu_path_new));
1693
1694 core_info_get_list(&list);
1695
1696 def_info.data = list;
1697 def_info.dir = menu_path_new;
1698 def_info.path = path;
1699 def_info.menu_label = menu_label;
1700 def_info.s = menu->deferred_path;
1701 def_info.len = sizeof(menu->deferred_path);
1702
1703 if (menu_content_find_first_core(&def_info, false, new_core_path,
1704 sizeof(new_core_path)))
1705 ret = -1;
1706
1707 if ( !is_carchive && !string_is_empty(path)
1708 && !string_is_empty(menu_path_new))
1709 fill_pathname_join(menu->detect_content_path,
1710 menu_path_new, path,
1711 sizeof(menu->detect_content_path));
1712
1713 if (enum_label_idx == MENU_ENUM_LABEL_COLLECTION)
1714 return generic_action_ok_displaylist_push(path, NULL,
1715 NULL, 0, idx, entry_idx, ACTION_OK_DL_DEFERRED_CORE_LIST_SET);
1716
1717 switch (ret)
1718 {
1719 case -1:
1720 {
1721 content_ctx_info_t content_info;
1722
1723 content_info.argc = 0;
1724 content_info.argv = NULL;
1725 content_info.args = NULL;
1726 content_info.environ_get = NULL;
1727
1728 if (!task_push_load_content_with_new_core_from_menu(
1729 new_core_path, def_info.s,
1730 &content_info,
1731 CORE_TYPE_PLAIN,
1732 NULL, NULL))
1733 return -1;
1734
1735 content_add_to_playlist(def_info.s);
1736 menu_driver_set_last_start_content(def_info.s);
1737
1738 ret = 0;
1739 break;
1740 }
1741 case 0:
1742 ret = generic_action_ok_displaylist_push(path, NULL, label, type,
1743 idx, entry_idx, ACTION_OK_DL_DEFERRED_CORE_LIST);
1744 break;
1745 default:
1746 break;
1747 }
1748 }
1749
1750 return ret;
1751 }
1752
action_ok_file_load_with_detect_core_carchive(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)1753 static int action_ok_file_load_with_detect_core_carchive(
1754 const char *path,
1755 const char *label, unsigned type, size_t idx, size_t entry_idx)
1756 {
1757 menu_handle_t *menu = menu_driver_get_ptr();
1758
1759 if (!menu)
1760 return menu_cbs_exit();
1761
1762 fill_pathname_join_delim(menu->detect_content_path,
1763 menu->detect_content_path, path,
1764 '#', sizeof(menu->detect_content_path));
1765
1766 type = 0;
1767 label = NULL;
1768
1769 return file_load_with_detect_core_wrapper(
1770 MSG_UNKNOWN, idx, entry_idx,
1771 path, label, type, true);
1772 }
1773
action_ok_file_load_with_detect_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)1774 static int action_ok_file_load_with_detect_core(const char *path,
1775 const char *label, unsigned type, size_t idx, size_t entry_idx)
1776 {
1777
1778 type = 0;
1779 label = NULL;
1780
1781 return file_load_with_detect_core_wrapper(
1782 MSG_UNKNOWN, idx, entry_idx,
1783 path, label, type, false);
1784 }
1785
action_ok_file_load_with_detect_core_collection(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)1786 static int action_ok_file_load_with_detect_core_collection(const char *path,
1787 const char *label, unsigned type, size_t idx, size_t entry_idx)
1788 {
1789 type = 0;
1790 label = NULL;
1791
1792 return file_load_with_detect_core_wrapper(
1793 MENU_ENUM_LABEL_COLLECTION,
1794 idx, entry_idx,
1795 path, label, type, false);
1796 }
1797
set_path_generic(const char * label,const char * action_path)1798 static int set_path_generic(const char *label, const char *action_path)
1799 {
1800 rarch_setting_t *setting = menu_setting_find(label);
1801
1802 if (setting)
1803 {
1804 setting_set_with_string_representation(
1805 setting, action_path);
1806 return menu_setting_generic(setting, 0, false);
1807 }
1808
1809 return 0;
1810 }
1811
generic_action_ok_command(enum event_command cmd)1812 int generic_action_ok_command(enum event_command cmd)
1813 {
1814 #ifdef HAVE_AUDIOMIXER
1815 settings_t *settings = config_get_ptr();
1816 bool audio_enable_menu = settings->bools.audio_enable_menu;
1817 bool audio_enable_menu_ok = settings->bools.audio_enable_menu_ok;
1818
1819 if (audio_enable_menu && audio_enable_menu_ok)
1820 audio_driver_mixer_play_menu_sound(AUDIO_MIXER_SYSTEM_SLOT_OK);
1821 #endif
1822
1823 if (!command_event(cmd, NULL))
1824 return menu_cbs_exit();
1825 return 0;
1826 }
1827
generic_action_ok(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx,unsigned id,enum msg_hash_enums flush_id)1828 static int generic_action_ok(const char *path,
1829 const char *label, unsigned type, size_t idx, size_t entry_idx,
1830 unsigned id, enum msg_hash_enums flush_id)
1831 {
1832 char action_path[PATH_MAX_LENGTH];
1833 unsigned flush_type = 0;
1834 int ret = 0;
1835 enum msg_hash_enums enum_idx = MSG_UNKNOWN;
1836 const char *menu_path = NULL;
1837 const char *menu_label = NULL;
1838 const char *flush_char = NULL;
1839 menu_handle_t *menu = menu_driver_get_ptr();
1840 #ifdef HAVE_AUDIOMIXER
1841 settings_t *settings = config_get_ptr();
1842 bool audio_enable_menu = settings->bools.audio_enable_menu;
1843 bool audio_enable_menu_ok = settings->bools.audio_enable_menu_ok;
1844
1845 if (audio_enable_menu && audio_enable_menu_ok)
1846 audio_driver_mixer_play_menu_sound(AUDIO_MIXER_SYSTEM_SLOT_OK);
1847 #endif
1848
1849 if (!menu)
1850 goto error;
1851
1852 menu_entries_get_last_stack(&menu_path,
1853 &menu_label, NULL, &enum_idx, NULL);
1854
1855 action_path[0] = '\0';
1856
1857 if (!string_is_empty(path))
1858 fill_pathname_join(action_path,
1859 menu_path, path, sizeof(action_path));
1860 else
1861 strlcpy(action_path, menu_path, sizeof(action_path));
1862
1863 switch (id)
1864 {
1865 case ACTION_OK_LOAD_WALLPAPER:
1866 flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_MENU_SETTINGS_LIST);
1867 if (filestream_exists(action_path))
1868 {
1869 settings_t *settings = config_get_ptr();
1870
1871 configuration_set_string(settings,
1872 settings->paths.path_menu_wallpaper,
1873 action_path);
1874
1875 task_push_image_load(action_path,
1876 video_driver_supports_rgba(), 0,
1877 menu_display_handle_wallpaper_upload, NULL);
1878 }
1879 break;
1880 case ACTION_OK_LOAD_CORE:
1881 {
1882 content_ctx_info_t content_info;
1883
1884 content_info.argc = 0;
1885 content_info.argv = NULL;
1886 content_info.args = NULL;
1887 content_info.environ_get = NULL;
1888
1889 flush_type = MENU_SETTINGS;
1890
1891 if (!task_push_load_new_core(
1892 action_path, NULL,
1893 &content_info,
1894 CORE_TYPE_PLAIN,
1895 NULL, NULL))
1896 {
1897 #ifndef HAVE_DYNAMIC
1898 ret = -1;
1899 #endif
1900 }
1901 }
1902 break;
1903 case ACTION_OK_LOAD_CONFIG_FILE:
1904 #ifdef HAVE_CONFIGFILE
1905 {
1906 settings_t *settings = config_get_ptr();
1907 bool config_save_on_exit = settings->bools.config_save_on_exit;
1908 flush_type = MENU_SETTINGS;
1909
1910 gfx_display_set_msg_force(true);
1911
1912 if (config_replace(config_save_on_exit, action_path))
1913 {
1914 bool pending_push = false;
1915 menu_driver_ctl(MENU_NAVIGATION_CTL_CLEAR, &pending_push);
1916 ret = -1;
1917 }
1918 }
1919 #endif
1920 break;
1921 case ACTION_OK_LOAD_PRESET:
1922 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
1923 {
1924 struct video_shader *shader = menu_shader_get();
1925 flush_char = msg_hash_to_str(flush_id);
1926
1927 /* Cache selected shader parent directory/file name */
1928 menu_driver_set_last_shader_preset_path(action_path);
1929
1930 menu_shader_manager_set_preset(shader,
1931 menu_driver_get_last_shader_preset_type(),
1932 action_path,
1933 true);
1934 }
1935 #endif
1936 break;
1937 case ACTION_OK_LOAD_SHADER_PASS:
1938 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
1939 {
1940 struct video_shader *shader = menu_shader_get();
1941 struct video_shader_pass *shader_pass = shader ? &shader->pass[menu->scratchpad.unsigned_var] : NULL;
1942 flush_char = msg_hash_to_str((enum msg_hash_enums)flush_id);
1943
1944 if (shader_pass)
1945 {
1946 /* Cache selected shader parent directory/file name */
1947 menu_driver_set_last_shader_pass_path(action_path);
1948
1949 strlcpy(
1950 shader_pass->source.path,
1951 action_path,
1952 sizeof(shader_pass->source.path));
1953 video_shader_resolve_parameters(shader);
1954
1955 shader->modified = true;
1956 }
1957 }
1958 #endif
1959 break;
1960 case ACTION_OK_LOAD_STREAM_CONFIGFILE:
1961 {
1962 settings_t *settings = config_get_ptr();
1963 flush_char = msg_hash_to_str(flush_id);
1964
1965 if (settings)
1966 {
1967 configuration_set_string(settings,
1968 settings->paths.path_stream_config, action_path);
1969 }
1970 }
1971 break;
1972 case ACTION_OK_LOAD_RECORD_CONFIGFILE:
1973 {
1974 settings_t *settings = config_get_ptr();
1975 flush_char = msg_hash_to_str(flush_id);
1976
1977 if (settings)
1978 {
1979 configuration_set_string(settings,
1980 settings->paths.path_record_config, action_path);
1981 }
1982 }
1983 break;
1984 case ACTION_OK_LOAD_REMAPPING_FILE:
1985 #ifdef HAVE_CONFIGFILE
1986 {
1987 config_file_t *conf = config_file_new_from_path_to_string(
1988 action_path);
1989 retro_ctx_controller_info_t pad;
1990 unsigned current_device = 0;
1991 unsigned port = 0;
1992 int conf_val = 0;
1993 char conf_key[64];
1994 flush_char = msg_hash_to_str(flush_id);
1995
1996 conf_key[0] = '\0';
1997
1998 if (conf)
1999 {
2000 if (input_remapping_load_file(conf, action_path))
2001 {
2002 for (port = 0; port < MAX_USERS; port++)
2003 {
2004 snprintf(conf_key, sizeof(conf_key), "input_libretro_device_p%u", port + 1);
2005 if (!config_get_int(conf, conf_key, &conf_val))
2006 continue;
2007
2008 current_device = input_config_get_device(port);
2009 input_config_set_device(port, current_device);
2010 pad.port = port;
2011 pad.device = current_device;
2012 core_set_controller_port_device(&pad);
2013 }
2014 }
2015 config_file_free(conf);
2016 conf = NULL;
2017 }
2018 }
2019 #endif
2020 break;
2021 case ACTION_OK_LOAD_CHEAT_FILE:
2022 #ifdef HAVE_CHEATS
2023 flush_char = msg_hash_to_str(flush_id);
2024 cheat_manager_state_free();
2025
2026 if (!cheat_manager_load(action_path,false))
2027 goto error;
2028 #endif
2029 break;
2030 case ACTION_OK_LOAD_CHEAT_FILE_APPEND:
2031 #ifdef HAVE_CHEATS
2032 flush_char = msg_hash_to_str(flush_id);
2033
2034 if (!cheat_manager_load(action_path,true))
2035 goto error;
2036 #endif
2037 break;
2038 case ACTION_OK_LOAD_RGUI_MENU_THEME_PRESET:
2039 {
2040 settings_t *settings = config_get_ptr();
2041 flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_MENU_SETTINGS_LIST);
2042
2043 if (settings)
2044 {
2045 configuration_set_string(settings,
2046 settings->paths.path_rgui_theme_preset, action_path);
2047 }
2048 }
2049 break;
2050 case ACTION_OK_SUBSYSTEM_ADD:
2051 flush_type = MENU_SETTINGS;
2052 content_add_subsystem(action_path);
2053 break;
2054 case ACTION_OK_SET_DIRECTORY:
2055 flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DIRECTORY_SETTINGS_LIST);
2056 #ifdef HAVE_COCOATOUCH
2057 /* For iOS, set the path using realpath because the
2058 * path name can start with /private and this ensures
2059 * the path starts with it.
2060 *
2061 * This will allow the path to be properly substituted
2062 * when fill_pathname_expand_special
2063 * is called.
2064 */
2065 {
2066 char real_action_path[PATH_MAX_LENGTH];
2067 real_action_path[0] = '\0';
2068 realpath(action_path, real_action_path);
2069 strlcpy(action_path, real_action_path, sizeof(action_path));
2070 }
2071 #endif
2072 ret = set_path_generic(menu->filebrowser_label, action_path);
2073 break;
2074 case ACTION_OK_SET_PATH_VIDEO_FILTER:
2075 flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_VIDEO_SETTINGS_LIST);
2076 ret = set_path_generic(menu_label, action_path);
2077 break;
2078 case ACTION_OK_SET_PATH_AUDIO_FILTER:
2079 flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_AUDIO_SETTINGS_LIST);
2080 ret = set_path_generic(menu_label, action_path);
2081 break;
2082 case ACTION_OK_SET_PATH_OVERLAY:
2083 flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ONSCREEN_OVERLAY_SETTINGS_LIST);
2084 ret = set_path_generic(menu_label, action_path);
2085 break;
2086 #ifdef HAVE_VIDEO_LAYOUT
2087 case ACTION_OK_SET_PATH_VIDEO_LAYOUT:
2088 flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ONSCREEN_VIDEO_LAYOUT_SETTINGS_LIST);
2089 ret = set_path_generic(menu_label, action_path);
2090 break;
2091 #endif
2092 case ACTION_OK_SET_PATH_VIDEO_FONT:
2093 flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST);
2094 ret = set_path_generic(menu_label, action_path);
2095 break;
2096 case ACTION_OK_SET_MANUAL_CONTENT_SCAN_DAT_FILE:
2097 flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST);
2098 ret = set_path_generic(menu_label, action_path);
2099 break;
2100 case ACTION_OK_SET_PATH:
2101 flush_type = MENU_SETTINGS;
2102 ret = set_path_generic(menu_label, action_path);
2103 break;
2104 default:
2105 flush_char = msg_hash_to_str(flush_id);
2106 break;
2107 }
2108
2109 menu_entries_flush_stack(flush_char, flush_type);
2110
2111 return ret;
2112
2113 error:
2114 return menu_cbs_exit();
2115 }
2116
default_action_ok_load_content_with_core_from_menu(const char * _path,unsigned _type)2117 static int default_action_ok_load_content_with_core_from_menu(const char *_path, unsigned _type)
2118 {
2119 content_ctx_info_t content_info;
2120 content_info.argc = 0;
2121 content_info.argv = NULL;
2122 content_info.args = NULL;
2123 content_info.environ_get = NULL;
2124 if (!task_push_load_content_with_core_from_menu(
2125 _path, &content_info,
2126 (enum rarch_core_type)_type, NULL, NULL))
2127 return -1;
2128 content_add_to_playlist(_path);
2129 menu_driver_set_last_start_content(_path);
2130 return 0;
2131 }
2132
default_action_ok_load_content_from_playlist_from_menu(const char * _path,const char * path,const char * entry_label)2133 static int default_action_ok_load_content_from_playlist_from_menu(const char *_path,
2134 const char *path, const char *entry_label)
2135 {
2136 content_ctx_info_t content_info;
2137 content_info.argc = 0;
2138 content_info.argv = NULL;
2139 content_info.args = NULL;
2140 content_info.environ_get = NULL;
2141 if (!task_push_load_content_from_playlist_from_menu(
2142 _path, path, entry_label,
2143 &content_info,
2144 NULL, NULL))
2145 return -1;
2146 return 0;
2147 }
2148
DEFAULT_ACTION_OK_SET(action_ok_set_path_audiofilter,ACTION_OK_SET_PATH_AUDIO_FILTER,MSG_UNKNOWN)2149 DEFAULT_ACTION_OK_SET(action_ok_set_path_audiofilter, ACTION_OK_SET_PATH_AUDIO_FILTER, MSG_UNKNOWN)
2150 DEFAULT_ACTION_OK_SET(action_ok_set_path_videofilter, ACTION_OK_SET_PATH_VIDEO_FILTER, MSG_UNKNOWN)
2151 DEFAULT_ACTION_OK_SET(action_ok_set_path_overlay, ACTION_OK_SET_PATH_OVERLAY, MSG_UNKNOWN)
2152 #ifdef HAVE_VIDEO_LAYOUT
2153 DEFAULT_ACTION_OK_SET(action_ok_set_path_video_layout,ACTION_OK_SET_PATH_VIDEO_LAYOUT, MSG_UNKNOWN)
2154 #endif
2155 DEFAULT_ACTION_OK_SET(action_ok_set_path_video_font, ACTION_OK_SET_PATH_VIDEO_FONT, MSG_UNKNOWN)
2156 DEFAULT_ACTION_OK_SET(action_ok_set_path, ACTION_OK_SET_PATH, MSG_UNKNOWN)
2157 DEFAULT_ACTION_OK_SET(action_ok_load_core, ACTION_OK_LOAD_CORE, MSG_UNKNOWN)
2158 DEFAULT_ACTION_OK_SET(action_ok_config_load, ACTION_OK_LOAD_CONFIG_FILE, MSG_UNKNOWN)
2159 DEFAULT_ACTION_OK_SET(action_ok_subsystem_add, ACTION_OK_SUBSYSTEM_ADD, MSG_UNKNOWN)
2160 DEFAULT_ACTION_OK_SET(action_ok_cheat_file_load, ACTION_OK_LOAD_CHEAT_FILE, MENU_ENUM_LABEL_CORE_CHEAT_OPTIONS)
2161 DEFAULT_ACTION_OK_SET(action_ok_cheat_file_load_append, ACTION_OK_LOAD_CHEAT_FILE_APPEND, MENU_ENUM_LABEL_CORE_CHEAT_OPTIONS)
2162 DEFAULT_ACTION_OK_SET(action_ok_record_configfile_load, ACTION_OK_LOAD_RECORD_CONFIGFILE, MENU_ENUM_LABEL_RECORDING_SETTINGS)
2163 DEFAULT_ACTION_OK_SET(action_ok_stream_configfile_load, ACTION_OK_LOAD_STREAM_CONFIGFILE, MENU_ENUM_LABEL_RECORDING_SETTINGS)
2164 DEFAULT_ACTION_OK_SET(action_ok_remap_file_load, ACTION_OK_LOAD_REMAPPING_FILE, MENU_ENUM_LABEL_CORE_INPUT_REMAPPING_OPTIONS )
2165 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
2166 DEFAULT_ACTION_OK_SET(action_ok_shader_preset_load, ACTION_OK_LOAD_PRESET , MENU_ENUM_LABEL_SHADER_OPTIONS)
2167 DEFAULT_ACTION_OK_SET(action_ok_shader_pass_load, ACTION_OK_LOAD_SHADER_PASS, MENU_ENUM_LABEL_SHADER_OPTIONS)
2168 #endif
2169 DEFAULT_ACTION_OK_SET(action_ok_rgui_menu_theme_preset_load, ACTION_OK_LOAD_RGUI_MENU_THEME_PRESET, MENU_ENUM_LABEL_MENU_SETTINGS)
2170 DEFAULT_ACTION_OK_SET(action_ok_set_manual_content_scan_dat_file, ACTION_OK_SET_MANUAL_CONTENT_SCAN_DAT_FILE, MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST)
2171
2172 static int action_ok_file_load(const char *path,
2173 const char *label, unsigned type, size_t idx, size_t entry_idx)
2174 {
2175 char menu_path_new[PATH_MAX_LENGTH];
2176 char full_path_new[PATH_MAX_LENGTH];
2177 const char *menu_label = NULL;
2178 const char *menu_path = NULL;
2179 rarch_setting_t *setting = NULL;
2180 file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(0);
2181
2182 menu_path_new[0] = full_path_new[0] = '\0';
2183
2184 if (filebrowser_get_type() == FILEBROWSER_SELECT_FILE_SUBSYSTEM)
2185 {
2186 /* TODO/FIXME - this path is triggered when we try to load a
2187 * file from an archive while inside the load subsystem
2188 * action */
2189 menu_handle_t *menu = menu_driver_get_ptr();
2190 if (!menu)
2191 return menu_cbs_exit();
2192
2193 fill_pathname_join(menu_path_new,
2194 menu->scratch2_buf, menu->scratch_buf,
2195 sizeof(menu_path_new));
2196 switch (type)
2197 {
2198 case FILE_TYPE_IN_CARCHIVE:
2199 fill_pathname_join_delim(full_path_new, menu_path_new, path,
2200 '#',sizeof(full_path_new));
2201 break;
2202 default:
2203 fill_pathname_join(full_path_new, menu_path_new, path,
2204 sizeof(full_path_new));
2205 break;
2206 }
2207
2208 content_add_subsystem(full_path_new);
2209 menu_entries_flush_stack(NULL, MENU_SETTINGS);
2210 return 0;
2211 }
2212
2213 file_list_get_last(menu_stack, &menu_path, &menu_label, NULL, NULL);
2214
2215 if (!string_is_empty(menu_label))
2216 setting = menu_setting_find(menu_label);
2217
2218 if (setting && setting->type == ST_PATH)
2219 return action_ok_set_path(path, label, type, idx, entry_idx);
2220
2221 if (!string_is_empty(menu_path))
2222 strlcpy(menu_path_new, menu_path, sizeof(menu_path_new));
2223
2224 if (!string_is_empty(menu_label))
2225 {
2226 if (
2227 string_is_equal(menu_label,
2228 msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN_DETECT_CORE)) ||
2229 string_is_equal(menu_label,
2230 msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN))
2231 )
2232 {
2233 menu_handle_t *menu = menu_driver_get_ptr();
2234 if (!menu)
2235 return menu_cbs_exit();
2236
2237 fill_pathname_join(menu_path_new,
2238 menu->scratch2_buf, menu->scratch_buf,
2239 sizeof(menu_path_new));
2240 }
2241 }
2242
2243 switch (type)
2244 {
2245 case FILE_TYPE_IN_CARCHIVE:
2246 fill_pathname_join_delim(full_path_new, menu_path_new, path,
2247 '#',sizeof(full_path_new));
2248 break;
2249 default:
2250 fill_pathname_join(full_path_new, menu_path_new, path,
2251 sizeof(full_path_new));
2252 break;
2253 }
2254
2255 return default_action_ok_load_content_with_core_from_menu(full_path_new,
2256 CORE_TYPE_PLAIN);
2257 }
2258
playlist_entry_path_is_valid(const char * entry_path)2259 static bool playlist_entry_path_is_valid(const char *entry_path)
2260 {
2261 char *archive_delim = NULL;
2262 char *file_path = NULL;
2263
2264 if (string_is_empty(entry_path))
2265 goto error;
2266
2267 file_path = strdup(entry_path);
2268
2269 /* We need to check whether the file referenced by the
2270 * entry path actually exists. If it is a normal file,
2271 * we can do this directly. If the path contains an
2272 * archive delimiter, then we have to trim everything
2273 * after the archive extension
2274 * > Note: Have to do a nasty cast here, since
2275 * path_get_archive_delim() returns a const char *
2276 * (this cast is safe, though, and is done in many
2277 * places throughout the codebase...) */
2278 archive_delim = (char *)path_get_archive_delim(file_path);
2279
2280 if (archive_delim)
2281 {
2282 *archive_delim = '\0';
2283 if (string_is_empty(file_path))
2284 goto error;
2285 }
2286
2287 /* Path is 'sanitised' - can now check if it exists */
2288 if (!path_is_valid(file_path))
2289 goto error;
2290
2291 /* File is valid */
2292 free(file_path);
2293 file_path = NULL;
2294
2295 return true;
2296
2297 error:
2298 if (file_path)
2299 {
2300 free(file_path);
2301 file_path = NULL;
2302 }
2303
2304 return false;
2305 }
2306
action_ok_playlist_entry_collection(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2307 static int action_ok_playlist_entry_collection(const char *path,
2308 const char *label, unsigned type, size_t idx, size_t entry_idx)
2309 {
2310 playlist_config_t playlist_config;
2311 char content_path[PATH_MAX_LENGTH];
2312 char content_label[PATH_MAX_LENGTH];
2313 char core_path[PATH_MAX_LENGTH];
2314 size_t selection_ptr = entry_idx;
2315 bool playlist_initialized = false;
2316 playlist_t *playlist = NULL;
2317 playlist_t *tmp_playlist = NULL;
2318 const struct playlist_entry *entry = NULL;
2319 core_info_t* core_info = NULL;
2320 bool core_is_builtin = false;
2321 menu_handle_t *menu = menu_driver_get_ptr();
2322 settings_t *settings = config_get_ptr();
2323 bool playlist_sort_alphabetical = settings->bools.playlist_sort_alphabetical;
2324 const char *path_content_history = settings->paths.path_content_history;
2325 const char *path_content_image_history = settings->paths.path_content_image_history;
2326 const char *path_content_music_history = settings->paths.path_content_music_history;
2327 const char *path_content_video_history = settings->paths.path_content_video_history;
2328
2329 playlist_config.capacity = COLLECTION_SIZE;
2330 playlist_config.old_format = settings->bools.playlist_use_old_format;
2331 playlist_config.compress = settings->bools.playlist_compression;
2332 playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
2333 playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
2334
2335 content_path[0] = '\0';
2336 content_label[0] = '\0';
2337 core_path[0] = '\0';
2338
2339 if (!menu)
2340 goto error;
2341
2342 /* Get playlist */
2343 tmp_playlist = playlist_get_cached();
2344
2345 if (!tmp_playlist)
2346 {
2347 /* If playlist is not cached, have to load
2348 * it here
2349 * > Since the menu will always sort playlists
2350 * based on current user config, have to do
2351 * the same here - otherwise entry_idx may
2352 * go out of sync... */
2353 bool is_content_history = string_is_equal(menu->db_playlist_file, path_content_history) ||
2354 string_is_equal(menu->db_playlist_file, path_content_image_history) ||
2355 string_is_equal(menu->db_playlist_file, path_content_music_history) ||
2356 string_is_equal(menu->db_playlist_file, path_content_video_history);
2357
2358 enum playlist_sort_mode current_sort_mode;
2359
2360 playlist_config_set_path(&playlist_config, menu->db_playlist_file);
2361 tmp_playlist = playlist_init(&playlist_config);
2362
2363 if (!tmp_playlist)
2364 goto error;
2365
2366 current_sort_mode = playlist_get_sort_mode(tmp_playlist);
2367
2368 if (!is_content_history &&
2369 ((playlist_sort_alphabetical && (current_sort_mode == PLAYLIST_SORT_MODE_DEFAULT)) ||
2370 (current_sort_mode == PLAYLIST_SORT_MODE_ALPHABETICAL)))
2371 playlist_qsort(tmp_playlist);
2372
2373 playlist_initialized = true;
2374 }
2375
2376 playlist = tmp_playlist;
2377
2378 /* Get playlist entry */
2379 playlist_get_index(playlist, selection_ptr, &entry);
2380 if (!entry)
2381 goto error;
2382
2383 /* Cache entry path */
2384 if (!string_is_empty(entry->path))
2385 {
2386 strlcpy(content_path, entry->path, sizeof(content_path));
2387 playlist_resolve_path(PLAYLIST_LOAD, false, content_path, sizeof(content_path));
2388 }
2389
2390 /* Cache entry label */
2391 if (!string_is_empty(entry->label))
2392 strlcpy(content_label, entry->label, sizeof(content_label));
2393
2394 /* Get core path */
2395 if (!playlist_entry_has_core(entry))
2396 {
2397 struct playlist_entry update_entry = {0};
2398
2399 /* Entry core is not set - attempt to use
2400 * playlist default */
2401 core_info = playlist_get_default_core_info(playlist);
2402
2403 /* If default core is not set, prompt user
2404 * to select one */
2405 if (!core_info)
2406 {
2407 /* TODO: figure out if this should refer to the inner or outer content_path */
2408 int ret = action_ok_file_load_with_detect_core_collection(content_path,
2409 label, type, selection_ptr, entry_idx);
2410
2411 if (playlist_initialized && tmp_playlist)
2412 {
2413 playlist_free(tmp_playlist);
2414 tmp_playlist = NULL;
2415 playlist = NULL;
2416 }
2417
2418 return ret;
2419 }
2420
2421 /* Cache core path */
2422 strlcpy(core_path, core_info->path, sizeof(core_path));
2423
2424 /* Update playlist entry */
2425 update_entry.core_path = core_info->path;
2426 update_entry.core_name = core_info->display_name;
2427
2428 command_playlist_update_write(
2429 playlist,
2430 selection_ptr,
2431 &update_entry);
2432 }
2433 else
2434 {
2435 /* Entry does have a core assignment
2436 * > If core is 'built-in' (imageviewer, etc.),
2437 * then copy the path without modification
2438 * > If this is a standard core, ensure
2439 * it has a corresponding core info entry */
2440 if (string_ends_with_size(entry->core_path, "builtin",
2441 strlen(entry->core_path),
2442 STRLEN_CONST("builtin")))
2443 {
2444 strlcpy(core_path, entry->core_path, sizeof(core_path));
2445 core_is_builtin = true;
2446 }
2447 else
2448 {
2449 core_info = playlist_entry_get_core_info(entry);
2450
2451 if (core_info && !string_is_empty(core_info->path))
2452 strlcpy(core_path, core_info->path, sizeof(core_path));
2453 else
2454 {
2455 /* Core path is invalid - just copy what we have
2456 * and hope for the best... */
2457 strlcpy(core_path, entry->core_path, sizeof(core_path));
2458 playlist_resolve_path(PLAYLIST_LOAD, true, core_path, sizeof(core_path));
2459 }
2460 }
2461 }
2462
2463 /* Ensure core path is valid */
2464 if (string_is_empty(core_path) ||
2465 (!core_is_builtin && !path_is_valid(core_path)))
2466 goto error;
2467
2468 /* Subsystem codepath */
2469 if (!string_is_empty(entry->subsystem_ident))
2470 {
2471 content_ctx_info_t content_info = {0};
2472 size_t i;
2473
2474 task_push_load_new_core(core_path, NULL,
2475 &content_info, CORE_TYPE_PLAIN, NULL, NULL);
2476
2477 content_clear_subsystem();
2478
2479 if (!content_set_subsystem_by_name(entry->subsystem_ident))
2480 {
2481 RARCH_LOG("[playlist] subsystem not found in implementation\n");
2482 goto error;
2483 }
2484
2485 for (i = 0; i < entry->subsystem_roms->size; i++)
2486 content_add_subsystem(entry->subsystem_roms->elems[i].data);
2487
2488 task_push_load_subsystem_with_core_from_menu(
2489 NULL, &content_info,
2490 CORE_TYPE_PLAIN, NULL, NULL);
2491
2492 /* TODO: update playlist entry? move to first position I guess? */
2493 if (playlist_initialized && tmp_playlist)
2494 {
2495 playlist_free(tmp_playlist);
2496 tmp_playlist = NULL;
2497 playlist = NULL;
2498 }
2499 return 1;
2500 }
2501
2502 /* Ensure entry path is valid */
2503 if (!playlist_entry_path_is_valid(content_path))
2504 goto error;
2505
2506 /* Free temporary playlist, if required */
2507 if (playlist_initialized && tmp_playlist)
2508 {
2509 playlist_free(tmp_playlist);
2510 tmp_playlist = NULL;
2511 playlist = NULL;
2512 }
2513
2514 /* Note: Have to use cached entry label, since entry
2515 * may be free()'d by above playlist_free() - but need
2516 * to pass NULL explicitly if label is empty */
2517 return default_action_ok_load_content_from_playlist_from_menu(
2518 core_path, content_path, string_is_empty(content_label) ? NULL : content_label);
2519
2520 error:
2521 runloop_msg_queue_push(
2522 "File could not be loaded from playlist.\n",
2523 1, 100, true,
2524 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
2525
2526 if (playlist_initialized && tmp_playlist)
2527 {
2528 playlist_free(tmp_playlist);
2529 tmp_playlist = NULL;
2530 playlist = NULL;
2531 }
2532
2533 return menu_cbs_exit();
2534 }
2535
2536 #ifdef HAVE_AUDIOMIXER
action_ok_mixer_stream_action_play(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2537 static int action_ok_mixer_stream_action_play(const char *path,
2538 const char *label, unsigned type, size_t idx, size_t entry_idx)
2539 {
2540 unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN;
2541 enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id);
2542
2543 switch (state)
2544 {
2545 case AUDIO_STREAM_STATE_STOPPED:
2546 audio_driver_mixer_play_stream(stream_id);
2547 break;
2548 case AUDIO_STREAM_STATE_PLAYING:
2549 case AUDIO_STREAM_STATE_PLAYING_LOOPED:
2550 case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL:
2551 case AUDIO_STREAM_STATE_NONE:
2552 break;
2553 }
2554 return 0;
2555 }
2556
action_ok_mixer_stream_action_play_looped(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2557 static int action_ok_mixer_stream_action_play_looped(const char *path,
2558 const char *label, unsigned type, size_t idx, size_t entry_idx)
2559 {
2560 unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN;
2561 enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id);
2562
2563 switch (state)
2564 {
2565 case AUDIO_STREAM_STATE_STOPPED:
2566 audio_driver_mixer_play_stream_looped(stream_id);
2567 break;
2568 case AUDIO_STREAM_STATE_PLAYING:
2569 case AUDIO_STREAM_STATE_PLAYING_LOOPED:
2570 case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL:
2571 case AUDIO_STREAM_STATE_NONE:
2572 break;
2573 }
2574 return 0;
2575 }
2576
action_ok_mixer_stream_action_play_sequential(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2577 static int action_ok_mixer_stream_action_play_sequential(const char *path,
2578 const char *label, unsigned type, size_t idx, size_t entry_idx)
2579 {
2580 unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_BEGIN;
2581 enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id);
2582
2583 switch (state)
2584 {
2585 case AUDIO_STREAM_STATE_STOPPED:
2586 audio_driver_mixer_play_stream_sequential(stream_id);
2587 break;
2588 case AUDIO_STREAM_STATE_PLAYING:
2589 case AUDIO_STREAM_STATE_PLAYING_LOOPED:
2590 case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL:
2591 case AUDIO_STREAM_STATE_NONE:
2592 break;
2593 }
2594 return 0;
2595 }
2596
action_ok_mixer_stream_action_remove(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2597 static int action_ok_mixer_stream_action_remove(const char *path,
2598 const char *label, unsigned type, size_t idx, size_t entry_idx)
2599 {
2600 unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN;
2601 enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id);
2602
2603 switch (state)
2604 {
2605 case AUDIO_STREAM_STATE_PLAYING:
2606 case AUDIO_STREAM_STATE_PLAYING_LOOPED:
2607 case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL:
2608 case AUDIO_STREAM_STATE_STOPPED:
2609 audio_driver_mixer_remove_stream(stream_id);
2610 break;
2611 case AUDIO_STREAM_STATE_NONE:
2612 break;
2613 }
2614 return 0;
2615 }
2616
action_ok_mixer_stream_action_stop(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2617 static int action_ok_mixer_stream_action_stop(const char *path,
2618 const char *label, unsigned type, size_t idx, size_t entry_idx)
2619 {
2620 unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_BEGIN;
2621 enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id);
2622
2623 switch (state)
2624 {
2625 case AUDIO_STREAM_STATE_PLAYING:
2626 case AUDIO_STREAM_STATE_PLAYING_LOOPED:
2627 case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL:
2628 audio_driver_mixer_stop_stream(stream_id);
2629 break;
2630 case AUDIO_STREAM_STATE_STOPPED:
2631 case AUDIO_STREAM_STATE_NONE:
2632 break;
2633 }
2634 return 0;
2635 }
2636 #endif
2637
action_ok_load_cdrom(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2638 static int action_ok_load_cdrom(const char *path,
2639 const char *label, unsigned type, size_t idx, size_t entry_idx)
2640 {
2641 #ifdef HAVE_CDROM
2642 struct retro_system_info *system;
2643
2644 if (!cdrom_drive_has_media(label[0]))
2645 {
2646 RARCH_LOG("[CDROM]: No media is inserted or drive is not ready.\n");
2647
2648 runloop_msg_queue_push(
2649 msg_hash_to_str(MSG_NO_DISC_INSERTED),
2650 1, 100, true,
2651 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
2652
2653 return -1;
2654 }
2655
2656 system = runloop_get_libretro_system_info();
2657
2658 if (system && !string_is_empty(system->library_name))
2659 {
2660 char cdrom_path[256] = {0};
2661
2662 cdrom_device_fillpath(cdrom_path, sizeof(cdrom_path), label[0], 0, true);
2663
2664 RARCH_LOG("[CDROM]: Loading disc from path: %s\n", cdrom_path);
2665
2666 path_clear(RARCH_PATH_CONTENT);
2667 path_set(RARCH_PATH_CONTENT, cdrom_path);
2668
2669 #if defined(HAVE_DYNAMIC)
2670 {
2671 content_ctx_info_t content_info;
2672
2673 content_info.argc = 0;
2674 content_info.argv = NULL;
2675 content_info.args = NULL;
2676 content_info.environ_get = NULL;
2677
2678 task_push_load_content_with_core_from_menu(cdrom_path, &content_info, CORE_TYPE_PLAIN, NULL, NULL);
2679 }
2680 #else
2681 frontend_driver_set_fork(FRONTEND_FORK_CORE_WITH_ARGS);
2682 #endif
2683 }
2684 else
2685 {
2686 RARCH_LOG("[CDROM]: Cannot load disc without a core.\n");
2687
2688 runloop_msg_queue_push(
2689 msg_hash_to_str(MSG_LOAD_CORE_FIRST),
2690 1, 100, true,
2691 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
2692
2693 return -1;
2694 }
2695 #endif
2696 return 0;
2697 }
2698
action_ok_dump_cdrom(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2699 static int action_ok_dump_cdrom(const char *path,
2700 const char *label, unsigned type, size_t idx, size_t entry_idx)
2701 {
2702 if (string_is_empty(label))
2703 return -1;
2704 #ifdef HAVE_CDROM
2705 if (!cdrom_drive_has_media(label[0]))
2706 {
2707 RARCH_LOG("[CDROM]: No media is inserted or drive is not ready.\n");
2708
2709 runloop_msg_queue_push(
2710 msg_hash_to_str(MSG_NO_DISC_INSERTED),
2711 1, 100, true,
2712 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
2713
2714 return -1;
2715 }
2716
2717 task_push_cdrom_dump(label);
2718 #endif
2719 return 0;
2720 }
2721
action_ok_lookup_setting(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2722 static int action_ok_lookup_setting(const char *path,
2723 const char *label, unsigned type, size_t idx, size_t entry_idx)
2724 {
2725 return menu_setting_set(type, MENU_ACTION_OK, false);
2726 }
2727
2728 #ifdef HAVE_AUDIOMIXER
action_ok_audio_add_to_mixer(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2729 static int action_ok_audio_add_to_mixer(const char *path,
2730 const char *label, unsigned type, size_t idx, size_t entry_idx)
2731 {
2732 playlist_t *tmp_playlist = playlist_get_cached();
2733 const struct playlist_entry *entry = NULL;
2734
2735 if (!tmp_playlist)
2736 return -1;
2737
2738 playlist_get_index(tmp_playlist, entry_idx, &entry);
2739
2740 if (filestream_exists(entry->path))
2741 task_push_audio_mixer_load(entry->path,
2742 NULL, NULL, false,
2743 AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC,
2744 0
2745 );
2746
2747 return 0;
2748 }
2749
action_ok_audio_add_to_mixer_and_play(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2750 static int action_ok_audio_add_to_mixer_and_play(const char *path,
2751 const char *label, unsigned type, size_t idx, size_t entry_idx)
2752 {
2753 playlist_t *tmp_playlist = playlist_get_cached();
2754 const struct playlist_entry *entry = NULL;
2755
2756 if (!tmp_playlist)
2757 return -1;
2758
2759 playlist_get_index(tmp_playlist, entry_idx, &entry);
2760
2761 if (filestream_exists(entry->path))
2762 task_push_audio_mixer_load_and_play(entry->path,
2763 NULL, NULL, false,
2764 AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC,
2765 0);
2766
2767 return 0;
2768 }
2769
action_ok_audio_add_to_mixer_and_collection(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2770 static int action_ok_audio_add_to_mixer_and_collection(const char *path,
2771 const char *label, unsigned type, size_t idx, size_t entry_idx)
2772 {
2773 char combined_path[PATH_MAX_LENGTH];
2774 struct playlist_entry entry = {0};
2775 menu_handle_t *menu = menu_driver_get_ptr();
2776
2777 combined_path[0] = '\0';
2778
2779 if (!menu)
2780 return menu_cbs_exit();
2781
2782 fill_pathname_join(combined_path, menu->scratch2_buf,
2783 menu->scratch_buf, sizeof(combined_path));
2784
2785 /* the push function reads our entry as const, so these casts are safe */
2786 entry.path = combined_path;
2787 entry.core_path = (char*)"builtin";
2788 entry.core_name = (char*)"musicplayer";
2789
2790 command_playlist_push_write(g_defaults.music_history, &entry);
2791
2792 if (filestream_exists(combined_path))
2793 task_push_audio_mixer_load(combined_path,
2794 NULL, NULL, false,
2795 AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC,
2796 0);
2797
2798 return 0;
2799 }
2800
action_ok_audio_add_to_mixer_and_collection_and_play(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2801 static int action_ok_audio_add_to_mixer_and_collection_and_play(const char *path,
2802 const char *label, unsigned type, size_t idx, size_t entry_idx)
2803 {
2804 char combined_path[PATH_MAX_LENGTH];
2805 struct playlist_entry entry = {0};
2806 menu_handle_t *menu = menu_driver_get_ptr();
2807
2808 combined_path[0] = '\0';
2809
2810 if (!menu)
2811 return menu_cbs_exit();
2812
2813 fill_pathname_join(combined_path, menu->scratch2_buf,
2814 menu->scratch_buf, sizeof(combined_path));
2815
2816 /* the push function reads our entry as const, so these casts are safe */
2817 entry.path = combined_path;
2818 entry.core_path = (char*)"builtin";
2819 entry.core_name = (char*)"musicplayer";
2820
2821 command_playlist_push_write(g_defaults.music_history, &entry);
2822
2823 if (filestream_exists(combined_path))
2824 task_push_audio_mixer_load_and_play(combined_path,
2825 NULL, NULL, false,
2826 AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC,
2827 0);
2828
2829 return 0;
2830 }
2831 #endif
2832
action_ok_menu_wallpaper(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2833 static int action_ok_menu_wallpaper(const char *path,
2834 const char *label, unsigned type, size_t idx, size_t entry_idx)
2835 {
2836 filebrowser_set_type(FILEBROWSER_SELECT_IMAGE);
2837 return action_ok_lookup_setting(path, label, type, idx, entry_idx);
2838 }
2839
action_ok_menu_wallpaper_load(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2840 static int action_ok_menu_wallpaper_load(const char *path,
2841 const char *label, unsigned type, size_t idx, size_t entry_idx)
2842 {
2843 settings_t *settings = config_get_ptr();
2844
2845 filebrowser_clear_type();
2846
2847 settings->uints.menu_xmb_shader_pipeline = XMB_SHADER_PIPELINE_WALLPAPER;
2848 return generic_action_ok(path, label, type, idx, entry_idx,
2849 ACTION_OK_LOAD_WALLPAPER, MSG_UNKNOWN);
2850 }
2851
generic_action_ok_help(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx,enum msg_hash_enums id,enum menu_dialog_type id2)2852 int generic_action_ok_help(const char *path,
2853 const char *label, unsigned type, size_t idx, size_t entry_idx,
2854 enum msg_hash_enums id, enum menu_dialog_type id2)
2855 {
2856 const char *lbl = msg_hash_to_str(id);
2857
2858 return generic_action_ok_displaylist_push(path, NULL, lbl, id2, idx,
2859 entry_idx, ACTION_OK_DL_HELP);
2860 }
2861
action_ok_bluetooth(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2862 static int action_ok_bluetooth(const char *path, const char *label,
2863 unsigned type, size_t idx, size_t entry_idx)
2864 {
2865 driver_bluetooth_connect_device((unsigned)idx);
2866
2867 return 0;
2868 }
2869
2870 #ifdef HAVE_NETWORKING
menu_input_wifi_cb(void * userdata,const char * passphrase)2871 static void menu_input_wifi_cb(void *userdata, const char *passphrase)
2872 {
2873 unsigned idx = menu_input_dialog_get_kb_idx();
2874 wifi_network_scan_t *scan = driver_wifi_get_ssids();
2875 wifi_network_info_t *netinfo = &scan->net_list[idx];
2876
2877 if (idx < RBUF_LEN(scan->net_list) && passphrase)
2878 {
2879 /* Need to fill in the passphrase that we got from the user! */
2880 strlcpy(netinfo->passphrase, passphrase, sizeof(netinfo->passphrase));
2881 task_push_wifi_connect(NULL, netinfo);
2882 }
2883
2884 menu_input_dialog_end();
2885 }
2886 #endif
2887
menu_input_st_string_cb_rename_entry(void * userdata,const char * str)2888 static void menu_input_st_string_cb_rename_entry(void *userdata,
2889 const char *str)
2890 {
2891 if (str && *str)
2892 {
2893 const char *label = menu_input_dialog_get_buffer();
2894
2895 if (!string_is_empty(label))
2896 {
2897 struct playlist_entry entry = {0};
2898
2899 /* the update function reads our entry as const,
2900 * so these casts are safe */
2901 entry.label = (char*)label;
2902
2903 command_playlist_update_write(NULL,
2904 menu_input_dialog_get_kb_idx(),
2905 &entry);
2906 }
2907 }
2908
2909 menu_input_dialog_end();
2910 }
2911
menu_input_st_string_cb_disable_kiosk_mode(void * userdata,const char * str)2912 static void menu_input_st_string_cb_disable_kiosk_mode(void *userdata,
2913 const char *str)
2914 {
2915 if (str && *str)
2916 {
2917 const char *label = menu_input_dialog_get_buffer();
2918 settings_t *settings = config_get_ptr();
2919 const char *path_kiosk_mode_password =
2920 settings->paths.kiosk_mode_password;
2921
2922 if (string_is_equal(label, path_kiosk_mode_password))
2923 {
2924 settings->bools.kiosk_mode_enable = false;
2925
2926 runloop_msg_queue_push(
2927 msg_hash_to_str(MSG_INPUT_KIOSK_MODE_PASSWORD_OK),
2928 1, 100, true,
2929 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
2930 }
2931 else
2932 {
2933 runloop_msg_queue_push(
2934 msg_hash_to_str(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK),
2935 1, 100, true,
2936 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
2937 }
2938 }
2939
2940 menu_input_dialog_end();
2941 }
2942
menu_input_st_string_cb_enable_settings(void * userdata,const char * str)2943 static void menu_input_st_string_cb_enable_settings(void *userdata,
2944 const char *str)
2945 {
2946 if (str && *str)
2947 {
2948 const char *label =
2949 menu_input_dialog_get_buffer();
2950 settings_t *settings = config_get_ptr();
2951 const char *menu_content_show_settings_password = settings->paths.menu_content_show_settings_password;
2952
2953 if (string_is_equal(label, menu_content_show_settings_password))
2954 {
2955 settings->bools.menu_content_show_settings = true;
2956
2957 runloop_msg_queue_push(
2958 msg_hash_to_str(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_OK),
2959 1, 100, true,
2960 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
2961 }
2962 else
2963 {
2964 runloop_msg_queue_push(
2965 msg_hash_to_str(MSG_INPUT_ENABLE_SETTINGS_PASSWORD_NOK),
2966 1, 100, true,
2967 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
2968 }
2969 }
2970
2971 menu_input_dialog_end();
2972 }
2973
2974 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
action_ok_shader_pass(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)2975 static int action_ok_shader_pass(const char *path,
2976 const char *label, unsigned type, size_t idx, size_t entry_idx)
2977 {
2978 menu_handle_t *menu = menu_driver_get_ptr();
2979
2980 if (!menu)
2981 return menu_cbs_exit();
2982
2983 menu->scratchpad.unsigned_var = type - MENU_SETTINGS_SHADER_PASS_0;
2984 return generic_action_ok_displaylist_push(path, NULL, label, type, idx,
2985 entry_idx, ACTION_OK_DL_SHADER_PASS);
2986 }
2987
menu_input_st_string_cb_save_preset(void * userdata,const char * str)2988 static void menu_input_st_string_cb_save_preset(void *userdata,
2989 const char *str)
2990 {
2991 if (!string_is_empty(str))
2992 {
2993 rarch_setting_t *setting = NULL;
2994 bool ret = false;
2995 const char *label = menu_input_dialog_get_label_buffer();
2996 settings_t *settings = config_get_ptr();
2997 const char *dir_video_shader = settings->paths.directory_video_shader;
2998 const char *dir_menu_config = settings->paths.directory_menu_config;
2999
3000 if (!string_is_empty(label))
3001 setting = menu_setting_find(label);
3002
3003 if (setting)
3004 {
3005 setting_set_with_string_representation(setting, str);
3006 menu_setting_generic(setting, 0, false);
3007 }
3008 else if (!string_is_empty(label))
3009 ret = menu_shader_manager_save_preset(
3010 menu_shader_get(),
3011 str,
3012 dir_video_shader,
3013 dir_menu_config,
3014 true);
3015
3016 if (ret)
3017 runloop_msg_queue_push(
3018 msg_hash_to_str(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY),
3019 1, 100, true,
3020 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3021 else
3022 runloop_msg_queue_push(
3023 msg_hash_to_str(MSG_ERROR_SAVING_SHADER_PRESET),
3024 1, 100, true,
3025 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3026 }
3027
3028 menu_input_dialog_end();
3029 }
3030
3031 DEFAULT_ACTION_DIALOG_START(action_ok_shader_preset_save_as,
3032 msg_hash_to_str(MSG_INPUT_PRESET_FILENAME),
3033 (unsigned)idx,
3034 menu_input_st_string_cb_save_preset)
3035
3036 enum
3037 {
3038 ACTION_OK_SHADER_PRESET_SAVE_GLOBAL = 0,
3039 ACTION_OK_SHADER_PRESET_SAVE_CORE,
3040 ACTION_OK_SHADER_PRESET_SAVE_PARENT,
3041 ACTION_OK_SHADER_PRESET_SAVE_GAME
3042 };
3043
3044 enum
3045 {
3046 ACTION_OK_SHADER_PRESET_REMOVE_GLOBAL = 0,
3047 ACTION_OK_SHADER_PRESET_REMOVE_CORE,
3048 ACTION_OK_SHADER_PRESET_REMOVE_PARENT,
3049 ACTION_OK_SHADER_PRESET_REMOVE_GAME
3050 };
3051
generic_action_ok_shader_preset_remove(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx,unsigned action_type)3052 static int generic_action_ok_shader_preset_remove(const char *path,
3053 const char *label, unsigned type, size_t idx, size_t entry_idx,
3054 unsigned action_type)
3055 {
3056 enum auto_shader_type preset_type;
3057 settings_t *settings = config_get_ptr();
3058 const char *dir_video_shader = settings->paths.directory_video_shader;
3059 const char *dir_menu_config = settings->paths.directory_menu_config;
3060
3061 switch (action_type)
3062 {
3063 case ACTION_OK_SHADER_PRESET_REMOVE_GLOBAL:
3064 preset_type = SHADER_PRESET_GLOBAL;
3065 break;
3066 case ACTION_OK_SHADER_PRESET_REMOVE_CORE:
3067 preset_type = SHADER_PRESET_CORE;
3068 break;
3069 case ACTION_OK_SHADER_PRESET_REMOVE_PARENT:
3070 preset_type = SHADER_PRESET_PARENT;
3071 break;
3072 case ACTION_OK_SHADER_PRESET_REMOVE_GAME:
3073 preset_type = SHADER_PRESET_GAME;
3074 break;
3075 default:
3076 return 0;
3077 }
3078
3079 if (menu_shader_manager_remove_auto_preset(preset_type,
3080 dir_video_shader, dir_menu_config))
3081 {
3082 bool refresh = false;
3083
3084 runloop_msg_queue_push(
3085 msg_hash_to_str(MSG_SHADER_PRESET_REMOVED_SUCCESSFULLY),
3086 1, 100, true,
3087 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3088
3089 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
3090 }
3091 else
3092 runloop_msg_queue_push(
3093 msg_hash_to_str(MSG_ERROR_REMOVING_SHADER_PRESET),
3094 1, 100, true,
3095 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3096
3097 return 0;
3098 }
3099
generic_action_ok_shader_preset_save(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx,unsigned action_type)3100 static int generic_action_ok_shader_preset_save(const char *path,
3101 const char *label, unsigned type, size_t idx, size_t entry_idx,
3102 unsigned action_type)
3103 {
3104 enum auto_shader_type preset_type;
3105 settings_t *settings = config_get_ptr();
3106 const char *dir_video_shader = settings->paths.directory_video_shader;
3107 const char *dir_menu_config = settings->paths.directory_menu_config;
3108
3109 switch (action_type)
3110 {
3111 case ACTION_OK_SHADER_PRESET_SAVE_GLOBAL:
3112 preset_type = SHADER_PRESET_GLOBAL;
3113 break;
3114 case ACTION_OK_SHADER_PRESET_SAVE_CORE:
3115 preset_type = SHADER_PRESET_CORE;
3116 break;
3117 case ACTION_OK_SHADER_PRESET_SAVE_PARENT:
3118 preset_type = SHADER_PRESET_PARENT;
3119 break;
3120 case ACTION_OK_SHADER_PRESET_SAVE_GAME:
3121 preset_type = SHADER_PRESET_GAME;
3122 break;
3123 default:
3124 return 0;
3125 }
3126
3127 /* Save Auto Preset and have it immediately reapply the preset
3128 * TODO: This seems necessary so that the loaded shader gains a link to the file saved
3129 * But this is slow and seems like a redundant way to do this
3130 * It seems like it would be better to just set the path and shader_preset_loaded
3131 * on the current shader */
3132 if (menu_shader_manager_save_auto_preset(menu_shader_get(), preset_type,
3133 dir_video_shader, dir_menu_config,
3134 true))
3135 runloop_msg_queue_push(
3136 msg_hash_to_str(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY),
3137 1, 100, true,
3138 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3139 else
3140 runloop_msg_queue_push(
3141 msg_hash_to_str(MSG_ERROR_SAVING_SHADER_PRESET),
3142 1, 100, true,
3143 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3144
3145 return 0;
3146 }
3147
action_ok_shader_preset_save_global(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3148 static int action_ok_shader_preset_save_global(const char *path,
3149 const char *label, unsigned type, size_t idx, size_t entry_idx)
3150 {
3151 return generic_action_ok_shader_preset_save(path, label, type,
3152 idx, entry_idx, ACTION_OK_SHADER_PRESET_SAVE_GLOBAL);
3153 }
3154
action_ok_shader_preset_save_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3155 static int action_ok_shader_preset_save_core(const char *path,
3156 const char *label, unsigned type, size_t idx, size_t entry_idx)
3157 {
3158 return generic_action_ok_shader_preset_save(path, label, type,
3159 idx, entry_idx, ACTION_OK_SHADER_PRESET_SAVE_CORE);
3160 }
3161
action_ok_shader_preset_save_parent(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3162 static int action_ok_shader_preset_save_parent(const char *path,
3163 const char *label, unsigned type, size_t idx, size_t entry_idx)
3164 {
3165 return generic_action_ok_shader_preset_save(path, label, type,
3166 idx, entry_idx, ACTION_OK_SHADER_PRESET_SAVE_PARENT);
3167 }
3168
action_ok_shader_preset_save_game(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3169 static int action_ok_shader_preset_save_game(const char *path,
3170 const char *label, unsigned type, size_t idx, size_t entry_idx)
3171 {
3172 return generic_action_ok_shader_preset_save(path, label, type,
3173 idx, entry_idx, ACTION_OK_SHADER_PRESET_SAVE_GAME);
3174 }
3175
action_ok_shader_preset_remove_global(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3176 static int action_ok_shader_preset_remove_global(const char *path,
3177 const char *label, unsigned type, size_t idx, size_t entry_idx)
3178 {
3179 return generic_action_ok_shader_preset_remove(path, label, type,
3180 idx, entry_idx, ACTION_OK_SHADER_PRESET_REMOVE_GLOBAL);
3181 }
3182
action_ok_shader_preset_remove_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3183 static int action_ok_shader_preset_remove_core(const char *path,
3184 const char *label, unsigned type, size_t idx, size_t entry_idx)
3185 {
3186 return generic_action_ok_shader_preset_remove(path, label, type,
3187 idx, entry_idx, ACTION_OK_SHADER_PRESET_REMOVE_CORE);
3188 }
3189
action_ok_shader_preset_remove_parent(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3190 static int action_ok_shader_preset_remove_parent(const char *path,
3191 const char *label, unsigned type, size_t idx, size_t entry_idx)
3192 {
3193 return generic_action_ok_shader_preset_remove(path, label, type,
3194 idx, entry_idx, ACTION_OK_SHADER_PRESET_REMOVE_PARENT);
3195 }
3196
action_ok_shader_preset_remove_game(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3197 static int action_ok_shader_preset_remove_game(const char *path,
3198 const char *label, unsigned type, size_t idx, size_t entry_idx)
3199 {
3200 return generic_action_ok_shader_preset_remove(path, label, type,
3201 idx, entry_idx, ACTION_OK_SHADER_PRESET_REMOVE_GAME);
3202 }
3203 #endif
3204
3205 #ifdef HAVE_NETWORKING
action_ok_wifi(const char * path,const char * label_setting,unsigned type,size_t idx,size_t entry_idx)3206 static int action_ok_wifi(const char *path, const char *label_setting,
3207 unsigned type, size_t idx, size_t entry_idx)
3208 {
3209 wifi_network_scan_t* scan = driver_wifi_get_ssids();
3210 if (idx >= RBUF_LEN(scan->net_list))
3211 return -1;
3212
3213 if (scan->net_list[idx].saved_password)
3214 {
3215 /* No need to ask for a password, should be stored */
3216 task_push_wifi_connect(NULL, &scan->net_list[idx]);
3217 return 0;
3218 }
3219 else
3220 {
3221 /* Show password input dialog */
3222 menu_input_ctx_line_t line;
3223 line.label = "Passphrase";
3224 line.label_setting = label_setting;
3225 line.type = type;
3226 line.idx = (unsigned)idx;
3227 line.cb = menu_input_wifi_cb;
3228 if (!menu_input_dialog_start(&line))
3229 return -1;
3230 return 0;
3231 }
3232 }
3233 #endif
3234
action_ok_video_filter_remove(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3235 static int action_ok_video_filter_remove(const char *path,
3236 const char *label, unsigned type, size_t idx, size_t entry_idx)
3237 {
3238 settings_t *settings = config_get_ptr();
3239
3240 if (!settings)
3241 return menu_cbs_exit();
3242
3243 if (!string_is_empty(settings->paths.path_softfilter_plugin))
3244 {
3245 bool refresh = false;
3246
3247 /* Unload video filter */
3248 settings->paths.path_softfilter_plugin[0] = '\0';
3249 command_event(CMD_EVENT_REINIT, NULL);
3250
3251 /* Refresh menu */
3252 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
3253 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
3254 }
3255
3256 return 0;
3257 }
3258
action_ok_audio_dsp_plugin_remove(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3259 static int action_ok_audio_dsp_plugin_remove(const char *path,
3260 const char *label, unsigned type, size_t idx, size_t entry_idx)
3261 {
3262 settings_t *settings = config_get_ptr();
3263
3264 if (!settings)
3265 return menu_cbs_exit();
3266
3267 if (!string_is_empty(settings->paths.path_audio_dsp_plugin))
3268 {
3269 bool refresh = false;
3270
3271 /* Unload dsp plugin filter */
3272 settings->paths.path_audio_dsp_plugin[0] = '\0';
3273 command_event(CMD_EVENT_DSP_FILTER_INIT, NULL);
3274
3275 /* Refresh menu */
3276 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
3277 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
3278 }
3279
3280 return 0;
3281 }
3282
3283 #ifdef HAVE_CHEATS
menu_input_st_string_cb_cheat_file_save_as(void * userdata,const char * str)3284 static void menu_input_st_string_cb_cheat_file_save_as(
3285 void *userdata, const char *str)
3286 {
3287 if (str && *str)
3288 {
3289 rarch_setting_t *setting = NULL;
3290 const char *label = menu_input_dialog_get_label_buffer();
3291 settings_t *settings = config_get_ptr();
3292 const char *path_cheat_database = settings->paths.path_cheat_database;
3293
3294 if (!string_is_empty(label))
3295 setting = menu_setting_find(label);
3296
3297 if (setting)
3298 {
3299 setting_set_with_string_representation(setting, str);
3300 menu_setting_generic(setting, 0, false);
3301 }
3302 else if (!string_is_empty(label))
3303 cheat_manager_save(str, path_cheat_database,
3304 false);
3305 }
3306
3307 menu_input_dialog_end();
3308 }
3309 #endif
3310
3311 DEFAULT_ACTION_DIALOG_START(action_ok_enable_settings,
3312 msg_hash_to_str(MSG_INPUT_ENABLE_SETTINGS_PASSWORD),
3313 (unsigned)entry_idx,
3314 menu_input_st_string_cb_enable_settings)
3315 #ifdef HAVE_CHEATS
3316 DEFAULT_ACTION_DIALOG_START(action_ok_cheat_file_save_as,
3317 msg_hash_to_str(MSG_INPUT_CHEAT_FILENAME),
3318 (unsigned)idx,
3319 menu_input_st_string_cb_cheat_file_save_as)
3320 #endif
3321 DEFAULT_ACTION_DIALOG_START(action_ok_disable_kiosk_mode,
3322 msg_hash_to_str(MSG_INPUT_KIOSK_MODE_PASSWORD),
3323 (unsigned)entry_idx,
3324 menu_input_st_string_cb_disable_kiosk_mode)
3325 DEFAULT_ACTION_DIALOG_START(action_ok_rename_entry,
3326 msg_hash_to_str(MSG_INPUT_RENAME_ENTRY),
3327 (unsigned)entry_idx,
3328 menu_input_st_string_cb_rename_entry)
3329
3330
generic_action_ok_remap_file_operation(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx,unsigned action_type)3331 static int generic_action_ok_remap_file_operation(const char *path,
3332 const char *label, unsigned type, size_t idx, size_t entry_idx,
3333 unsigned action_type)
3334 {
3335 #ifdef HAVE_CONFIGFILE
3336 char directory[PATH_MAX_LENGTH];
3337 char file[PATH_MAX_LENGTH];
3338 char content_dir[PATH_MAX_LENGTH];
3339 struct retro_system_info *system = runloop_get_libretro_system_info();
3340 const char *core_name = system ? system->library_name : NULL;
3341 settings_t *settings = config_get_ptr();
3342 const char *path_dir_input_remapping = settings->paths.directory_input_remapping;
3343
3344 directory[0] = file[0] = '\0';
3345
3346 if (!string_is_empty(core_name))
3347 fill_pathname_join(
3348 directory,
3349 path_dir_input_remapping,
3350 core_name,
3351 sizeof(directory));
3352
3353 switch (action_type)
3354 {
3355 case ACTION_OK_REMAP_FILE_SAVE_CORE:
3356 case ACTION_OK_REMAP_FILE_REMOVE_CORE:
3357 if (!string_is_empty(core_name))
3358 fill_pathname_join(file, core_name, core_name, sizeof(file));
3359 break;
3360 case ACTION_OK_REMAP_FILE_SAVE_GAME:
3361 case ACTION_OK_REMAP_FILE_REMOVE_GAME:
3362 if (!string_is_empty(core_name))
3363 fill_pathname_join(file, core_name,
3364 path_basename(path_get(RARCH_PATH_BASENAME)), sizeof(file));
3365 break;
3366 case ACTION_OK_REMAP_FILE_SAVE_CONTENT_DIR:
3367 case ACTION_OK_REMAP_FILE_REMOVE_CONTENT_DIR:
3368 if (!string_is_empty(core_name))
3369 {
3370 fill_pathname_parent_dir_name(content_dir, path_get(RARCH_PATH_BASENAME), sizeof(content_dir));
3371 fill_pathname_join(file, core_name,
3372 content_dir, sizeof(file));
3373 }
3374 break;
3375 }
3376
3377 if (!path_is_directory(directory))
3378 path_mkdir(directory);
3379
3380 if (action_type < ACTION_OK_REMAP_FILE_REMOVE_CORE)
3381 {
3382 if (input_remapping_save_file(file))
3383 {
3384 #ifdef HAVE_CONFIGFILE
3385 switch (action_type)
3386 {
3387 case ACTION_OK_REMAP_FILE_SAVE_CORE:
3388 rarch_ctl(RARCH_CTL_SET_REMAPS_CORE_ACTIVE, NULL);
3389 break;
3390 case ACTION_OK_REMAP_FILE_SAVE_GAME:
3391 rarch_ctl(RARCH_CTL_SET_REMAPS_GAME_ACTIVE, NULL);
3392 break;
3393 case ACTION_OK_REMAP_FILE_SAVE_CONTENT_DIR:
3394 rarch_ctl(RARCH_CTL_SET_REMAPS_CONTENT_DIR_ACTIVE, NULL);
3395 break;
3396 }
3397 #endif
3398
3399 runloop_msg_queue_push(
3400 msg_hash_to_str(MSG_REMAP_FILE_SAVED_SUCCESSFULLY),
3401 1, 100, true,
3402 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3403 }
3404 else
3405 runloop_msg_queue_push(
3406 msg_hash_to_str(MSG_ERROR_SAVING_REMAP_FILE),
3407 1, 100, true,
3408 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3409 }
3410 else
3411 {
3412 if (input_remapping_remove_file(file, path_dir_input_remapping))
3413 {
3414 switch (action_type)
3415 {
3416 case ACTION_OK_REMAP_FILE_REMOVE_CORE:
3417 if (rarch_ctl(RARCH_CTL_IS_REMAPS_CORE_ACTIVE, NULL))
3418 {
3419 input_remapping_deinit();
3420 input_remapping_set_defaults(false);
3421 }
3422 break;
3423 case ACTION_OK_REMAP_FILE_REMOVE_GAME:
3424 if (rarch_ctl(RARCH_CTL_IS_REMAPS_GAME_ACTIVE, NULL))
3425 {
3426 input_remapping_deinit();
3427 input_remapping_set_defaults(false);
3428 }
3429 break;
3430 case ACTION_OK_REMAP_FILE_REMOVE_CONTENT_DIR:
3431 if (rarch_ctl(RARCH_CTL_IS_REMAPS_CONTENT_DIR_ACTIVE, NULL))
3432 {
3433 input_remapping_deinit();
3434 input_remapping_set_defaults(false);
3435 }
3436 break;
3437 }
3438
3439 runloop_msg_queue_push(
3440 msg_hash_to_str(MSG_REMAP_FILE_REMOVED_SUCCESSFULLY),
3441 1, 100, true,
3442 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3443 }
3444 else
3445 runloop_msg_queue_push(
3446 msg_hash_to_str(MSG_ERROR_REMOVING_REMAP_FILE),
3447 1, 100, true,
3448 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3449 }
3450 #endif
3451 return 0;
3452 }
3453
action_ok_remap_file_save_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3454 static int action_ok_remap_file_save_core(const char *path,
3455 const char *label, unsigned type, size_t idx, size_t entry_idx)
3456 {
3457 return generic_action_ok_remap_file_operation(path, label, type,
3458 idx, entry_idx, ACTION_OK_REMAP_FILE_SAVE_CORE);
3459 }
3460
action_ok_remap_file_save_content_dir(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3461 static int action_ok_remap_file_save_content_dir(const char *path,
3462 const char *label, unsigned type, size_t idx, size_t entry_idx)
3463 {
3464 return generic_action_ok_remap_file_operation(path, label, type,
3465 idx, entry_idx, ACTION_OK_REMAP_FILE_SAVE_CONTENT_DIR);
3466 }
3467
action_ok_remap_file_save_game(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3468 static int action_ok_remap_file_save_game(const char *path,
3469 const char *label, unsigned type, size_t idx, size_t entry_idx)
3470 {
3471 return generic_action_ok_remap_file_operation(path, label, type,
3472 idx, entry_idx, ACTION_OK_REMAP_FILE_SAVE_GAME);
3473 }
3474
action_ok_remap_file_remove_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3475 static int action_ok_remap_file_remove_core(const char *path,
3476 const char *label, unsigned type, size_t idx, size_t entry_idx)
3477 {
3478 return generic_action_ok_remap_file_operation(path, label, type,
3479 idx, entry_idx, ACTION_OK_REMAP_FILE_REMOVE_CORE);
3480 }
3481
action_ok_remap_file_remove_content_dir(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3482 static int action_ok_remap_file_remove_content_dir(const char *path,
3483 const char *label, unsigned type, size_t idx, size_t entry_idx)
3484 {
3485 return generic_action_ok_remap_file_operation(path, label, type,
3486 idx, entry_idx, ACTION_OK_REMAP_FILE_REMOVE_CONTENT_DIR);
3487 }
3488
action_ok_remap_file_remove_game(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3489 static int action_ok_remap_file_remove_game(const char *path,
3490 const char *label, unsigned type, size_t idx, size_t entry_idx)
3491 {
3492 return generic_action_ok_remap_file_operation(path, label, type,
3493 idx, entry_idx, ACTION_OK_REMAP_FILE_REMOVE_GAME);
3494 }
3495
action_ok_path_use_directory(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3496 int action_ok_path_use_directory(const char *path,
3497 const char *label, unsigned type, size_t idx, size_t entry_idx)
3498 {
3499 filebrowser_clear_type();
3500 return generic_action_ok(NULL, label, type, idx, entry_idx,
3501 ACTION_OK_SET_DIRECTORY, MSG_UNKNOWN);
3502 }
3503
3504 #ifdef HAVE_LIBRETRODB
action_ok_scan_file(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3505 static int action_ok_scan_file(const char *path,
3506 const char *label, unsigned type, size_t idx, size_t entry_idx)
3507 {
3508 return action_scan_file(path, label, type, idx);
3509 }
3510
action_ok_path_scan_directory(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3511 static int action_ok_path_scan_directory(const char *path,
3512 const char *label, unsigned type, size_t idx, size_t entry_idx)
3513 {
3514 return action_scan_directory(NULL, label, type, idx);
3515 }
3516 #endif
3517
action_ok_path_manual_scan_directory(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3518 static int action_ok_path_manual_scan_directory(const char *path,
3519 const char *label, unsigned type, size_t idx, size_t entry_idx)
3520 {
3521 char content_dir[PATH_MAX_LENGTH];
3522 const char *flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST);
3523 unsigned flush_type = 0;
3524 const char *menu_path = NULL;
3525
3526 content_dir[0] = '\0';
3527
3528 /* 'Reset' file browser */
3529 filebrowser_clear_type();
3530
3531 /* Get user-selected scan directory */
3532 menu_entries_get_last_stack(&menu_path,
3533 NULL, NULL, NULL, NULL);
3534
3535 if (!string_is_empty(menu_path))
3536 strlcpy(content_dir, menu_path, sizeof(content_dir));
3537
3538 #ifdef HAVE_COCOATOUCH
3539 {
3540 /* For iOS, set the path using realpath because the path name
3541 * can start with /private and this ensures the path starts with it.
3542 * This will allow the path to be properly substituted when
3543 * fill_pathname_expand_special() is called. */
3544 char real_content_dir[PATH_MAX_LENGTH];
3545 real_content_dir[0] = '\0';
3546 realpath(content_dir, real_content_dir);
3547 strlcpy(content_dir, real_content_dir, sizeof(content_dir));
3548 }
3549 #endif
3550
3551 /* Update manual content scan settings */
3552 manual_content_scan_set_menu_content_dir(content_dir);
3553
3554 /* Return to 'manual content scan' menu */
3555 menu_entries_flush_stack(flush_char, flush_type);
3556
3557 return 0;
3558 }
3559
action_ok_core_deferred_set(const char * new_core_path,const char * content_label,unsigned type,size_t idx,size_t entry_idx)3560 static int action_ok_core_deferred_set(const char *new_core_path,
3561 const char *content_label, unsigned type, size_t idx, size_t entry_idx)
3562 {
3563 size_t selection = menu_navigation_get_selection();
3564 struct playlist_entry entry = {0};
3565 menu_handle_t *menu = menu_driver_get_ptr();
3566 core_info_t *core_info = NULL;
3567 const char *core_display_name = NULL;
3568 char resolved_core_path[PATH_MAX_LENGTH];
3569 char msg[PATH_MAX_LENGTH];
3570
3571 resolved_core_path[0] = '\0';
3572 msg[0] = '\0';
3573
3574 if (!menu ||
3575 string_is_empty(new_core_path))
3576 return menu_cbs_exit();
3577
3578 /* Get core display name */
3579 if (core_info_find(new_core_path, &core_info))
3580 core_display_name = core_info->display_name;
3581
3582 if (string_is_empty(core_display_name))
3583 core_display_name = path_basename_nocompression(new_core_path);
3584
3585 /* Get 'real' core path */
3586 strlcpy(resolved_core_path, new_core_path, sizeof(resolved_core_path));
3587 playlist_resolve_path(PLAYLIST_SAVE, true, resolved_core_path, sizeof(resolved_core_path));
3588
3589 /* the update function reads our entry
3590 * as const, so these casts are safe */
3591 entry.core_path = (char*)resolved_core_path;
3592 entry.core_name = (char*)core_display_name;
3593
3594 command_playlist_update_write(
3595 NULL,
3596 menu->scratchpad.unsigned_var,
3597 &entry);
3598
3599 /* Provide visual feedback */
3600 strlcpy(msg, msg_hash_to_str(MSG_SET_CORE_ASSOCIATION), sizeof(msg));
3601 strlcat(msg, core_display_name, sizeof(msg));
3602 runloop_msg_queue_push(msg, 1, 100, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3603
3604 menu_entries_pop_stack(&selection, 0, 1);
3605 menu_navigation_set_selection(selection);
3606
3607 return 0;
3608 }
3609
action_ok_deferred_list_stub(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3610 static int action_ok_deferred_list_stub(const char *path,
3611 const char *label, unsigned type, size_t idx, size_t entry_idx)
3612 {
3613 return 0;
3614 }
3615
3616 #if defined(HAVE_LAKKA_SWITCH) || defined(HAVE_LIBNX)
action_ok_set_switch_cpu_profile(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3617 static int action_ok_set_switch_cpu_profile(const char *path,
3618 const char *label, unsigned type, size_t idx, size_t entry_idx)
3619 {
3620 char command[PATH_MAX_LENGTH] = {0};
3621 #ifdef HAVE_LAKKA_SWITCH
3622 char* profile_name = SWITCH_CPU_PROFILES[entry_idx];
3623
3624 snprintf(command, sizeof(command), "cpu-profile set '%s'", profile_name);
3625
3626 system(command);
3627 snprintf(command, sizeof(command), "Current profile set to %s", profile_name);
3628 #else
3629 unsigned profile_clock = SWITCH_CPU_SPEEDS_VALUES[entry_idx];
3630 settings_t *settings = config_get_ptr();
3631
3632 settings->uints.libnx_overclock = entry_idx;
3633
3634 if (hosversionBefore(8, 0, 0))
3635 pcvSetClockRate(PcvModule_CpuBus, (u32)profile_clock);
3636 else
3637 {
3638 ClkrstSession session = {0};
3639 clkrstOpenSession(&session, PcvModuleId_CpuBus, 3);
3640 clkrstSetClockRate(&session, profile_clock);
3641 clkrstCloseSession(&session);
3642 }
3643 snprintf(command, sizeof(command),
3644 "Current Clock set to %i", profile_clock);
3645 #endif
3646
3647 runloop_msg_queue_push(command, 1, 90, true, NULL,
3648 MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3649
3650 return menu_cbs_exit();
3651 }
3652 #endif
3653
3654 #ifdef HAVE_LAKKA_SWITCH
3655
action_ok_set_switch_gpu_profile(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3656 static int action_ok_set_switch_gpu_profile(const char *path,
3657 const char *label, unsigned type, size_t idx, size_t entry_idx)
3658 {
3659 char command[PATH_MAX_LENGTH];
3660 char *profile_name = SWITCH_GPU_PROFILES[entry_idx];
3661
3662 command[0] = '\0';
3663
3664 snprintf(command, sizeof(command),
3665 "gpu-profile set '%s'",
3666 profile_name);
3667
3668 system(command);
3669
3670 snprintf(command, sizeof(command),
3671 "Current profile set to %s",
3672 profile_name);
3673
3674 runloop_msg_queue_push(command, 1, 90, true, NULL,
3675 MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3676
3677 return menu_cbs_exit();
3678 }
3679
3680 #endif
3681
action_ok_load_core_deferred(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3682 static int action_ok_load_core_deferred(const char *path,
3683 const char *label, unsigned type, size_t idx, size_t entry_idx)
3684 {
3685 content_ctx_info_t content_info;
3686 menu_handle_t *menu = menu_driver_get_ptr();
3687
3688 content_info.argc = 0;
3689 content_info.argv = NULL;
3690 content_info.args = NULL;
3691 content_info.environ_get = NULL;
3692
3693 if (!menu)
3694 return menu_cbs_exit();
3695
3696 if (!task_push_load_content_with_new_core_from_menu(
3697 path, menu->deferred_path,
3698 &content_info,
3699 CORE_TYPE_PLAIN,
3700 NULL, NULL))
3701 return -1;
3702 content_add_to_playlist(path);
3703 menu_driver_set_last_start_content(path);
3704
3705 return 0;
3706 }
3707
DEFAULT_ACTION_OK_START_BUILTIN_CORE(action_ok_start_net_retropad_core,CORE_TYPE_NETRETROPAD)3708 DEFAULT_ACTION_OK_START_BUILTIN_CORE(action_ok_start_net_retropad_core, CORE_TYPE_NETRETROPAD)
3709 DEFAULT_ACTION_OK_START_BUILTIN_CORE(action_ok_start_gong_core, CORE_TYPE_GONG)
3710 DEFAULT_ACTION_OK_START_BUILTIN_CORE(action_ok_start_video_processor_core, CORE_TYPE_VIDEO_PROCESSOR)
3711
3712 #if defined(HAVE_FFMPEG) || defined(HAVE_MPV)
3713 static int action_ok_file_load_ffmpeg(const char *path,
3714 const char *label, unsigned type, size_t idx, size_t entry_idx)
3715 {
3716 char new_path[PATH_MAX_LENGTH];
3717 const char *menu_path = NULL;
3718 file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(0);
3719
3720 file_list_get_last(menu_stack, &menu_path, NULL, NULL, NULL);
3721
3722 new_path[0] = '\0';
3723
3724 if (!string_is_empty(menu_path))
3725 fill_pathname_join(new_path, menu_path, path,
3726 sizeof(new_path));
3727
3728 /* TODO/FIXME - should become runtime optional */
3729 #ifdef HAVE_MPV
3730 return default_action_ok_load_content_with_core_from_menu(
3731 new_path, CORE_TYPE_MPV);
3732 #else
3733 return default_action_ok_load_content_with_core_from_menu(
3734 new_path, CORE_TYPE_FFMPEG);
3735 #endif
3736 }
3737 #endif
3738
action_ok_audio_run(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3739 static int action_ok_audio_run(const char *path,
3740 const char *label, unsigned type, size_t idx, size_t entry_idx)
3741 {
3742 char combined_path[PATH_MAX_LENGTH];
3743 menu_handle_t *menu = menu_driver_get_ptr();
3744
3745 combined_path[0] = '\0';
3746
3747 if (!menu)
3748 return menu_cbs_exit();
3749
3750 fill_pathname_join(combined_path, menu->scratch2_buf,
3751 menu->scratch_buf, sizeof(combined_path));
3752
3753 /* TODO/FIXME - should become runtime optional */
3754 #ifdef HAVE_MPV
3755 return default_action_ok_load_content_with_core_from_menu(
3756 combined_path, CORE_TYPE_MPV);
3757 #else
3758 return default_action_ok_load_content_with_core_from_menu(
3759 combined_path, CORE_TYPE_FFMPEG);
3760 #endif
3761 }
3762
action_ok_core_option_dropdown_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3763 int action_ok_core_option_dropdown_list(const char *path,
3764 const char *label, unsigned type, size_t idx, size_t entry_idx)
3765 {
3766 core_option_manager_t *coreopts = NULL;
3767 struct core_option *option = NULL;
3768 const char *value_label_0 = NULL;
3769 const char *value_label_1 = NULL;
3770 size_t option_index;
3771 char option_path_str[256];
3772 char option_lbl_str[256];
3773
3774 option_path_str[0] = '\0';
3775 option_lbl_str[0] = '\0';
3776
3777 /* Boolean options are toggled directly,
3778 * without the use of a drop-down list */
3779
3780 /* > Get current option index */
3781 if (type < MENU_SETTINGS_CORE_OPTION_START)
3782 goto push_dropdown_list;
3783
3784 option_index = type - MENU_SETTINGS_CORE_OPTION_START;
3785
3786 /* > Get core options struct */
3787 if (!rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts) ||
3788 (option_index >= coreopts->size))
3789 goto push_dropdown_list;
3790
3791 /* > Get current option, and check whether
3792 * it has exactly 2 values (i.e. on/off) */
3793 option = (struct core_option*)&coreopts->opts[option_index];
3794
3795 if (!option ||
3796 (option->vals->size != 2) ||
3797 ((option->index != 0) &&
3798 (option->index != 1)))
3799 goto push_dropdown_list;
3800
3801 /* > Check whether option values correspond
3802 * to a boolean toggle */
3803 value_label_0 = option->val_labels->elems[0].data;
3804 value_label_1 = option->val_labels->elems[1].data;
3805
3806 if (string_is_empty(value_label_0) ||
3807 string_is_empty(value_label_1) ||
3808 !((string_is_equal(value_label_0, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)) &&
3809 string_is_equal(value_label_1, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) ||
3810 (string_is_equal(value_label_0, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) &&
3811 string_is_equal(value_label_1, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)))))
3812 goto push_dropdown_list;
3813
3814 /* > Update value and return */
3815 core_option_manager_set_val(coreopts, option_index,
3816 (option->index == 0) ? 1 : 0);
3817
3818 return 0;
3819
3820 push_dropdown_list:
3821
3822 /* If this option is not a boolean toggle,
3823 * push drop-down list */
3824 snprintf(option_path_str, sizeof(option_path_str),
3825 "core_option_%d", (int)idx);
3826 snprintf(option_lbl_str, sizeof(option_lbl_str),
3827 "%d", type);
3828
3829 /* TODO/FIXME: This should be refactored to make
3830 * use of a core-option-specific drop-down list,
3831 * rather than hijacking the generic one... */
3832 generic_action_ok_displaylist_push(
3833 option_path_str, NULL,
3834 option_lbl_str, 0, idx, 0,
3835 ACTION_OK_DL_DROPDOWN_BOX_LIST);
3836
3837 return 0;
3838 }
3839
3840 #ifdef HAVE_CHEATS
action_ok_cheat_reload_cheats(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3841 static int action_ok_cheat_reload_cheats(const char *path,
3842 const char *label, unsigned type, size_t idx, size_t entry_idx)
3843 {
3844 bool refresh = false;
3845 settings_t *settings = config_get_ptr();
3846 const char *path_cheat_database = settings->paths.path_cheat_database;
3847
3848 cheat_manager_realloc(0, CHEAT_HANDLER_TYPE_EMU);
3849
3850 cheat_manager_load_game_specific_cheats(
3851 path_cheat_database);
3852
3853 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
3854 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
3855 return 0;
3856 }
3857 #endif
3858
action_ok_start_recording(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3859 static int action_ok_start_recording(const char *path,
3860 const char *label, unsigned type, size_t idx, size_t entry_idx)
3861 {
3862 streaming_set_state(false);
3863 command_event(CMD_EVENT_RECORD_INIT, NULL);
3864 return generic_action_ok_command(CMD_EVENT_RESUME);
3865 }
3866
action_ok_start_streaming(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3867 static int action_ok_start_streaming(const char *path,
3868 const char *label, unsigned type, size_t idx, size_t entry_idx)
3869 {
3870 streaming_set_state(true);
3871 command_event(CMD_EVENT_RECORD_INIT, NULL);
3872 return generic_action_ok_command(CMD_EVENT_RESUME);
3873 }
3874
action_ok_stop_recording(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3875 static int action_ok_stop_recording(const char *path,
3876 const char *label, unsigned type, size_t idx, size_t entry_idx)
3877 {
3878 command_event(CMD_EVENT_RECORD_DEINIT, NULL);
3879 return generic_action_ok_command(CMD_EVENT_RESUME);
3880 }
3881
action_ok_stop_streaming(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3882 static int action_ok_stop_streaming(const char *path,
3883 const char *label, unsigned type, size_t idx, size_t entry_idx)
3884 {
3885 command_event(CMD_EVENT_RECORD_DEINIT, NULL);
3886 return generic_action_ok_command(CMD_EVENT_RESUME);
3887 }
3888
3889 #ifdef HAVE_CHEATS
action_ok_cheat_add_top(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3890 static int action_ok_cheat_add_top(const char *path,
3891 const char *label, unsigned type, size_t idx, size_t entry_idx)
3892 {
3893 int i;
3894 struct item_cheat tmp;
3895 char msg[256];
3896 bool refresh = false;
3897 unsigned int new_size = cheat_manager_get_size() + 1;
3898
3899 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
3900 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
3901 cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_EMU);
3902
3903 memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.size-1],
3904 sizeof(struct item_cheat));
3905 tmp.idx = 0;
3906
3907 for (i = cheat_manager_state.size-2; i >=0; i--)
3908 {
3909 memcpy(&cheat_manager_state.cheats[i+1],
3910 &cheat_manager_state.cheats[i], sizeof(struct item_cheat));
3911 cheat_manager_state.cheats[i+1].idx++;
3912 }
3913
3914 memcpy(&cheat_manager_state.cheats[0], &tmp, sizeof(struct item_cheat));
3915
3916 strlcpy(msg, msg_hash_to_str(MSG_CHEAT_ADD_TOP_SUCCESS), sizeof(msg));
3917 msg[sizeof(msg) - 1] = 0;
3918
3919 runloop_msg_queue_push(msg, 1, 180, true, NULL,
3920 MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3921
3922 return 0;
3923 }
3924
action_ok_cheat_add_bottom(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3925 static int action_ok_cheat_add_bottom(const char *path,
3926 const char *label, unsigned type, size_t idx, size_t entry_idx)
3927 {
3928 char msg[256];
3929 bool refresh = false;
3930 unsigned int new_size = cheat_manager_get_size() + 1;
3931
3932 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
3933 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
3934 cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_EMU);
3935
3936 msg[0] = '\0';
3937 strlcpy(msg,
3938 msg_hash_to_str(MSG_CHEAT_ADD_BOTTOM_SUCCESS), sizeof(msg));
3939 msg[sizeof(msg) - 1] = 0;
3940
3941 runloop_msg_queue_push(msg, 1, 180, true, NULL,
3942 MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3943
3944 return 0;
3945 }
3946
action_ok_cheat_delete_all(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3947 static int action_ok_cheat_delete_all(const char *path,
3948 const char *label, unsigned type, size_t idx, size_t entry_idx)
3949 {
3950 char msg[256];
3951 bool refresh = false;
3952
3953 msg[0] = '\0';
3954 cheat_manager_state.delete_state = 0;
3955 cheat_manager_realloc(0, CHEAT_HANDLER_TYPE_EMU);
3956 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
3957 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
3958
3959 strlcpy(msg,
3960 msg_hash_to_str(MSG_CHEAT_DELETE_ALL_SUCCESS), sizeof(msg));
3961 msg[sizeof(msg) - 1] = 0;
3962
3963 runloop_msg_queue_push(msg, 1, 180, true, NULL,
3964 MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3965
3966 return 0;
3967 }
3968
action_ok_cheat_add_new_after(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)3969 static int action_ok_cheat_add_new_after(const char *path,
3970 const char *label, unsigned type, size_t idx, size_t entry_idx)
3971 {
3972 int i;
3973 char msg[256];
3974 struct item_cheat tmp;
3975 bool refresh = false;
3976 unsigned int new_size = cheat_manager_get_size() + 1;
3977
3978 cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_EMU);
3979
3980 memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.size-1],
3981 sizeof(struct item_cheat));
3982 tmp.idx = cheat_manager_state.working_cheat.idx+1;
3983
3984 for (i = cheat_manager_state.size-2; i >= (int)(cheat_manager_state.working_cheat.idx+1); i--)
3985 {
3986 memcpy(&cheat_manager_state.cheats[i+1], &cheat_manager_state.cheats[i], sizeof(struct item_cheat));
3987 cheat_manager_state.cheats[i+1].idx++;
3988 }
3989
3990 memcpy(&cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx+1], &tmp, sizeof(struct item_cheat));
3991
3992 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
3993 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
3994
3995 strlcpy(msg, msg_hash_to_str(MSG_CHEAT_ADD_AFTER_SUCCESS), sizeof(msg));
3996 msg[sizeof(msg) - 1] = 0;
3997
3998 runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3999
4000 return 0;
4001 }
4002
action_ok_cheat_add_new_before(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4003 static int action_ok_cheat_add_new_before(const char *path,
4004 const char *label, unsigned type, size_t idx, size_t entry_idx)
4005 {
4006 int i;
4007 char msg[256];
4008 struct item_cheat tmp;
4009 bool refresh = false;
4010 unsigned int new_size = cheat_manager_get_size() + 1;
4011
4012 cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_EMU);
4013
4014 memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.size-1], sizeof(struct item_cheat));
4015 tmp.idx = cheat_manager_state.working_cheat.idx;
4016
4017 for (i = cheat_manager_state.size-2; i >=(int)tmp.idx; i--)
4018 {
4019 memcpy(&cheat_manager_state.cheats[i+1], &cheat_manager_state.cheats[i], sizeof(struct item_cheat));
4020 cheat_manager_state.cheats[i+1].idx++;
4021 }
4022
4023 memcpy(&cheat_manager_state.cheats[tmp.idx],
4024 &tmp, sizeof(struct item_cheat));
4025 memcpy(&cheat_manager_state.working_cheat,
4026 &tmp, sizeof(struct item_cheat));
4027
4028 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
4029 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
4030
4031 strlcpy(msg, msg_hash_to_str(MSG_CHEAT_ADD_BEFORE_SUCCESS), sizeof(msg));
4032 msg[sizeof(msg) - 1] = 0;
4033
4034 runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
4035
4036 return 0;
4037 }
4038
action_ok_cheat_copy_before(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4039 static int action_ok_cheat_copy_before(const char *path,
4040 const char *label, unsigned type, size_t idx, size_t entry_idx)
4041 {
4042 int i;
4043 struct item_cheat tmp;
4044 char msg[256];
4045 bool refresh = false;
4046 unsigned int new_size = cheat_manager_get_size() + 1;
4047 cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO);
4048
4049 memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx], sizeof(struct item_cheat));
4050 tmp.idx = cheat_manager_state.working_cheat.idx;
4051 if (tmp.code)
4052 tmp.code = strdup(tmp.code);
4053 if (tmp.desc)
4054 tmp.desc = strdup(tmp.desc);
4055
4056 for (i = cheat_manager_state.size-2; i >=(int)tmp.idx; i--)
4057 {
4058 memcpy(&cheat_manager_state.cheats[i+1], &cheat_manager_state.cheats[i], sizeof(struct item_cheat));
4059 cheat_manager_state.cheats[i+1].idx++;
4060 }
4061
4062 memcpy(&cheat_manager_state.cheats[tmp.idx], &tmp, sizeof(struct item_cheat));
4063 memcpy(&cheat_manager_state.working_cheat, &tmp, sizeof(struct item_cheat));
4064
4065 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
4066 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
4067
4068 strlcpy(msg, msg_hash_to_str(MSG_CHEAT_COPY_BEFORE_SUCCESS), sizeof(msg));
4069 msg[sizeof(msg) - 1] = 0;
4070
4071 runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
4072
4073 return 0;
4074 }
4075
action_ok_cheat_copy_after(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4076 static int action_ok_cheat_copy_after(const char *path,
4077 const char *label, unsigned type, size_t idx, size_t entry_idx)
4078 {
4079 int i;
4080 struct item_cheat tmp;
4081 char msg[256];
4082 bool refresh = false;
4083 unsigned int new_size = cheat_manager_get_size() + 1;
4084
4085 cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO);
4086
4087 memcpy(&tmp, &cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx], sizeof(struct item_cheat));
4088 tmp.idx = cheat_manager_state.working_cheat.idx+1;
4089 if (tmp.code)
4090 tmp.code = strdup(tmp.code);
4091 if (tmp.desc)
4092 tmp.desc = strdup(tmp.desc);
4093
4094 for (i = cheat_manager_state.size-2; i >= (int)(cheat_manager_state.working_cheat.idx+1); i--)
4095 {
4096 memcpy(&cheat_manager_state.cheats[i+1], &cheat_manager_state.cheats[i], sizeof(struct item_cheat));
4097 cheat_manager_state.cheats[i+1].idx++;
4098 }
4099
4100 memcpy(&cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx+1], &tmp, sizeof(struct item_cheat ));
4101
4102 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
4103 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
4104
4105 strlcpy(msg, msg_hash_to_str(MSG_CHEAT_COPY_AFTER_SUCCESS), sizeof(msg));
4106 msg[sizeof(msg) - 1] = 0;
4107
4108 runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
4109
4110 return 0;
4111 }
4112
action_ok_cheat_delete(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4113 static int action_ok_cheat_delete(const char *path,
4114 const char *label, unsigned type, size_t idx, size_t entry_idx)
4115 {
4116 char msg[256];
4117 size_t new_selection_ptr = 0;
4118 unsigned int new_size = cheat_manager_get_size() - 1;
4119
4120 if (new_size >0)
4121 {
4122 unsigned i;
4123
4124 if (cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx].code)
4125 free(cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx].code);
4126 if (cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx].desc)
4127 free(cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx].desc);
4128
4129 for (i = cheat_manager_state.working_cheat.idx; i <cheat_manager_state.size-1; i++)
4130 {
4131 memcpy(&cheat_manager_state.cheats[i], &cheat_manager_state.cheats[i+1], sizeof(struct item_cheat ));
4132 cheat_manager_state.cheats[i].idx--;
4133 }
4134
4135 cheat_manager_state.cheats[cheat_manager_state.size-1].code = NULL;
4136 cheat_manager_state.cheats[cheat_manager_state.size-1].desc = NULL;
4137 cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx].desc = NULL;
4138 cheat_manager_state.cheats[cheat_manager_state.working_cheat.idx].code = NULL;
4139
4140 }
4141
4142 cheat_manager_realloc(new_size, CHEAT_HANDLER_TYPE_RETRO);
4143
4144 strlcpy(msg, msg_hash_to_str(MSG_CHEAT_DELETE_SUCCESS), sizeof(msg));
4145 msg[sizeof(msg) - 1] = 0;
4146
4147 runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
4148
4149 new_selection_ptr = menu_navigation_get_selection();
4150 menu_entries_pop_stack(&new_selection_ptr, 0, 1);
4151 menu_navigation_set_selection(new_selection_ptr);
4152
4153 menu_driver_ctl(RARCH_MENU_CTL_UPDATE_SAVESTATE_THUMBNAIL_PATH, NULL);
4154 menu_driver_ctl(RARCH_MENU_CTL_UPDATE_SAVESTATE_THUMBNAIL_IMAGE, NULL);
4155
4156 return 0;
4157 }
4158 #endif
4159
action_ok_file_load_imageviewer(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4160 static int action_ok_file_load_imageviewer(const char *path,
4161 const char *label, unsigned type, size_t idx, size_t entry_idx)
4162 {
4163 char fullpath[PATH_MAX_LENGTH];
4164 const char *menu_path = NULL;
4165 file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(0);
4166
4167 file_list_get_last(menu_stack, &menu_path, NULL, NULL, NULL);
4168
4169 fullpath[0] = '\0';
4170
4171 if (!string_is_empty(menu_path))
4172 fill_pathname_join(fullpath, menu_path, path,
4173 sizeof(fullpath));
4174
4175 return default_action_ok_load_content_with_core_from_menu(fullpath, CORE_TYPE_IMAGEVIEWER);
4176 }
4177
action_ok_file_load_current_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4178 static int action_ok_file_load_current_core(const char *path,
4179 const char *label, unsigned type, size_t idx, size_t entry_idx)
4180 {
4181 menu_handle_t *menu = menu_driver_get_ptr();
4182
4183 if (!menu)
4184 return menu_cbs_exit();
4185
4186 return default_action_ok_load_content_with_core_from_menu(
4187 menu->detect_content_path, CORE_TYPE_PLAIN);
4188 }
4189
action_ok_file_load_detect_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4190 static int action_ok_file_load_detect_core(const char *path,
4191 const char *label, unsigned type, size_t idx, size_t entry_idx)
4192 {
4193 content_ctx_info_t content_info;
4194 menu_handle_t *menu = menu_driver_get_ptr();
4195
4196 if (!menu)
4197 return menu_cbs_exit();
4198
4199 content_info.argc = 0;
4200 content_info.argv = NULL;
4201 content_info.args = NULL;
4202 content_info.environ_get = NULL;
4203
4204 if (!task_push_load_content_with_new_core_from_menu(
4205 path, menu->detect_content_path,
4206 &content_info,
4207 CORE_TYPE_PLAIN,
4208 NULL, NULL))
4209 return -1;
4210 content_add_to_playlist(menu->detect_content_path);
4211 menu_driver_set_last_start_content(menu->detect_content_path);
4212
4213 return 0;
4214 }
4215
action_ok_load_state(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4216 static int action_ok_load_state(const char *path,
4217 const char *label, unsigned type, size_t idx, size_t entry_idx)
4218 {
4219 settings_t *settings = config_get_ptr();
4220 bool resume = settings->bools.menu_savestate_resume;
4221
4222 if (generic_action_ok_command(CMD_EVENT_LOAD_STATE) == -1)
4223 return menu_cbs_exit();
4224
4225 if (resume)
4226 return generic_action_ok_command(CMD_EVENT_RESUME);
4227
4228 return 0;
4229 }
4230
action_ok_save_state(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4231 static int action_ok_save_state(const char *path,
4232 const char *label, unsigned type, size_t idx, size_t entry_idx)
4233 {
4234 settings_t *settings = config_get_ptr();
4235 bool resume = settings->bools.menu_savestate_resume;
4236
4237 if (generic_action_ok_command(CMD_EVENT_SAVE_STATE) == -1)
4238 return menu_cbs_exit();
4239
4240 if (resume)
4241 return generic_action_ok_command(CMD_EVENT_RESUME);
4242
4243 return 0;
4244 }
4245
action_ok_close_submenu(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4246 static int action_ok_close_submenu(const char* path,
4247 const char* label, unsigned type, size_t idx, size_t entry_idx)
4248 {
4249 return action_cancel_pop_default(path, label, type, idx);
4250 }
4251
action_ok_cheevos_toggle_hardcore_mode(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4252 static int action_ok_cheevos_toggle_hardcore_mode(const char *path,
4253 const char *label, unsigned type, size_t idx, size_t entry_idx)
4254 {
4255 generic_action_ok_command(CMD_EVENT_CHEEVOS_HARDCORE_MODE_TOGGLE);
4256 action_cancel_pop_default(path, label, type, idx);
4257 return generic_action_ok_command(CMD_EVENT_RESUME);
4258 }
4259
action_ok_undo_load_state(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4260 static int action_ok_undo_load_state(const char *path,
4261 const char *label, unsigned type, size_t idx, size_t entry_idx)
4262 {
4263 if (generic_action_ok_command(CMD_EVENT_UNDO_LOAD_STATE) == -1)
4264 return menu_cbs_exit();
4265 return generic_action_ok_command(CMD_EVENT_RESUME);
4266 }
4267
action_ok_undo_save_state(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4268 static int action_ok_undo_save_state(const char *path,
4269 const char *label, unsigned type, size_t idx, size_t entry_idx)
4270 {
4271 if (generic_action_ok_command(CMD_EVENT_UNDO_SAVE_STATE) == -1)
4272 return menu_cbs_exit();
4273 return generic_action_ok_command(CMD_EVENT_RESUME);
4274 }
4275
4276 #ifdef HAVE_NETWORKING
4277
4278 #ifdef HAVE_ZLIB
cb_decompressed(retro_task_t * task,void * task_data,void * user_data,const char * err)4279 static void cb_decompressed(retro_task_t *task,
4280 void *task_data, void *user_data, const char *err)
4281 {
4282 decompress_task_data_t *dec = (decompress_task_data_t*)task_data;
4283
4284 if (dec && !err)
4285 {
4286 unsigned enum_idx = (unsigned)(uintptr_t)user_data;
4287
4288 switch (enum_idx)
4289 {
4290 case MENU_ENUM_LABEL_CB_UPDATE_ASSETS:
4291 generic_action_ok_command(CMD_EVENT_REINIT);
4292 break;
4293 default:
4294 break;
4295 }
4296 }
4297
4298 if (err)
4299 RARCH_ERR("%s", err);
4300
4301 if (dec)
4302 {
4303 if (filestream_exists(dec->source_file))
4304 filestream_delete(dec->source_file);
4305
4306 free(dec->source_file);
4307 free(dec);
4308 }
4309 }
4310 #endif
4311
action_ok_core_updater_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4312 static int action_ok_core_updater_list(const char *path,
4313 const char *label, unsigned type, size_t idx, size_t entry_idx)
4314 {
4315 /* Get cached core updater list, initialising
4316 * it if required */
4317 core_updater_list_t *core_list = core_updater_list_get_cached();
4318
4319 if (!core_list)
4320 {
4321 core_updater_list_init_cached();
4322 core_list = core_updater_list_get_cached();
4323
4324 if (!core_list)
4325 return menu_cbs_exit();
4326 }
4327
4328 #if defined(ANDROID)
4329 if (play_feature_delivery_enabled())
4330 {
4331 settings_t *settings = config_get_ptr();
4332 const char *path_dir_libretro = settings->paths.directory_libretro;
4333 const char *path_libretro_info = settings->paths.path_libretro_info;
4334 /* Core downloads are handled via play
4335 * feature delivery
4336 * > Core list can be populated directly
4337 * using the play feature delivery
4338 * interface */
4339 struct string_list *available_cores =
4340 play_feature_delivery_available_cores();
4341 bool success = false;
4342
4343 if (!available_cores)
4344 return menu_cbs_exit();
4345
4346 core_updater_list_reset(core_list);
4347
4348 success = core_updater_list_parse_pfd_data(
4349 core_list,
4350 path_dir_libretro,
4351 path_libretro_info,
4352 available_cores);
4353
4354 string_list_free(available_cores);
4355
4356 if (!success)
4357 return menu_cbs_exit();
4358
4359 /* Ensure network is initialised */
4360 generic_action_ok_command(CMD_EVENT_NETWORK_INIT);
4361 }
4362 else
4363 #endif
4364 {
4365 bool refresh = true;
4366
4367 /* Initial setup... */
4368 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
4369 generic_action_ok_command(CMD_EVENT_NETWORK_INIT);
4370
4371 /* Push core list update task */
4372 task_push_get_core_updater_list(core_list, false, true);
4373 }
4374
4375 return generic_action_ok_displaylist_push(
4376 path, NULL, label, type, idx, entry_idx,
4377 ACTION_OK_DL_CORE_UPDATER_LIST);
4378 }
4379
cb_net_generic_subdir(retro_task_t * task,void * task_data,void * user_data,const char * err)4380 static void cb_net_generic_subdir(retro_task_t *task,
4381 void *task_data, void *user_data, const char *err)
4382 {
4383 char subdir_path[PATH_MAX_LENGTH];
4384 http_transfer_data_t *data = (http_transfer_data_t*)task_data;
4385 file_transfer_t *state = (file_transfer_t*)user_data;
4386
4387 subdir_path[0] = '\0';
4388
4389 if (!data || err)
4390 goto finish;
4391
4392 if (!string_is_empty(data->data))
4393 memcpy(subdir_path, data->data, data->len * sizeof(char));
4394 subdir_path[data->len] = '\0';
4395
4396 finish:
4397 if (!err && !string_ends_with_size(subdir_path,
4398 FILE_PATH_INDEX_DIRS_URL,
4399 strlen(subdir_path),
4400 STRLEN_CONST(FILE_PATH_INDEX_DIRS_URL)
4401 ))
4402 {
4403 char parent_dir[PATH_MAX_LENGTH];
4404
4405 parent_dir[0] = '\0';
4406
4407 fill_pathname_parent_dir(parent_dir,
4408 state->path, sizeof(parent_dir));
4409
4410 /*generic_action_ok_displaylist_push(parent_dir, NULL,
4411 subdir_path, 0, 0, 0, ACTION_OK_DL_CORE_CONTENT_DIRS_SUBDIR_LIST);*/
4412 }
4413
4414 if (user_data)
4415 free(user_data);
4416 }
4417
cb_net_generic(retro_task_t * task,void * task_data,void * user_data,const char * err)4418 static void cb_net_generic(retro_task_t *task,
4419 void *task_data, void *user_data, const char *err)
4420 {
4421 bool refresh = false;
4422 http_transfer_data_t *data = (http_transfer_data_t*)task_data;
4423 file_transfer_t *state = (file_transfer_t*)user_data;
4424 menu_handle_t *menu = menu_driver_get_ptr();
4425
4426 if (!menu)
4427 goto finish;
4428
4429 if (menu->core_buf)
4430 free(menu->core_buf);
4431
4432 menu->core_buf = NULL;
4433 menu->core_len = 0;
4434
4435 if (!data || err || !data->data)
4436 goto finish;
4437
4438 menu->core_buf = (char*)malloc((data->len+1) * sizeof(char));
4439
4440 if (!menu->core_buf)
4441 goto finish;
4442
4443 if (!string_is_empty(data->data))
4444 memcpy(menu->core_buf, data->data, data->len * sizeof(char));
4445 menu->core_buf[data->len] = '\0';
4446 menu->core_len = data->len;
4447
4448 finish:
4449 refresh = true;
4450 menu_entries_ctl(MENU_ENTRIES_CTL_UNSET_REFRESH, &refresh);
4451
4452 if (!err &&
4453 !string_ends_with_size(state->path,
4454 FILE_PATH_INDEX_DIRS_URL,
4455 strlen(state->path),
4456 STRLEN_CONST(FILE_PATH_INDEX_DIRS_URL)
4457 ))
4458 {
4459 char parent_dir[PATH_MAX_LENGTH];
4460 char parent_dir_encoded[PATH_MAX_LENGTH];
4461 file_transfer_t *transf = NULL;
4462
4463 parent_dir[0] = '\0';
4464 parent_dir_encoded[0] = '\0';
4465
4466 fill_pathname_parent_dir(parent_dir,
4467 state->path, sizeof(parent_dir));
4468 strlcat(parent_dir, FILE_PATH_INDEX_DIRS_URL,
4469 sizeof(parent_dir));
4470
4471 transf = (file_transfer_t*)malloc(sizeof(*transf));
4472
4473 transf->enum_idx = MSG_UNKNOWN;
4474 strlcpy(transf->path, parent_dir, sizeof(transf->path));
4475
4476 net_http_urlencode_full(parent_dir_encoded, parent_dir,
4477 sizeof(parent_dir_encoded));
4478 task_push_http_transfer_file(parent_dir_encoded, true,
4479 "index_dirs", cb_net_generic_subdir, transf);
4480 }
4481
4482 if (state)
4483 free(state);
4484 }
4485
generic_action_ok_network(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx,enum msg_hash_enums enum_idx)4486 static int generic_action_ok_network(const char *path,
4487 const char *label, unsigned type, size_t idx, size_t entry_idx,
4488 enum msg_hash_enums enum_idx)
4489 {
4490 char url_path[PATH_MAX_LENGTH];
4491 char url_path_encoded[PATH_MAX_LENGTH];
4492 unsigned type_id2 = 0;
4493 file_transfer_t *transf = NULL;
4494 const char *url_label = NULL;
4495 retro_task_callback_t callback = NULL;
4496 bool refresh = true;
4497 bool suppress_msg = false;
4498 settings_t *settings = config_get_ptr();
4499 const char *network_buildbot_assets_url =
4500 settings->paths.network_buildbot_assets_url;
4501
4502 url_path[0] = '\0';
4503 url_path_encoded[0] = '\0';
4504
4505 switch (enum_idx)
4506 {
4507 case MENU_ENUM_LABEL_CB_CORE_CONTENT_DIRS_LIST:
4508
4509 if (string_is_empty(network_buildbot_assets_url))
4510 return menu_cbs_exit();
4511
4512 fill_pathname_join(url_path,
4513 network_buildbot_assets_url,
4514 "cores/" FILE_PATH_INDEX_DIRS_URL,
4515 sizeof(url_path));
4516 url_label = msg_hash_to_str(enum_idx);
4517 type_id2 = ACTION_OK_DL_CORE_CONTENT_DIRS_LIST;
4518 callback = cb_net_generic;
4519 suppress_msg = true;
4520 break;
4521 case MENU_ENUM_LABEL_CB_CORE_CONTENT_LIST:
4522 fill_pathname_join(url_path, path,
4523 FILE_PATH_INDEX_URL, sizeof(url_path));
4524 url_label = msg_hash_to_str(enum_idx);
4525 type_id2 = ACTION_OK_DL_CORE_CONTENT_LIST;
4526 callback = cb_net_generic;
4527 suppress_msg = true;
4528 break;
4529 case MENU_ENUM_LABEL_CB_THUMBNAILS_UPDATER_LIST:
4530 fill_pathname_join(url_path,
4531 FILE_PATH_CORE_THUMBNAILPACKS_URL,
4532 FILE_PATH_INDEX_URL, sizeof(url_path));
4533 url_label = msg_hash_to_str(enum_idx);
4534 type_id2 = ACTION_OK_DL_THUMBNAILS_UPDATER_LIST;
4535 callback = cb_net_generic;
4536 break;
4537 #ifdef HAVE_LAKKA
4538 case MENU_ENUM_LABEL_CB_LAKKA_LIST:
4539 /* TODO unhardcode this path */
4540 fill_pathname_join(url_path,
4541 FILE_PATH_LAKKA_URL,
4542 lakka_get_project(), sizeof(url_path));
4543 fill_pathname_join(url_path, url_path,
4544 FILE_PATH_INDEX_URL,
4545 sizeof(url_path));
4546 url_label = msg_hash_to_str(enum_idx);
4547 type_id2 = ACTION_OK_DL_LAKKA_LIST;
4548 callback = cb_net_generic;
4549 break;
4550 #endif
4551 default:
4552 break;
4553 }
4554
4555 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
4556
4557 generic_action_ok_command(CMD_EVENT_NETWORK_INIT);
4558
4559 transf = (file_transfer_t*)calloc(1, sizeof(*transf));
4560 strlcpy(transf->path, url_path, sizeof(transf->path));
4561
4562 net_http_urlencode_full(url_path_encoded, url_path, sizeof(url_path_encoded));
4563 task_push_http_transfer_file(url_path_encoded, suppress_msg, url_label, callback, transf);
4564
4565 return generic_action_ok_displaylist_push(path, NULL,
4566 label, type, idx, entry_idx, type_id2);
4567 }
4568
DEFAULT_ACTION_OK_LIST(action_ok_core_content_list,MENU_ENUM_LABEL_CB_CORE_CONTENT_LIST)4569 DEFAULT_ACTION_OK_LIST(action_ok_core_content_list, MENU_ENUM_LABEL_CB_CORE_CONTENT_LIST)
4570 DEFAULT_ACTION_OK_LIST(action_ok_core_content_dirs_list, MENU_ENUM_LABEL_CB_CORE_CONTENT_DIRS_LIST)
4571 DEFAULT_ACTION_OK_LIST(action_ok_thumbnails_updater_list, MENU_ENUM_LABEL_CB_THUMBNAILS_UPDATER_LIST)
4572 DEFAULT_ACTION_OK_LIST(action_ok_lakka_list, MENU_ENUM_LABEL_CB_LAKKA_LIST)
4573
4574 static void cb_generic_dir_download(retro_task_t *task,
4575 void *task_data,
4576 void *user_data, const char *err)
4577 {
4578 file_transfer_t *transf = (file_transfer_t*)user_data;
4579 if (transf)
4580 {
4581 generic_action_ok_network(transf->path, transf->path, 0, 0, 0,
4582 MENU_ENUM_LABEL_CB_CORE_CONTENT_LIST);
4583
4584 free(transf);
4585 }
4586 }
4587
4588 /* expects http_transfer_t*, file_transfer_t* */
cb_generic_download(retro_task_t * task,void * task_data,void * user_data,const char * err)4589 void cb_generic_download(retro_task_t *task,
4590 void *task_data,
4591 void *user_data, const char *err)
4592 {
4593 char output_path[PATH_MAX_LENGTH];
4594 char buf[PATH_MAX_LENGTH];
4595 #if defined(HAVE_COMPRESSION) && defined(HAVE_ZLIB)
4596 bool extract = true;
4597 #endif
4598 const char *dir_path = NULL;
4599 file_transfer_t *transf = (file_transfer_t*)user_data;
4600 settings_t *settings = config_get_ptr();
4601 http_transfer_data_t *data = (http_transfer_data_t*)task_data;
4602
4603 if (!data || !data->data || !transf)
4604 goto finish;
4605
4606 output_path[0] = '\0';
4607
4608 /* we have to determine dir_path at the time of writting or else
4609 * we'd run into races when the user changes the setting during an
4610 * http transfer. */
4611 switch (transf->enum_idx)
4612 {
4613 case MENU_ENUM_LABEL_CB_CORE_THUMBNAILS_DOWNLOAD:
4614 dir_path = settings->paths.directory_thumbnails;
4615 break;
4616 case MENU_ENUM_LABEL_CB_CORE_CONTENT_DOWNLOAD:
4617 dir_path = settings->paths.directory_core_assets;
4618 #if defined(HAVE_COMPRESSION) && defined(HAVE_ZLIB)
4619 extract = settings->bools.network_buildbot_auto_extract_archive;
4620 #endif
4621 break;
4622 case MENU_ENUM_LABEL_CB_UPDATE_CORE_INFO_FILES:
4623 dir_path = settings->paths.path_libretro_info;
4624 break;
4625 case MENU_ENUM_LABEL_CB_UPDATE_ASSETS:
4626 dir_path = settings->paths.directory_assets;
4627 break;
4628 case MENU_ENUM_LABEL_CB_UPDATE_AUTOCONFIG_PROFILES:
4629 dir_path = settings->paths.directory_autoconfig;
4630 break;
4631 case MENU_ENUM_LABEL_CB_UPDATE_DATABASES:
4632 dir_path = settings->paths.path_content_database;
4633 break;
4634 case MENU_ENUM_LABEL_CB_UPDATE_OVERLAYS:
4635 dir_path = settings->paths.directory_overlay;
4636 break;
4637 case MENU_ENUM_LABEL_CB_UPDATE_CHEATS:
4638 dir_path = settings->paths.path_cheat_database;
4639 break;
4640 case MENU_ENUM_LABEL_CB_UPDATE_SHADERS_CG:
4641 case MENU_ENUM_LABEL_CB_UPDATE_SHADERS_GLSL:
4642 case MENU_ENUM_LABEL_CB_UPDATE_SHADERS_SLANG:
4643 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
4644 {
4645 static char shaderdir[PATH_MAX_LENGTH] = {0};
4646 const char *dirname = NULL;
4647 const char *dir_video_shader = settings->paths.directory_video_shader;
4648
4649 switch (transf->enum_idx)
4650 {
4651 case MENU_ENUM_LABEL_CB_UPDATE_SHADERS_CG:
4652 dirname = "shaders_cg";
4653 break;
4654 case MENU_ENUM_LABEL_CB_UPDATE_SHADERS_GLSL:
4655 dirname = "shaders_glsl";
4656 break;
4657 case MENU_ENUM_LABEL_CB_UPDATE_SHADERS_SLANG:
4658 dirname = "shaders_slang";
4659 break;
4660 default:
4661 break;
4662 }
4663
4664 fill_pathname_join(shaderdir, dir_video_shader,
4665 dirname, sizeof(shaderdir));
4666
4667 if (!path_is_directory(shaderdir) && !path_mkdir(shaderdir))
4668 goto finish;
4669
4670 dir_path = shaderdir;
4671 }
4672 #endif
4673 break;
4674 case MENU_ENUM_LABEL_CB_LAKKA_DOWNLOAD:
4675 dir_path = LAKKA_UPDATE_DIR;
4676 break;
4677 case MENU_ENUM_LABEL_CB_DISCORD_AVATAR:
4678 fill_pathname_application_special(buf, sizeof(buf),
4679 APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_DISCORD_AVATARS);
4680 dir_path = buf;
4681 break;
4682 default:
4683 RARCH_WARN("Unknown transfer type '%s' bailing out.\n",
4684 msg_hash_to_str(transf->enum_idx));
4685 break;
4686 }
4687
4688 if (!string_is_empty(dir_path))
4689 fill_pathname_join(output_path, dir_path,
4690 transf->path, sizeof(output_path));
4691
4692 /* Make sure the directory exists
4693 * This function is horrible. It mutates the original path
4694 * so after operating we'll have to set the path to the intended
4695 * location again...
4696 */
4697 path_basedir_wrapper(output_path);
4698
4699 if (!path_mkdir(output_path))
4700 {
4701 err = msg_hash_to_str(MSG_FAILED_TO_CREATE_THE_DIRECTORY);
4702 goto finish;
4703 }
4704
4705 if (!string_is_empty(dir_path))
4706 fill_pathname_join(output_path, dir_path,
4707 transf->path, sizeof(output_path));
4708
4709 #ifdef HAVE_COMPRESSION
4710 if (path_is_compressed_file(output_path))
4711 {
4712 if (task_check_decompress(output_path))
4713 {
4714 err = msg_hash_to_str(MSG_DECOMPRESSION_ALREADY_IN_PROGRESS);
4715 goto finish;
4716 }
4717 }
4718 #endif
4719
4720 if (!filestream_write_file(output_path, data->data, data->len))
4721 {
4722 err = "Write failed.";
4723 goto finish;
4724 }
4725
4726 #if defined(HAVE_COMPRESSION) && defined(HAVE_ZLIB)
4727 if (!extract)
4728 goto finish;
4729
4730 if (path_is_compressed_file(output_path))
4731 {
4732 retro_task_t *decompress_task = NULL;
4733 void *frontend_userdata = task->frontend_userdata;
4734 task->frontend_userdata = NULL;
4735
4736 decompress_task = (retro_task_t*)task_push_decompress(
4737 output_path, dir_path,
4738 NULL, NULL, NULL,
4739 cb_decompressed,
4740 (void*)(uintptr_t)transf->enum_idx,
4741 frontend_userdata, false);
4742
4743 if (!decompress_task)
4744 {
4745 err = msg_hash_to_str(MSG_DECOMPRESSION_FAILED);
4746 goto finish;
4747 }
4748 }
4749 #endif
4750
4751 finish:
4752 if (err)
4753 {
4754 RARCH_ERR("Download of '%s' failed: %s\n",
4755 (transf ? transf->path: msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN)), err);
4756 }
4757 #ifdef HAVE_DISCORD
4758 else if (transf && transf->enum_idx == MENU_ENUM_LABEL_CB_DISCORD_AVATAR)
4759 discord_avatar_set_ready(true);
4760 #endif
4761
4762 if (transf)
4763 free(transf);
4764 }
4765 #endif
4766
action_ok_download_generic(const char * path,const char * label,const char * menu_label,unsigned type,size_t idx,size_t entry_idx,enum msg_hash_enums enum_idx)4767 static int action_ok_download_generic(const char *path,
4768 const char *label, const char *menu_label,
4769 unsigned type, size_t idx, size_t entry_idx,
4770 enum msg_hash_enums enum_idx)
4771 {
4772 #ifdef HAVE_NETWORKING
4773 char s[PATH_MAX_LENGTH];
4774 char s2[PATH_MAX_LENGTH];
4775 char s3[PATH_MAX_LENGTH];
4776 file_transfer_t *transf = NULL;
4777 bool suppress_msg = false;
4778 retro_task_callback_t cb = cb_generic_download;
4779 settings_t *settings = config_get_ptr();
4780 const char *network_buildbot_assets_url =
4781 settings->paths.network_buildbot_assets_url;
4782 const char *network_buildbot_url = settings->paths.network_buildbot_url;
4783
4784 s[0] = s2[0] = s3[0] = '\0';
4785
4786 fill_pathname_join(s,
4787 network_buildbot_assets_url,
4788 "frontend", sizeof(s));
4789
4790 switch (enum_idx)
4791 {
4792 case MENU_ENUM_LABEL_CB_DOWNLOAD_URL:
4793 suppress_msg = true;
4794 fill_pathname_join(s, label,
4795 path, sizeof(s));
4796 path = s;
4797 cb = cb_generic_dir_download;
4798 break;
4799 case MENU_ENUM_LABEL_CB_CORE_CONTENT_DOWNLOAD:
4800 {
4801 struct string_list str_list = {0};
4802
4803 string_list_initialize(&str_list);
4804 if (string_split_noalloc(&str_list, menu_label, ";"))
4805 strlcpy(s, str_list.elems[0].data, sizeof(s));
4806 string_list_deinitialize(&str_list);
4807 }
4808 break;
4809 case MENU_ENUM_LABEL_CB_LAKKA_DOWNLOAD:
4810 #ifdef HAVE_LAKKA
4811 /* TODO unhardcode this path*/
4812 fill_pathname_join(s, FILE_PATH_LAKKA_URL,
4813 lakka_get_project(), sizeof(s));
4814 #endif
4815 break;
4816 case MENU_ENUM_LABEL_CB_UPDATE_ASSETS:
4817 path = "assets.zip";
4818 break;
4819 case MENU_ENUM_LABEL_CB_UPDATE_AUTOCONFIG_PROFILES:
4820 path = "autoconfig.zip";
4821 break;
4822 case MENU_ENUM_LABEL_CB_UPDATE_CORE_INFO_FILES:
4823 path = "info.zip";
4824 break;
4825 case MENU_ENUM_LABEL_CB_UPDATE_CHEATS:
4826 path = "cheats.zip";
4827 break;
4828 case MENU_ENUM_LABEL_CB_UPDATE_OVERLAYS:
4829 path = "overlays.zip";
4830 break;
4831 case MENU_ENUM_LABEL_CB_UPDATE_DATABASES:
4832 path = "database-rdb.zip";
4833 break;
4834 case MENU_ENUM_LABEL_CB_UPDATE_SHADERS_GLSL:
4835 path = "shaders_glsl.zip";
4836 break;
4837 case MENU_ENUM_LABEL_CB_UPDATE_SHADERS_SLANG:
4838 path = "shaders_slang.zip";
4839 break;
4840 case MENU_ENUM_LABEL_CB_UPDATE_SHADERS_CG:
4841 path = "shaders_cg.zip";
4842 break;
4843 case MENU_ENUM_LABEL_CB_CORE_THUMBNAILS_DOWNLOAD:
4844 strcpy_literal(s, "http://thumbnailpacks.libretro.com");
4845 break;
4846 default:
4847 strlcpy(s, network_buildbot_url, sizeof(s));
4848 break;
4849 }
4850
4851 fill_pathname_join(s2, s, path, sizeof(s2));
4852
4853 transf = (file_transfer_t*)calloc(1, sizeof(*transf));
4854 transf->enum_idx = enum_idx;
4855 strlcpy(transf->path, path, sizeof(transf->path));
4856
4857 if (string_is_equal(path, s))
4858 net_http_urlencode_full(s3, s, sizeof(s3));
4859 else
4860 net_http_urlencode_full(s3, s2, sizeof(s3));
4861
4862 task_push_http_transfer_file(s3, suppress_msg,
4863 msg_hash_to_str(enum_idx), cb, transf);
4864 #endif
4865 return 0;
4866 }
4867
action_ok_core_content_download(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4868 static int action_ok_core_content_download(const char *path,
4869 const char *label, unsigned type, size_t idx, size_t entry_idx)
4870 {
4871 const char *menu_path = NULL;
4872 const char *menu_label = NULL;
4873 enum msg_hash_enums enum_idx = MSG_UNKNOWN;
4874
4875 menu_entries_get_last_stack(&menu_path, &menu_label,
4876 NULL, &enum_idx, NULL);
4877
4878 return action_ok_download_generic(path, label,
4879 menu_path, type, idx, entry_idx,
4880 MENU_ENUM_LABEL_CB_CORE_CONTENT_DOWNLOAD);
4881 }
4882
action_ok_core_updater_download(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4883 static int action_ok_core_updater_download(const char *path,
4884 const char *label, unsigned type, size_t idx, size_t entry_idx)
4885 {
4886 #ifdef HAVE_NETWORKING
4887 core_updater_list_t *core_list = core_updater_list_get_cached();
4888 settings_t *settings = config_get_ptr();
4889 bool auto_backup = settings->bools.core_updater_auto_backup;
4890 unsigned auto_backup_history_size = settings->uints.core_updater_auto_backup_history_size;
4891 const char *path_dir_libretro = settings->paths.directory_libretro;
4892 const char *path_dir_core_assets = settings->paths.directory_core_assets;
4893
4894 if (!core_list)
4895 return menu_cbs_exit();
4896
4897 #if defined(ANDROID)
4898 /* Play Store builds install cores via
4899 * the play feature delivery interface */
4900 if (play_feature_delivery_enabled())
4901 task_push_play_feature_delivery_core_install(
4902 core_list, path, false);
4903 else
4904 #endif
4905 task_push_core_updater_download(
4906 core_list, path, 0, false,
4907 auto_backup, (size_t)auto_backup_history_size,
4908 path_dir_libretro, path_dir_core_assets);
4909
4910 #endif
4911 return 0;
4912 }
4913
4914 #ifdef HAVE_NETWORKING
action_ok_update_installed_cores(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4915 static int action_ok_update_installed_cores(const char *path,
4916 const char *label, unsigned type, size_t idx, size_t entry_idx)
4917 {
4918 settings_t *settings = config_get_ptr();
4919 bool auto_backup = settings->bools.core_updater_auto_backup;
4920 unsigned auto_backup_history_size = settings->uints.core_updater_auto_backup_history_size;
4921 const char *path_dir_libretro = settings->paths.directory_libretro;
4922 const char *path_dir_core_assets = settings->paths.directory_core_assets;
4923
4924 /* Ensure networking is initialised */
4925 generic_action_ok_command(CMD_EVENT_NETWORK_INIT);
4926
4927 /* Push update task */
4928 task_push_update_installed_cores(
4929 auto_backup, auto_backup_history_size,
4930 path_dir_libretro, path_dir_core_assets);
4931
4932 return 0;
4933 }
4934
4935 #if defined(ANDROID)
action_ok_switch_installed_cores_pfd(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4936 static int action_ok_switch_installed_cores_pfd(const char *path,
4937 const char *label, unsigned type, size_t idx, size_t entry_idx)
4938 {
4939 settings_t *settings = config_get_ptr();
4940 const char *path_dir_libretro = settings->paths.directory_libretro;
4941 const char *path_libretro_info = settings->paths.path_libretro_info;
4942
4943 /* Ensure networking is initialised */
4944 generic_action_ok_command(CMD_EVENT_NETWORK_INIT);
4945
4946 /* Push core switch/update task */
4947 task_push_play_feature_delivery_switch_installed_cores(
4948 path_dir_libretro, path_libretro_info);
4949
4950 return 0;
4951 }
4952 #endif
4953 #endif
4954
action_ok_sideload_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)4955 static int action_ok_sideload_core(const char *path,
4956 const char *label, unsigned type, size_t idx, size_t entry_idx)
4957 {
4958 char backup_path[PATH_MAX_LENGTH];
4959 const char *menu_path = NULL;
4960 const char *core_file = path;
4961 bool core_loaded = false;
4962 menu_handle_t *menu = menu_driver_get_ptr();
4963 settings_t *settings = config_get_ptr();
4964 const char *dir_libretro = settings->paths.directory_libretro;
4965
4966 backup_path[0] = '\0';
4967
4968 if (string_is_empty(core_file) || !menu)
4969 return menu_cbs_exit();
4970
4971 /* Get path of source (core 'backup') file */
4972 menu_entries_get_last_stack(
4973 &menu_path, NULL, NULL, NULL, NULL);
4974
4975 if (!string_is_empty(menu_path))
4976 fill_pathname_join(
4977 backup_path, menu_path, core_file, sizeof(backup_path));
4978 else
4979 strlcpy(backup_path, core_file, sizeof(backup_path));
4980
4981 /* Push core 'restore' task */
4982 task_push_core_restore(backup_path, dir_libretro, &core_loaded);
4983
4984 /* Flush stack
4985 * > Since the 'sideload core' option is present
4986 * in several locations, can't flush to a predefined
4987 * level - just go to the top */
4988 menu_entries_flush_stack(NULL, 0);
4989
4990 return 0;
4991 }
4992
DEFAULT_ACTION_OK_DOWNLOAD(action_ok_core_content_thumbnails,MENU_ENUM_LABEL_CB_CORE_THUMBNAILS_DOWNLOAD)4993 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_core_content_thumbnails, MENU_ENUM_LABEL_CB_CORE_THUMBNAILS_DOWNLOAD)
4994 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_thumbnails_updater_download, MENU_ENUM_LABEL_CB_THUMBNAILS_UPDATER_DOWNLOAD)
4995 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_download_url, MENU_ENUM_LABEL_CB_DOWNLOAD_URL)
4996 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_lakka_download, MENU_ENUM_LABEL_CB_LAKKA_DOWNLOAD)
4997 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_update_assets, MENU_ENUM_LABEL_CB_UPDATE_ASSETS)
4998 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_update_core_info_files, MENU_ENUM_LABEL_CB_UPDATE_CORE_INFO_FILES)
4999 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_update_overlays, MENU_ENUM_LABEL_CB_UPDATE_OVERLAYS)
5000 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
5001 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_update_shaders_cg, MENU_ENUM_LABEL_CB_UPDATE_SHADERS_CG)
5002 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_update_shaders_glsl, MENU_ENUM_LABEL_CB_UPDATE_SHADERS_GLSL)
5003 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_update_shaders_slang, MENU_ENUM_LABEL_CB_UPDATE_SHADERS_SLANG)
5004 #endif
5005 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_update_databases, MENU_ENUM_LABEL_CB_UPDATE_DATABASES)
5006 #ifdef HAVE_CHEATS
5007 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_update_cheats, MENU_ENUM_LABEL_CB_UPDATE_CHEATS)
5008 #endif
5009 DEFAULT_ACTION_OK_DOWNLOAD(action_ok_update_autoconfig_profiles, MENU_ENUM_LABEL_CB_UPDATE_AUTOCONFIG_PROFILES)
5010
5011 static int action_ok_game_specific_core_options_create(const char *path,
5012 const char *label, unsigned type, size_t idx, size_t entry_idx)
5013 {
5014 bool refresh = false;
5015
5016 core_options_create_override(true);
5017
5018 /* Refresh menu */
5019 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
5020 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
5021
5022 return 0;
5023 }
5024
action_ok_folder_specific_core_options_create(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5025 static int action_ok_folder_specific_core_options_create(const char *path,
5026 const char *label, unsigned type, size_t idx, size_t entry_idx)
5027 {
5028 bool refresh = false;
5029
5030 core_options_create_override(false);
5031
5032 /* Refresh menu */
5033 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
5034 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
5035
5036 return 0;
5037 }
5038
action_ok_game_specific_core_options_remove(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5039 static int action_ok_game_specific_core_options_remove(const char *path,
5040 const char *label, unsigned type, size_t idx, size_t entry_idx)
5041 {
5042 bool refresh = false;
5043
5044 core_options_remove_override(true);
5045
5046 /* Refresh menu */
5047 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
5048 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
5049
5050 return 0;
5051 }
5052
action_ok_folder_specific_core_options_remove(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5053 static int action_ok_folder_specific_core_options_remove(const char *path,
5054 const char *label, unsigned type, size_t idx, size_t entry_idx)
5055 {
5056 bool refresh = false;
5057
5058 core_options_remove_override(false);
5059
5060 /* Refresh menu */
5061 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
5062 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
5063
5064 return 0;
5065 }
5066
action_ok_core_options_reset(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5067 static int action_ok_core_options_reset(const char *path,
5068 const char *label, unsigned type, size_t idx, size_t entry_idx)
5069 {
5070 core_options_reset();
5071 return 0;
5072 }
5073
action_ok_close_content(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5074 int action_ok_close_content(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx)
5075 {
5076 int ret;
5077
5078 /* Reset navigation pointer
5079 * > If we are returning to the quick menu, want
5080 * the active entry to be 'Run' (first item in
5081 * menu list) */
5082 menu_navigation_set_selection(0);
5083
5084 /* Unload core */
5085 ret = generic_action_ok_command(CMD_EVENT_UNLOAD_CORE);
5086
5087 /* If close content was selected via 'Main Menu > Quick Menu',
5088 * have to flush the menu stack back to 'Main Menu'
5089 * (otherwise users will be presented with an empty
5090 * 'No items' quick menu, requiring needless backwards
5091 * navigation) */
5092 if (type == MENU_SETTING_ACTION_CLOSE)
5093 {
5094 menu_entries_flush_stack(msg_hash_to_str(MENU_ENUM_LABEL_MAIN_MENU), 0);
5095 /* An annoyance - some menu drivers (Ozone...) call
5096 * RARCH_MENU_CTL_SET_PREVENT_POPULATE in awkward
5097 * places, which can cause breakage here when flushing
5098 * the menu stack. We therefore have to force a
5099 * RARCH_MENU_CTL_UNSET_PREVENT_POPULATE */
5100 menu_driver_ctl(RARCH_MENU_CTL_UNSET_PREVENT_POPULATE, NULL);
5101 }
5102
5103 return ret;
5104 }
5105
DEFAULT_ACTION_OK_CMD_FUNC(action_ok_cheat_apply_changes,CMD_EVENT_CHEATS_APPLY)5106 DEFAULT_ACTION_OK_CMD_FUNC(action_ok_cheat_apply_changes, CMD_EVENT_CHEATS_APPLY)
5107 DEFAULT_ACTION_OK_CMD_FUNC(action_ok_quit, CMD_EVENT_QUIT)
5108 DEFAULT_ACTION_OK_CMD_FUNC(action_ok_save_new_config, CMD_EVENT_MENU_SAVE_CONFIG)
5109 DEFAULT_ACTION_OK_CMD_FUNC(action_ok_resume_content, CMD_EVENT_RESUME)
5110 DEFAULT_ACTION_OK_CMD_FUNC(action_ok_restart_content, CMD_EVENT_RESET)
5111 DEFAULT_ACTION_OK_CMD_FUNC(action_ok_screenshot, CMD_EVENT_TAKE_SCREENSHOT)
5112 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
5113 DEFAULT_ACTION_OK_CMD_FUNC(action_ok_shader_apply_changes, CMD_EVENT_SHADERS_APPLY_CHANGES)
5114 #endif
5115 DEFAULT_ACTION_OK_CMD_FUNC(action_ok_show_wimp, CMD_EVENT_UI_COMPANION_TOGGLE)
5116
5117 static int action_ok_set_core_association(const char *path,
5118 const char *label, unsigned type, size_t idx, size_t entry_idx)
5119 {
5120 menu_handle_t *menu = menu_driver_get_ptr();
5121
5122 if (!menu)
5123 return menu_cbs_exit();
5124
5125 /* TODO/FIXME - menu->rpl_entry_selection_ptr - find
5126 * a way so that we can remove this temporary state */
5127 return generic_action_ok_displaylist_push(path, NULL,
5128 NULL, 0, menu->rpl_entry_selection_ptr, entry_idx,
5129 ACTION_OK_DL_DEFERRED_CORE_LIST_SET);
5130 }
5131
action_ok_reset_core_association(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5132 static int action_ok_reset_core_association(const char *path,
5133 const char *label, unsigned type, size_t idx, size_t entry_idx)
5134 {
5135 menu_handle_t *menu = menu_driver_get_ptr();
5136 size_t playlist_index;
5137
5138 if (!menu)
5139 return menu_cbs_exit();
5140
5141 playlist_index = (size_t)menu->rpl_entry_selection_ptr;
5142
5143 if (!command_event(CMD_EVENT_RESET_CORE_ASSOCIATION,
5144 (void *)&playlist_index))
5145 return menu_cbs_exit();
5146 return 0;
5147 }
5148
5149 /* This function is called when selecting 'add to favorites'
5150 * while viewing the quick menu (i.e. content is running) */
action_ok_add_to_favorites(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5151 static int action_ok_add_to_favorites(const char *path,
5152 const char *label, unsigned type, size_t idx, size_t entry_idx)
5153 {
5154 const char *content_path = path_get(RARCH_PATH_CONTENT);
5155 int ret = 0;
5156
5157 /* Error checking
5158 * > If content path is empty, cannot do anything... */
5159 if (!string_is_empty(content_path))
5160 {
5161 global_t *global = global_get_ptr();
5162 struct retro_system_info *system = runloop_get_libretro_system_info();
5163 struct string_list *str_list = NULL;
5164 const char *crc32 = NULL;
5165 const char *db_name = NULL;
5166
5167 union string_list_elem_attr attr;
5168 char content_label[PATH_MAX_LENGTH];
5169 char core_path[PATH_MAX_LENGTH];
5170 char core_name[PATH_MAX_LENGTH];
5171
5172 content_label[0] = '\0';
5173 core_path[0] = '\0';
5174 core_name[0] = '\0';
5175
5176 /* Create string list container for playlist parameters */
5177 attr.i = 0;
5178 str_list = string_list_new();
5179 if (!str_list)
5180 return 0;
5181
5182 /* Determine playlist parameters */
5183
5184 /* > content_label */
5185 if (global)
5186 if (!string_is_empty(global->name.label))
5187 strlcpy(content_label, global->name.label, sizeof(content_label));
5188
5189 /* Label is empty - use file name instead */
5190 if (string_is_empty(content_label))
5191 fill_short_pathname_representation(content_label,
5192 content_path, sizeof(content_label));
5193
5194 /* > core_path + core_name */
5195 if (system)
5196 {
5197 if (!string_is_empty(path_get(RARCH_PATH_CORE)))
5198 {
5199 core_info_t *core_info = NULL;
5200
5201 /* >> core_path */
5202 strlcpy(core_path, path_get(RARCH_PATH_CORE), sizeof(core_path));
5203
5204 /* >> core_name
5205 * (always use display name, if available) */
5206 if (core_info_find(core_path, &core_info))
5207 if (!string_is_empty(core_info->display_name))
5208 strlcpy(core_name, core_info->display_name,
5209 sizeof(core_name));
5210 }
5211
5212 /* >> core_name (continued) */
5213 if ( string_is_empty(core_name) &&
5214 !string_is_empty(system->library_name))
5215 strlcpy(core_name, system->library_name, sizeof(core_name));
5216 }
5217
5218 if (string_is_empty(core_path) || string_is_empty(core_name))
5219 {
5220 strcpy_literal(core_path, "DETECT");
5221 strcpy_literal(core_name, "DETECT");
5222 }
5223
5224 /* > crc32 + db_name */
5225 {
5226 menu_handle_t *menu = menu_driver_get_ptr();
5227 if (menu)
5228 {
5229 playlist_t *playlist_curr = playlist_get_cached();
5230
5231 if (playlist_index_is_valid(playlist_curr,
5232 menu->rpl_entry_selection_ptr,
5233 content_path, core_path))
5234 {
5235 playlist_get_crc32(playlist_curr,
5236 menu->rpl_entry_selection_ptr, &crc32);
5237 playlist_get_db_name(playlist_curr,
5238 menu->rpl_entry_selection_ptr, &db_name);
5239 }
5240 }
5241 }
5242
5243 /* Copy playlist parameters into string list
5244 * [0]: content_path
5245 * [1]: content_label
5246 * [2]: core_path
5247 * [3]: core_name
5248 * [4]: crc32
5249 * [5]: db_name */
5250 string_list_append(str_list, content_path, attr);
5251 string_list_append(str_list, content_label, attr);
5252 string_list_append(str_list, core_path, attr);
5253 string_list_append(str_list, core_name, attr);
5254 string_list_append(str_list, !string_is_empty(crc32)
5255 ? crc32 : "", attr);
5256 string_list_append(str_list, !string_is_empty(db_name)
5257 ? db_name : "", attr);
5258
5259 /* Trigger 'ADD_TO_FAVORITES' event */
5260 if (!command_event(CMD_EVENT_ADD_TO_FAVORITES, (void*)str_list))
5261 ret = menu_cbs_exit();
5262
5263 /* Clean up */
5264 string_list_free(str_list);
5265 str_list = NULL;
5266 }
5267
5268 return ret;
5269 }
5270
5271 /* This function is called when selecting 'add to favorites'
5272 * while viewing a playlist entry */
action_ok_add_to_favorites_playlist(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5273 static int action_ok_add_to_favorites_playlist(const char *path,
5274 const char *label, unsigned type, size_t idx, size_t entry_idx)
5275 {
5276 playlist_t *playlist_curr = playlist_get_cached();
5277 const struct playlist_entry *entry = NULL;
5278 menu_handle_t *menu = menu_driver_get_ptr();
5279 int ret = 0;
5280
5281 if (!playlist_curr)
5282 return 0;
5283 if (!menu)
5284 return menu_cbs_exit();
5285
5286 /* Read current playlist parameters */
5287 playlist_get_index(playlist_curr, menu->rpl_entry_selection_ptr, &entry);
5288
5289 /* Error checking
5290 * > If content path is empty, cannot do anything... */
5291 if (!string_is_empty(entry->path))
5292 {
5293 union string_list_elem_attr attr;
5294 char core_display_name[PATH_MAX_LENGTH];
5295 struct string_list
5296 *str_list = NULL;
5297
5298 core_display_name[0] = '\0';
5299
5300 /* Create string list container for playlist parameters */
5301 attr.i = 0;
5302 str_list = string_list_new();
5303 if (!str_list)
5304 return 0;
5305
5306 /* Copy playlist parameters into string list
5307 * [0]: content_path
5308 * [1]: content_label
5309 * [2]: core_path
5310 * [3]: core_name
5311 * [4]: crc32
5312 * [5]: db_name */
5313
5314 /* > content_path */
5315 string_list_append(str_list, entry->path, attr);
5316
5317 /* > content_label */
5318 if (!string_is_empty(entry->label))
5319 string_list_append(str_list, entry->label, attr);
5320 else
5321 {
5322 /* Label is empty - use file name instead */
5323 char fallback_content_label[PATH_MAX_LENGTH];
5324 fallback_content_label[0] = '\0';
5325 fill_short_pathname_representation(fallback_content_label, entry->path, sizeof(fallback_content_label));
5326 string_list_append(str_list, fallback_content_label, attr);
5327 }
5328
5329 /* > core_path + core_name */
5330 if (!string_is_empty(entry->core_path) && !string_is_empty(entry->core_name))
5331 {
5332 core_info_t *core_info = NULL;
5333
5334 /* >> core_path */
5335 string_list_append(str_list, entry->core_path, attr);
5336
5337 /* >> core_name
5338 * (always use display name, if available) */
5339 if (core_info_find(entry->core_path, &core_info))
5340 if (!string_is_empty(core_info->display_name))
5341 strlcpy(core_display_name, core_info->display_name, sizeof(core_display_name));
5342
5343 if (!string_is_empty(core_display_name))
5344 string_list_append(str_list, core_display_name, attr);
5345 else
5346 string_list_append(str_list, entry->core_name, attr);
5347 }
5348 else
5349 {
5350 string_list_append(str_list, "DETECT", attr);
5351 string_list_append(str_list, "DETECT", attr);
5352 }
5353
5354 /* crc32 */
5355 string_list_append(str_list, !string_is_empty(entry->crc32) ? entry->crc32 : "", attr);
5356
5357 /* db_name */
5358 string_list_append(str_list, !string_is_empty(entry->db_name) ? entry->db_name : "", attr);
5359
5360 /* Trigger 'ADD_TO_FAVORITES' event */
5361 if (!command_event(CMD_EVENT_ADD_TO_FAVORITES, (void*)str_list))
5362 ret = menu_cbs_exit();
5363
5364 /* Clean up */
5365 string_list_free(str_list);
5366 str_list = NULL;
5367 }
5368
5369 return ret;
5370 }
5371
action_ok_delete_entry(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5372 static int action_ok_delete_entry(const char *path,
5373 const char *label, unsigned type, size_t idx, size_t entry_idx)
5374 {
5375 size_t new_selection_ptr;
5376 char *conf_path = NULL;
5377 char *def_conf_path = NULL;
5378 char *def_conf_music_path = NULL;
5379 #if defined(HAVE_FFMPEG) || defined(HAVE_MPV)
5380 char *def_conf_video_path = NULL;
5381 #endif
5382 #ifdef HAVE_IMAGEVIEWER
5383 char *def_conf_img_path = NULL;
5384 #endif
5385 char *def_conf_fav_path = NULL;
5386 playlist_t *playlist = playlist_get_cached();
5387 menu_handle_t *menu = menu_driver_get_ptr();
5388
5389 if (!menu)
5390 return menu_cbs_exit();
5391
5392 conf_path = playlist_get_conf_path(playlist);
5393 def_conf_path = playlist_get_conf_path(g_defaults.content_history);
5394 def_conf_music_path = playlist_get_conf_path(g_defaults.music_history);
5395 #if defined(HAVE_FFMPEG) || defined(HAVE_MPV)
5396 def_conf_video_path = playlist_get_conf_path(g_defaults.video_history);
5397 #endif
5398 #ifdef HAVE_IMAGEVIEWER
5399 def_conf_img_path = playlist_get_conf_path(g_defaults.image_history);
5400 #endif
5401 def_conf_fav_path = playlist_get_conf_path(g_defaults.content_favorites);
5402
5403 if (string_is_equal(conf_path, def_conf_path))
5404 playlist = g_defaults.content_history;
5405 else if (string_is_equal(conf_path, def_conf_music_path))
5406 playlist = g_defaults.music_history;
5407 #if defined(HAVE_FFMPEG) || defined(HAVE_MPV)
5408 else if (string_is_equal(conf_path, def_conf_video_path))
5409 playlist = g_defaults.video_history;
5410 #endif
5411 #ifdef HAVE_IMAGEVIEWER
5412 else if (string_is_equal(conf_path, def_conf_img_path))
5413 playlist = g_defaults.image_history;
5414 #endif
5415 else if (string_is_equal(conf_path, def_conf_fav_path))
5416 playlist = g_defaults.content_favorites;
5417
5418 if (playlist)
5419 {
5420 playlist_delete_index(playlist, menu->rpl_entry_selection_ptr);
5421 playlist_write_file(playlist);
5422 }
5423
5424 new_selection_ptr = menu_navigation_get_selection();
5425 menu_entries_pop_stack(&new_selection_ptr, 0, 1);
5426 menu_navigation_set_selection(new_selection_ptr);
5427
5428 return 0;
5429 }
5430
action_ok_rdb_entry_submenu(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5431 static int action_ok_rdb_entry_submenu(const char *path,
5432 const char *label, unsigned type, size_t idx, size_t entry_idx)
5433 {
5434 union string_list_elem_attr attr;
5435 char new_label[PATH_MAX_LENGTH];
5436 char new_path[PATH_MAX_LENGTH];
5437 int ret = -1;
5438 char *rdb = NULL;
5439 int len = 0;
5440 struct string_list str_list = {0};
5441 struct string_list str_list2 = {0};
5442
5443 if (!label)
5444 return menu_cbs_exit();
5445
5446 new_label[0] = new_path[0] = '\0';
5447
5448 string_list_initialize(&str_list);
5449 if (!string_split_noalloc(&str_list, label, "|"))
5450 goto end;
5451
5452 string_list_initialize(&str_list2);
5453
5454 /* element 0 : label
5455 * element 1 : value
5456 * element 2 : database path
5457 */
5458
5459 attr.i = 0;
5460
5461 len += strlen(str_list.elems[1].data) + 1;
5462 string_list_append(&str_list2, str_list.elems[1].data, attr);
5463
5464 len += strlen(str_list.elems[2].data) + 1;
5465 string_list_append(&str_list2, str_list.elems[2].data, attr);
5466
5467 rdb = (char*)calloc(len, sizeof(char));
5468
5469 if (!rdb)
5470 goto end;
5471
5472 string_list_join_concat(rdb, len, &str_list2, "|");
5473 strlcpy(new_path, rdb, sizeof(new_path));
5474
5475 fill_pathname_join_delim(new_label,
5476 msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CURSOR_MANAGER_LIST),
5477 str_list.elems[0].data, '_',
5478 sizeof(new_label));
5479
5480 ret = generic_action_ok_displaylist_push(new_path, NULL,
5481 new_label, type, idx, entry_idx,
5482 ACTION_OK_DL_RDB_ENTRY_SUBMENU);
5483
5484 end:
5485 if (rdb)
5486 free(rdb);
5487 string_list_deinitialize(&str_list);
5488 string_list_deinitialize(&str_list2);
5489
5490 return ret;
5491 }
5492
DEFAULT_ACTION_OK_FUNC(action_ok_browse_url_start,ACTION_OK_DL_BROWSE_URL_START)5493 DEFAULT_ACTION_OK_FUNC(action_ok_browse_url_start, ACTION_OK_DL_BROWSE_URL_START)
5494 DEFAULT_ACTION_OK_FUNC(action_ok_goto_favorites, ACTION_OK_DL_FAVORITES_LIST)
5495 DEFAULT_ACTION_OK_FUNC(action_ok_goto_images, ACTION_OK_DL_IMAGES_LIST)
5496 DEFAULT_ACTION_OK_FUNC(action_ok_cdrom_info_list, ACTION_OK_DL_CDROM_INFO_DETAIL_LIST)
5497 DEFAULT_ACTION_OK_FUNC(action_ok_goto_video, ACTION_OK_DL_VIDEO_LIST)
5498 DEFAULT_ACTION_OK_FUNC(action_ok_goto_music, ACTION_OK_DL_MUSIC_LIST)
5499 DEFAULT_ACTION_OK_FUNC(action_ok_goto_explore, ACTION_OK_DL_EXPLORE_LIST)
5500 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
5501 DEFAULT_ACTION_OK_FUNC(action_ok_shader_preset_save, ACTION_OK_DL_SHADER_PRESET_SAVE)
5502 DEFAULT_ACTION_OK_FUNC(action_ok_shader_preset_remove, ACTION_OK_DL_SHADER_PRESET_REMOVE)
5503 DEFAULT_ACTION_OK_FUNC(action_ok_shader_parameters, ACTION_OK_DL_SHADER_PARAMETERS)
5504 #endif
5505 DEFAULT_ACTION_OK_FUNC(action_ok_parent_directory_push, ACTION_OK_DL_PARENT_DIRECTORY_PUSH)
5506 DEFAULT_ACTION_OK_FUNC(action_ok_directory_push, ACTION_OK_DL_DIRECTORY_PUSH)
5507 DEFAULT_ACTION_OK_FUNC(action_ok_configurations_list, ACTION_OK_DL_CONFIGURATIONS_LIST)
5508 DEFAULT_ACTION_OK_FUNC(action_ok_saving_list, ACTION_OK_DL_SAVING_SETTINGS_LIST)
5509 DEFAULT_ACTION_OK_FUNC(action_ok_network_list, ACTION_OK_DL_NETWORK_SETTINGS_LIST)
5510 DEFAULT_ACTION_OK_FUNC(action_ok_network_hosting_list, ACTION_OK_DL_NETWORK_HOSTING_SETTINGS_LIST)
5511 DEFAULT_ACTION_OK_FUNC(action_ok_subsystem_list, ACTION_OK_DL_SUBSYSTEM_SETTINGS_LIST)
5512 DEFAULT_ACTION_OK_FUNC(action_ok_database_manager_list, ACTION_OK_DL_DATABASE_MANAGER_LIST)
5513 DEFAULT_ACTION_OK_FUNC(action_ok_bluetooth_list, ACTION_OK_DL_BLUETOOTH_SETTINGS_LIST)
5514 #ifdef HAVE_NETWORKING
5515 DEFAULT_ACTION_OK_FUNC(action_ok_wifi_list, ACTION_OK_DL_WIFI_SETTINGS_LIST)
5516 DEFAULT_ACTION_OK_FUNC(action_ok_wifi_networks_list, ACTION_OK_DL_WIFI_NETWORKS_LIST)
5517 #endif
5518 DEFAULT_ACTION_OK_FUNC(action_ok_cursor_manager_list, ACTION_OK_DL_CURSOR_MANAGER_LIST)
5519 DEFAULT_ACTION_OK_FUNC(action_ok_compressed_archive_push, ACTION_OK_DL_COMPRESSED_ARCHIVE_PUSH)
5520 DEFAULT_ACTION_OK_FUNC(action_ok_compressed_archive_push_detect_core, ACTION_OK_DL_COMPRESSED_ARCHIVE_PUSH_DETECT_CORE)
5521 DEFAULT_ACTION_OK_FUNC(action_ok_logging_list, ACTION_OK_DL_LOGGING_SETTINGS_LIST)
5522 DEFAULT_ACTION_OK_FUNC(action_ok_frame_throttle_list, ACTION_OK_DL_FRAME_THROTTLE_SETTINGS_LIST)
5523 DEFAULT_ACTION_OK_FUNC(action_ok_frame_time_counter_list, ACTION_OK_DL_FRAME_TIME_COUNTER_SETTINGS_LIST)
5524 DEFAULT_ACTION_OK_FUNC(action_ok_rewind_list, ACTION_OK_DL_REWIND_SETTINGS_LIST)
5525 DEFAULT_ACTION_OK_FUNC(action_ok_cheat, ACTION_OK_DL_CHEAT_DETAILS_SETTINGS_LIST)
5526 DEFAULT_ACTION_OK_FUNC(action_ok_cheat_start_or_cont, ACTION_OK_DL_CHEAT_SEARCH_SETTINGS_LIST)
5527 DEFAULT_ACTION_OK_FUNC(action_ok_onscreen_display_list, ACTION_OK_DL_ONSCREEN_DISPLAY_SETTINGS_LIST)
5528 DEFAULT_ACTION_OK_FUNC(action_ok_onscreen_notifications_list, ACTION_OK_DL_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST)
5529 DEFAULT_ACTION_OK_FUNC(action_ok_onscreen_notifications_views_list, ACTION_OK_DL_ONSCREEN_NOTIFICATIONS_VIEWS_SETTINGS_LIST)
5530 DEFAULT_ACTION_OK_FUNC(action_ok_onscreen_overlay_list, ACTION_OK_DL_ONSCREEN_OVERLAY_SETTINGS_LIST)
5531 #ifdef HAVE_VIDEO_LAYOUT
5532 DEFAULT_ACTION_OK_FUNC(action_ok_onscreen_video_layout_list, ACTION_OK_DL_ONSCREEN_VIDEO_LAYOUT_SETTINGS_LIST)
5533 #endif
5534 DEFAULT_ACTION_OK_FUNC(action_ok_menu_list, ACTION_OK_DL_MENU_SETTINGS_LIST)
5535 DEFAULT_ACTION_OK_FUNC(action_ok_quick_menu_override_options, ACTION_OK_DL_QUICK_MENU_OVERRIDE_OPTIONS_LIST)
5536 DEFAULT_ACTION_OK_FUNC(action_ok_menu_views_list, ACTION_OK_DL_MENU_VIEWS_SETTINGS_LIST)
5537 DEFAULT_ACTION_OK_FUNC(action_ok_settings_views_list, ACTION_OK_DL_SETTINGS_VIEWS_SETTINGS_LIST)
5538 DEFAULT_ACTION_OK_FUNC(action_ok_quick_menu_views_list, ACTION_OK_DL_QUICK_MENU_VIEWS_SETTINGS_LIST)
5539 DEFAULT_ACTION_OK_FUNC(action_ok_power_management_list, ACTION_OK_DL_POWER_MANAGEMENT_SETTINGS_LIST)
5540 DEFAULT_ACTION_OK_FUNC(action_ok_cpu_perfpower_list, ACTION_OK_DL_CPU_PERFPOWER_SETTINGS_LIST)
5541 DEFAULT_ACTION_OK_FUNC(action_ok_cpu_policy_entry, ACTION_OK_DL_CPU_POLICY_SETTINGS_LIST)
5542 DEFAULT_ACTION_OK_FUNC(action_ok_menu_sounds_list, ACTION_OK_DL_MENU_SOUNDS_LIST)
5543 DEFAULT_ACTION_OK_FUNC(action_ok_user_interface_list, ACTION_OK_DL_USER_INTERFACE_SETTINGS_LIST)
5544 DEFAULT_ACTION_OK_FUNC(action_ok_menu_file_browser_list, ACTION_OK_DL_MENU_FILE_BROWSER_SETTINGS_LIST)
5545 DEFAULT_ACTION_OK_FUNC(action_ok_retro_achievements_list, ACTION_OK_DL_RETRO_ACHIEVEMENTS_SETTINGS_LIST)
5546 DEFAULT_ACTION_OK_FUNC(action_ok_updater_list, ACTION_OK_DL_UPDATER_SETTINGS_LIST)
5547 DEFAULT_ACTION_OK_FUNC(action_ok_lakka_services, ACTION_OK_DL_LAKKA_SERVICES_LIST)
5548 DEFAULT_ACTION_OK_FUNC(action_ok_user_list, ACTION_OK_DL_USER_SETTINGS_LIST)
5549 DEFAULT_ACTION_OK_FUNC(action_ok_netplay_sublist, ACTION_OK_DL_NETPLAY)
5550 DEFAULT_ACTION_OK_FUNC(action_ok_directory_list, ACTION_OK_DL_DIRECTORY_SETTINGS_LIST)
5551 DEFAULT_ACTION_OK_FUNC(action_ok_privacy_list, ACTION_OK_DL_PRIVACY_SETTINGS_LIST)
5552 DEFAULT_ACTION_OK_FUNC(action_ok_midi_list, ACTION_OK_DL_MIDI_SETTINGS_LIST)
5553 DEFAULT_ACTION_OK_FUNC(action_ok_rdb_entry, ACTION_OK_DL_RDB_ENTRY)
5554 #ifdef HAVE_AUDIOMIXER
5555 DEFAULT_ACTION_OK_FUNC(action_ok_mixer_stream_actions, ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST)
5556 #endif
5557 DEFAULT_ACTION_OK_FUNC(action_ok_browse_url_list, ACTION_OK_DL_BROWSE_URL_LIST)
5558 DEFAULT_ACTION_OK_FUNC(action_ok_core_list, ACTION_OK_DL_CORE_LIST)
5559 DEFAULT_ACTION_OK_FUNC(action_ok_sideload_core_list, ACTION_OK_DL_SIDELOAD_CORE_LIST)
5560 DEFAULT_ACTION_OK_FUNC(action_ok_cheat_file, ACTION_OK_DL_CHEAT_FILE)
5561 DEFAULT_ACTION_OK_FUNC(action_ok_cheat_file_append, ACTION_OK_DL_CHEAT_FILE_APPEND)
5562 DEFAULT_ACTION_OK_FUNC(action_ok_playlist_collection, ACTION_OK_DL_PLAYLIST_COLLECTION)
5563 DEFAULT_ACTION_OK_FUNC(action_ok_disk_image_append_list, ACTION_OK_DL_DISK_IMAGE_APPEND_LIST)
5564 DEFAULT_ACTION_OK_FUNC(action_ok_subsystem_add_list, ACTION_OK_DL_SUBSYSTEM_ADD_LIST)
5565 DEFAULT_ACTION_OK_FUNC(action_ok_subsystem_add_load, ACTION_OK_DL_SUBSYSTEM_LOAD)
5566 DEFAULT_ACTION_OK_FUNC(action_ok_record_configfile, ACTION_OK_DL_RECORD_CONFIGFILE)
5567 DEFAULT_ACTION_OK_FUNC(action_ok_stream_configfile, ACTION_OK_DL_STREAM_CONFIGFILE)
5568 DEFAULT_ACTION_OK_FUNC(action_ok_remap_file, ACTION_OK_DL_REMAP_FILE)
5569 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
5570 DEFAULT_ACTION_OK_FUNC(action_ok_shader_preset, ACTION_OK_DL_SHADER_PRESET)
5571 #endif
5572 DEFAULT_ACTION_OK_FUNC(action_ok_push_generic_list, ACTION_OK_DL_GENERIC)
5573 DEFAULT_ACTION_OK_FUNC(action_ok_audio_dsp_plugin, ACTION_OK_DL_AUDIO_DSP_PLUGIN)
5574 DEFAULT_ACTION_OK_FUNC(action_ok_video_filter, ACTION_OK_DL_VIDEO_FILTER)
5575 DEFAULT_ACTION_OK_FUNC(action_ok_overlay_preset, ACTION_OK_DL_OVERLAY_PRESET)
5576 #if defined(HAVE_VIDEO_LAYOUT)
5577 DEFAULT_ACTION_OK_FUNC(action_ok_video_layout, ACTION_OK_DL_VIDEO_LAYOUT)
5578 #endif
5579 DEFAULT_ACTION_OK_FUNC(action_ok_video_font, ACTION_OK_DL_VIDEO_FONT)
5580 DEFAULT_ACTION_OK_FUNC(action_ok_rpl_entry, ACTION_OK_DL_RPL_ENTRY)
5581 DEFAULT_ACTION_OK_FUNC(action_ok_open_archive_detect_core, ACTION_OK_DL_OPEN_ARCHIVE_DETECT_CORE)
5582 DEFAULT_ACTION_OK_FUNC(action_ok_file_load_music, ACTION_OK_DL_MUSIC)
5583 DEFAULT_ACTION_OK_FUNC(action_ok_push_accounts_list, ACTION_OK_DL_ACCOUNTS_LIST)
5584 DEFAULT_ACTION_OK_FUNC(action_ok_push_achievements_hardcore_pause_list, ACTION_OK_DL_ACHIEVEMENTS_HARDCORE_PAUSE_LIST)
5585 DEFAULT_ACTION_OK_FUNC(action_ok_push_driver_settings_list, ACTION_OK_DL_DRIVER_SETTINGS_LIST)
5586 DEFAULT_ACTION_OK_FUNC(action_ok_push_crt_switchres_settings_list, ACTION_OK_DL_CRT_SWITCHRES_SETTINGS_LIST)
5587 DEFAULT_ACTION_OK_FUNC(action_ok_push_video_settings_list, ACTION_OK_DL_VIDEO_SETTINGS_LIST)
5588 DEFAULT_ACTION_OK_FUNC(action_ok_push_video_fullscreen_mode_settings_list, ACTION_OK_DL_VIDEO_FULLSCREEN_MODE_SETTINGS_LIST)
5589 DEFAULT_ACTION_OK_FUNC(action_ok_push_video_synchronization_settings_list, ACTION_OK_DL_VIDEO_SYNCHRONIZATION_SETTINGS_LIST)
5590 DEFAULT_ACTION_OK_FUNC(action_ok_push_video_windowed_mode_settings_list, ACTION_OK_DL_VIDEO_WINDOWED_MODE_SETTINGS_LIST)
5591 DEFAULT_ACTION_OK_FUNC(action_ok_push_video_scaling_settings_list, ACTION_OK_DL_VIDEO_SCALING_SETTINGS_LIST)
5592 DEFAULT_ACTION_OK_FUNC(action_ok_push_video_output_settings_list, ACTION_OK_DL_VIDEO_OUTPUT_SETTINGS_LIST)
5593 DEFAULT_ACTION_OK_FUNC(action_ok_push_configuration_settings_list, ACTION_OK_DL_CONFIGURATION_SETTINGS_LIST)
5594 DEFAULT_ACTION_OK_FUNC(action_ok_push_core_settings_list, ACTION_OK_DL_CORE_SETTINGS_LIST)
5595 DEFAULT_ACTION_OK_FUNC(action_ok_push_core_information_list, ACTION_OK_DL_CORE_INFORMATION_LIST)
5596 DEFAULT_ACTION_OK_FUNC(action_ok_push_core_restore_backup_list, ACTION_OK_DL_CORE_RESTORE_BACKUP_LIST)
5597 DEFAULT_ACTION_OK_FUNC(action_ok_push_core_delete_backup_list, ACTION_OK_DL_CORE_DELETE_BACKUP_LIST)
5598 DEFAULT_ACTION_OK_FUNC(action_ok_push_audio_settings_list, ACTION_OK_DL_AUDIO_SETTINGS_LIST)
5599 DEFAULT_ACTION_OK_FUNC(action_ok_push_audio_output_settings_list, ACTION_OK_DL_AUDIO_OUTPUT_SETTINGS_LIST)
5600 DEFAULT_ACTION_OK_FUNC(action_ok_push_audio_resampler_settings_list, ACTION_OK_DL_AUDIO_RESAMPLER_SETTINGS_LIST)
5601 DEFAULT_ACTION_OK_FUNC(action_ok_push_audio_synchronization_settings_list, ACTION_OK_DL_AUDIO_SYNCHRONIZATION_SETTINGS_LIST)
5602 #ifdef HAVE_AUDIOMIXER
5603 DEFAULT_ACTION_OK_FUNC(action_ok_push_audio_mixer_settings_list, ACTION_OK_DL_AUDIO_MIXER_SETTINGS_LIST)
5604 #endif
5605 DEFAULT_ACTION_OK_FUNC(action_ok_push_ai_service_settings_list, ACTION_OK_DL_AI_SERVICE_SETTINGS_LIST)
5606 DEFAULT_ACTION_OK_FUNC(action_ok_push_accessibility_settings_list, ACTION_OK_DL_ACCESSIBILITY_SETTINGS_LIST)
5607 DEFAULT_ACTION_OK_FUNC(action_ok_push_input_settings_list, ACTION_OK_DL_INPUT_SETTINGS_LIST)
5608 DEFAULT_ACTION_OK_FUNC(action_ok_push_input_menu_settings_list, ACTION_OK_DL_INPUT_MENU_SETTINGS_LIST)
5609 DEFAULT_ACTION_OK_FUNC(action_ok_push_input_turbo_fire_settings_list, ACTION_OK_DL_INPUT_TURBO_FIRE_SETTINGS_LIST)
5610 DEFAULT_ACTION_OK_FUNC(action_ok_push_input_haptic_feedback_settings_list, ACTION_OK_DL_INPUT_HAPTIC_FEEDBACK_SETTINGS_LIST)
5611 DEFAULT_ACTION_OK_FUNC(action_ok_push_latency_settings_list, ACTION_OK_DL_LATENCY_SETTINGS_LIST)
5612 DEFAULT_ACTION_OK_FUNC(action_ok_push_recording_settings_list, ACTION_OK_DL_RECORDING_SETTINGS_LIST)
5613 DEFAULT_ACTION_OK_FUNC(action_ok_push_playlist_settings_list, ACTION_OK_DL_PLAYLIST_SETTINGS_LIST)
5614 DEFAULT_ACTION_OK_FUNC(action_ok_push_playlist_manager_list, ACTION_OK_DL_PLAYLIST_MANAGER_LIST)
5615 DEFAULT_ACTION_OK_FUNC(action_ok_push_playlist_manager_settings, ACTION_OK_DL_PLAYLIST_MANAGER_SETTINGS)
5616 DEFAULT_ACTION_OK_FUNC(action_ok_push_input_hotkey_binds_list, ACTION_OK_DL_INPUT_HOTKEY_BINDS_LIST)
5617 DEFAULT_ACTION_OK_FUNC(action_ok_push_user_binds_list, ACTION_OK_DL_USER_BINDS_LIST)
5618 DEFAULT_ACTION_OK_FUNC(action_ok_push_accounts_cheevos_list, ACTION_OK_DL_ACCOUNTS_CHEEVOS_LIST)
5619 DEFAULT_ACTION_OK_FUNC(action_ok_push_accounts_youtube_list, ACTION_OK_DL_ACCOUNTS_YOUTUBE_LIST)
5620 DEFAULT_ACTION_OK_FUNC(action_ok_push_accounts_twitch_list, ACTION_OK_DL_ACCOUNTS_TWITCH_LIST)
5621 DEFAULT_ACTION_OK_FUNC(action_ok_push_accounts_facebook_list, ACTION_OK_DL_ACCOUNTS_FACEBOOK_LIST)
5622 DEFAULT_ACTION_OK_FUNC(action_ok_push_dump_disc_list, ACTION_OK_DL_DUMP_DISC_LIST)
5623 DEFAULT_ACTION_OK_FUNC(action_ok_push_load_disc_list, ACTION_OK_DL_LOAD_DISC_LIST)
5624 DEFAULT_ACTION_OK_FUNC(action_ok_open_archive, ACTION_OK_DL_OPEN_ARCHIVE)
5625 DEFAULT_ACTION_OK_FUNC(action_ok_rgui_menu_theme_preset, ACTION_OK_DL_RGUI_MENU_THEME_PRESET)
5626 DEFAULT_ACTION_OK_FUNC(action_ok_pl_thumbnails_updater_list, ACTION_OK_DL_PL_THUMBNAILS_UPDATER_LIST)
5627 DEFAULT_ACTION_OK_FUNC(action_ok_push_manual_content_scan_list, ACTION_OK_DL_MANUAL_CONTENT_SCAN_LIST)
5628 DEFAULT_ACTION_OK_FUNC(action_ok_manual_content_scan_dat_file, ACTION_OK_DL_MANUAL_CONTENT_SCAN_DAT_FILE)
5629 DEFAULT_ACTION_OK_FUNC(action_ok_push_core_manager_list, ACTION_OK_DL_CORE_MANAGER_LIST)
5630 DEFAULT_ACTION_OK_FUNC(action_ok_push_core_option_override_list, ACTION_OK_DL_CORE_OPTION_OVERRIDE_LIST)
5631
5632 static int action_ok_open_uwp_permission_settings(const char *path,
5633 const char *label, unsigned type, size_t idx, size_t entry_idx)
5634 {
5635 #ifdef __WINRT__
5636 uwp_open_broadfilesystemaccess_settings();
5637 #else
5638 retro_assert(false);
5639 #endif
5640 return 0;
5641 }
5642
action_ok_open_picker(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5643 static int action_ok_open_picker(const char *path,
5644 const char *label, unsigned type, size_t idx, size_t entry_idx)
5645 {
5646 int ret;
5647 #ifdef __WINRT__
5648 char *new_path = uwp_trigger_picker();
5649 if (!new_path)
5650 return 0; /* User aborted */
5651 #else
5652 char *new_path = NULL;
5653 retro_assert(false);
5654 #endif
5655
5656 ret = generic_action_ok_displaylist_push(path, new_path,
5657 msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES),
5658 MENU_SETTING_ACTION_FAVORITES_DIR, idx,
5659 entry_idx, ACTION_OK_DL_CONTENT_LIST);
5660
5661 free(new_path);
5662 return ret;
5663 }
5664
5665 #ifdef HAVE_NETWORKING
wifi_menu_refresh_callback(retro_task_t * task,void * task_data,void * user_data,const char * error)5666 static void wifi_menu_refresh_callback(retro_task_t *task,
5667 void *task_data,
5668 void *user_data, const char *error)
5669 {
5670 bool refresh = false;
5671 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
5672 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
5673 }
5674
action_ok_wifi_disconnect(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5675 static int action_ok_wifi_disconnect(const char *path,
5676 const char *label, unsigned type, size_t idx, size_t entry_idx)
5677 {
5678 task_push_wifi_disconnect(wifi_menu_refresh_callback);
5679 return true;
5680 }
5681 #endif
5682
action_ok_netplay_connect_room(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5683 static int action_ok_netplay_connect_room(const char *path,
5684 const char *label, unsigned type, size_t idx, size_t entry_idx)
5685 {
5686 #ifdef HAVE_NETWORKING
5687 char tmp_hostname[4115];
5688 unsigned room_index = type - MENU_SETTINGS_NETPLAY_ROOMS_START;
5689
5690 tmp_hostname[0] = '\0';
5691
5692 if (room_index >= (unsigned)netplay_room_count)
5693 return menu_cbs_exit();
5694
5695 if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
5696 generic_action_ok_command(CMD_EVENT_NETPLAY_DEINIT);
5697 netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
5698
5699 if (netplay_room_list[room_index].host_method == NETPLAY_HOST_METHOD_MITM)
5700 snprintf(tmp_hostname,
5701 sizeof(tmp_hostname),
5702 "%s|%d",
5703 netplay_room_list[room_index].mitm_address,
5704 netplay_room_list[room_index].mitm_port);
5705 else
5706 snprintf(tmp_hostname,
5707 sizeof(tmp_hostname),
5708 "%s|%d",
5709 netplay_room_list[room_index].address,
5710 netplay_room_list[room_index].port);
5711
5712 #if 0
5713 RARCH_LOG("[lobby] connecting to: %s with game: %s/%08x\n",
5714 tmp_hostname,
5715 netplay_room_list[room_index].gamename,
5716 netplay_room_list[room_index].gamecrc);
5717 #endif
5718
5719 task_push_netplay_crc_scan(
5720 netplay_room_list[room_index].gamecrc,
5721 netplay_room_list[room_index].gamename,
5722 tmp_hostname,
5723 netplay_room_list[room_index].corename,
5724 netplay_room_list[room_index].subsystem_name);
5725
5726 #else
5727 return -1;
5728
5729 #endif
5730 return 0;
5731 }
5732
action_ok_netplay_lan_scan(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5733 static int action_ok_netplay_lan_scan(const char *path,
5734 const char *label, unsigned type, size_t idx, size_t entry_idx)
5735 {
5736 #ifdef HAVE_NETWORKING
5737 struct netplay_host_list *hosts = NULL;
5738 struct netplay_host *host = NULL;
5739
5740 /* Figure out what host we're connecting to */
5741 if (!netplay_discovery_driver_ctl(RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &hosts))
5742 return -1;
5743 if (entry_idx >= hosts->size)
5744 return -1;
5745 host = &hosts->hosts[entry_idx];
5746
5747 /* Enable Netplay client mode */
5748 if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
5749 generic_action_ok_command(CMD_EVENT_NETPLAY_DEINIT);
5750 netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
5751
5752 /* Enable Netplay */
5753 if (command_event(CMD_EVENT_NETPLAY_INIT_DIRECT, (void *) host))
5754 return generic_action_ok_command(CMD_EVENT_RESUME);
5755 #endif
5756 return -1;
5757 }
5758
DEFAULT_ACTION_OK_DL_PUSH(action_ok_content_collection_list,FILEBROWSER_SELECT_COLLECTION,ACTION_OK_DL_CONTENT_COLLECTION_LIST,NULL)5759 DEFAULT_ACTION_OK_DL_PUSH(action_ok_content_collection_list, FILEBROWSER_SELECT_COLLECTION, ACTION_OK_DL_CONTENT_COLLECTION_LIST, NULL)
5760 DEFAULT_ACTION_OK_DL_PUSH(action_ok_push_content_list, FILEBROWSER_SELECT_FILE, ACTION_OK_DL_CONTENT_LIST, settings->paths.directory_menu_content)
5761 DEFAULT_ACTION_OK_DL_PUSH(action_ok_push_scan_file, FILEBROWSER_SCAN_FILE, ACTION_OK_DL_CONTENT_LIST, settings->paths.directory_menu_content)
5762
5763 #ifdef HAVE_NETWORKING
5764 static void netplay_refresh_rooms_cb(retro_task_t *task,
5765 void *task_data, void *user_data, const char *err)
5766 {
5767 char *new_data = NULL;
5768 const char *path = NULL;
5769 const char *label = NULL;
5770 unsigned menu_type = 0;
5771 enum msg_hash_enums enum_idx = MSG_UNKNOWN;
5772
5773 http_transfer_data_t *data = (http_transfer_data_t*)task_data;
5774
5775 menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
5776
5777 /* Don't push the results if we left the netplay menu */
5778 if (!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB))
5779 && !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY)))
5780 return;
5781
5782 if (!data || err)
5783 goto finish;
5784
5785 new_data = (char*)realloc(data->data, data->len + 1);
5786
5787 if (!new_data)
5788 goto finish;
5789
5790 data->data = new_data;
5791 data->data[data->len] = '\0';
5792
5793 if (!string_ends_with_size(data->data, "registry.lpl",
5794 strlen(data->data),
5795 STRLEN_CONST("registry.lpl")))
5796 {
5797 if (string_is_empty(data->data))
5798 netplay_room_count = 0;
5799 else
5800 {
5801 char s[PATH_MAX_LENGTH];
5802 unsigned i = 0;
5803 unsigned j = 0;
5804 struct netplay_host_list *lan_hosts = NULL;
5805 int lan_room_count = 0;
5806 bool refresh = false;
5807
5808 #ifndef RARCH_CONSOLE
5809 netplay_discovery_driver_ctl(RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &lan_hosts);
5810 if (lan_hosts)
5811 lan_room_count = (int)lan_hosts->size;
5812 #endif
5813
5814 netplay_rooms_parse(data->data);
5815
5816 if (netplay_room_list)
5817 free(netplay_room_list);
5818
5819 /* TODO/FIXME - right now, a LAN and non-LAN netplay session might appear
5820 * in the same list. If both entries are available, we want to show only
5821 * the LAN one. */
5822
5823 netplay_room_count = netplay_rooms_get_count();
5824 netplay_room_list = (struct netplay_room*)
5825 calloc(netplay_room_count + lan_room_count,
5826 sizeof(struct netplay_room));
5827
5828 for (i = 0; i < (unsigned)netplay_room_count; i++)
5829 memcpy(&netplay_room_list[i], netplay_room_get(i), sizeof(netplay_room_list[i]));
5830
5831 if (lan_room_count != 0)
5832 {
5833 for (i = netplay_room_count; i < (unsigned)(netplay_room_count + lan_room_count); i++)
5834 {
5835 struct netplay_host *host = &lan_hosts->hosts[j++];
5836
5837 strlcpy(netplay_room_list[i].nickname,
5838 host->nick,
5839 sizeof(netplay_room_list[i].nickname));
5840
5841 strlcpy(netplay_room_list[i].address,
5842 host->address,
5843 INET6_ADDRSTRLEN);
5844 strlcpy(netplay_room_list[i].corename,
5845 host->core,
5846 sizeof(netplay_room_list[i].corename));
5847 strlcpy(netplay_room_list[i].retroarch_version,
5848 host->retroarch_version,
5849 sizeof(netplay_room_list[i].retroarch_version));
5850 strlcpy(netplay_room_list[i].coreversion,
5851 host->core_version,
5852 sizeof(netplay_room_list[i].coreversion));
5853 strlcpy(netplay_room_list[i].gamename,
5854 host->content,
5855 sizeof(netplay_room_list[i].gamename));
5856 strlcpy(netplay_room_list[i].frontend,
5857 host->frontend,
5858 sizeof(netplay_room_list[i].frontend));
5859 strlcpy(netplay_room_list[i].subsystem_name,
5860 host->subsystem_name,
5861 sizeof(netplay_room_list[i].subsystem_name));
5862
5863 netplay_room_list[i].port = host->port;
5864 netplay_room_list[i].gamecrc = host->content_crc;
5865 netplay_room_list[i].timestamp = 0;
5866 netplay_room_list[i].lan = true;
5867
5868 snprintf(s, sizeof(s),
5869 msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME),
5870 netplay_room_list[i].nickname);
5871 }
5872 netplay_room_count += lan_room_count;
5873 }
5874
5875 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
5876 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
5877 }
5878 }
5879
5880 finish:
5881
5882 if (err)
5883 RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED), err);
5884
5885 if (user_data)
5886 free(user_data);
5887 }
5888
5889 #ifndef RARCH_CONSOLE
netplay_lan_scan_callback(retro_task_t * task,void * task_data,void * user_data,const char * error)5890 static void netplay_lan_scan_callback(retro_task_t *task,
5891 void *task_data,
5892 void *user_data, const char *error)
5893 {
5894 struct netplay_host_list *netplay_hosts = NULL;
5895 enum msg_hash_enums enum_idx = MSG_UNKNOWN;
5896 unsigned menu_type = 0;
5897 const char *label = NULL;
5898 const char *path = NULL;
5899
5900 /* TODO/FIXME: I have no idea what this is supposed to be
5901 * doing...
5902 * As it stands, this function will never get past the
5903 * following sanity check (i.e. netplay_lan_scan_callback()
5904 * will never be called when we are viewing the 'lan scan
5905 * settings' list, since this list doesn't even exist...).
5906 * Moreover, any menu entries that get added here
5907 * (menu_entries_append_enum()) will be erased by the
5908 * subsequent netplay_refresh_rooms_cb() callback - and
5909 * menu entries should never be added outside of
5910 * menu_displaylist.c anyway.
5911 * This is some legacy garbage, and someone who understands
5912 * netplay needs to rip it all out. */
5913
5914 menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
5915
5916 /* Don't push the results if we left the LAN scan menu */
5917 if (!string_is_equal(label,
5918 msg_hash_to_str(
5919 MENU_ENUM_LABEL_DEFERRED_NETPLAY_LAN_SCAN_SETTINGS_LIST)))
5920 return;
5921
5922 if (!netplay_discovery_driver_ctl(
5923 RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES,
5924 (void *) &netplay_hosts))
5925 return;
5926
5927 if (netplay_hosts->size > 0)
5928 {
5929 unsigned i;
5930 file_list_t *file_list = menu_entries_get_selection_buf_ptr(0);
5931
5932 menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, file_list);
5933
5934 for (i = 0; i < netplay_hosts->size; i++)
5935 {
5936 struct netplay_host *host = &netplay_hosts->hosts[i];
5937 menu_entries_append_enum(file_list,
5938 host->nick,
5939 msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_CONNECT_TO),
5940 MENU_ENUM_LABEL_NETPLAY_CONNECT_TO,
5941 MENU_NETPLAY_LAN_SCAN, 0, 0);
5942 }
5943 }
5944 }
5945 #endif
5946
action_ok_push_netplay_refresh_rooms(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5947 static int action_ok_push_netplay_refresh_rooms(const char *path,
5948 const char *label, unsigned type, size_t idx, size_t entry_idx)
5949 {
5950 char url [2048] = "http://lobby.libretro.com/list/";
5951 #ifndef RARCH_CONSOLE
5952 task_push_netplay_lan_scan(netplay_lan_scan_callback);
5953 #endif
5954 task_push_http_transfer(url, true, NULL, netplay_refresh_rooms_cb, NULL);
5955 return 0;
5956 }
5957 #endif
5958
action_ok_scan_directory_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5959 static int action_ok_scan_directory_list(const char *path,
5960 const char *label, unsigned type, size_t idx, size_t entry_idx)
5961 {
5962 settings_t *settings = config_get_ptr();
5963 const char *dir_menu_content = settings->paths.directory_menu_content;
5964
5965 filebrowser_clear_type();
5966 return generic_action_ok_displaylist_push(path,
5967 dir_menu_content, label, type, idx,
5968 entry_idx, ACTION_OK_DL_SCAN_DIR_LIST);
5969 }
5970
action_ok_push_random_dir(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5971 static int action_ok_push_random_dir(const char *path,
5972 const char *label, unsigned type, size_t idx, size_t entry_idx)
5973 {
5974 return generic_action_ok_displaylist_push(path, path,
5975 msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES),
5976 type, idx,
5977 entry_idx, ACTION_OK_DL_CONTENT_LIST);
5978 }
5979
action_ok_push_downloads_dir(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5980 static int action_ok_push_downloads_dir(const char *path,
5981 const char *label, unsigned type, size_t idx, size_t entry_idx)
5982 {
5983 settings_t *settings = config_get_ptr();
5984 const char *dir_core_assets = settings->paths.directory_core_assets;
5985
5986 filebrowser_set_type(FILEBROWSER_SELECT_FILE);
5987 return generic_action_ok_displaylist_push(path,
5988 dir_core_assets,
5989 msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES),
5990 type, idx,
5991 entry_idx, ACTION_OK_DL_CONTENT_LIST);
5992 }
5993
action_ok_push_filebrowser_list_dir_select(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)5994 int action_ok_push_filebrowser_list_dir_select(const char *path,
5995 const char *label, unsigned type, size_t idx, size_t entry_idx)
5996 {
5997 menu_handle_t *menu = menu_driver_get_ptr();
5998
5999 if (!menu)
6000 return menu_cbs_exit();
6001
6002 filebrowser_set_type(FILEBROWSER_SELECT_DIR);
6003 strlcpy(menu->filebrowser_label, label, sizeof(menu->filebrowser_label));
6004 return generic_action_ok_displaylist_push(path, NULL, label, type, idx,
6005 entry_idx, ACTION_OK_DL_FILE_BROWSER_SELECT_DIR);
6006 }
6007
action_ok_push_filebrowser_list_file_select(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6008 int action_ok_push_filebrowser_list_file_select(const char *path,
6009 const char *label, unsigned type, size_t idx, size_t entry_idx)
6010 {
6011 menu_handle_t *menu = menu_driver_get_ptr();
6012
6013 if (!menu)
6014 return menu_cbs_exit();
6015
6016 filebrowser_set_type(FILEBROWSER_SELECT_FILE);
6017 strlcpy(menu->filebrowser_label, label, sizeof(menu->filebrowser_label));
6018 return generic_action_ok_displaylist_push(path, NULL, label, type, idx,
6019 entry_idx, ACTION_OK_DL_FILE_BROWSER_SELECT_DIR);
6020 }
6021
action_ok_push_manual_content_scan_dir_select(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6022 int action_ok_push_manual_content_scan_dir_select(const char *path,
6023 const char *label, unsigned type, size_t idx, size_t entry_idx)
6024 {
6025 settings_t *settings = config_get_ptr();
6026 const char *dir_menu_content = settings->paths.directory_menu_content;
6027
6028 filebrowser_clear_type();
6029 return generic_action_ok_displaylist_push(path,
6030 dir_menu_content, label, type, idx,
6031 entry_idx, ACTION_OK_DL_MANUAL_SCAN_DIR_LIST);
6032 }
6033
6034 /* TODO/FIXME */
action_ok_push_dropdown_setting_core_options_item_special(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6035 static int action_ok_push_dropdown_setting_core_options_item_special(
6036 const char *path,
6037 const char *label, unsigned type, size_t idx, size_t entry_idx)
6038 {
6039 core_option_manager_t *coreopts = NULL;
6040 int core_option_idx = (int)atoi(label);
6041
6042 rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts);
6043
6044 if (!coreopts)
6045 return -1;
6046
6047 core_option_manager_set_val(coreopts, core_option_idx, idx);
6048 return action_cancel_pop_default(NULL, NULL, 0, 0);
6049 }
6050
action_ok_push_dropdown_setting_core_options_item(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6051 static int action_ok_push_dropdown_setting_core_options_item(const char *path,
6052 const char *label, unsigned type, size_t idx, size_t entry_idx)
6053 {
6054 core_option_manager_t *coreopts = NULL;
6055 int core_option_idx = (int)atoi(label);
6056
6057 rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts);
6058
6059 if (!coreopts)
6060 return -1;
6061
6062 core_option_manager_set_val(coreopts, core_option_idx, idx);
6063 return action_cancel_pop_default(NULL, NULL, 0, 0);
6064 }
6065
6066 /* TODO/FIXME */
6067
action_ok_push_dropdown_setting_uint_item_special(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6068 static int action_ok_push_dropdown_setting_uint_item_special(const char *path,
6069 const char *label, unsigned type, size_t idx, size_t entry_idx)
6070 {
6071 unsigned value;
6072 enum msg_hash_enums enum_idx = (enum msg_hash_enums)atoi(label);
6073 rarch_setting_t *setting = menu_setting_find_enum(enum_idx);
6074
6075 if (!setting)
6076 return -1;
6077
6078 value = (unsigned)(idx + setting->offset_by);
6079
6080 if (!string_is_empty(path))
6081 {
6082 unsigned path_value = atoi(path);
6083 if (path_value != value)
6084 value = path_value;
6085 }
6086
6087 *setting->value.target.unsigned_integer = value;
6088
6089 if (setting->change_handler)
6090 setting->change_handler(setting);
6091
6092 return action_cancel_pop_default(NULL, NULL, 0, 0);
6093 }
6094
6095
generic_action_ok_dropdown_setting(const char * path,const char * label,unsigned type,size_t idx)6096 static int generic_action_ok_dropdown_setting(const char *path, const char *label,
6097 unsigned type, size_t idx)
6098 {
6099 enum msg_hash_enums enum_idx = (enum msg_hash_enums)atoi(label);
6100 rarch_setting_t *setting = menu_setting_find_enum(enum_idx);
6101
6102 if (!setting)
6103 return -1;
6104
6105 switch (setting->type)
6106 {
6107 case ST_INT:
6108 *setting->value.target.integer = (int32_t)(idx + setting->offset_by);
6109 break;
6110 case ST_UINT:
6111 {
6112 unsigned value = (unsigned)(idx + setting->offset_by);
6113 *setting->value.target.unsigned_integer = value;
6114 }
6115 break;
6116 case ST_FLOAT:
6117 {
6118 float val = (float)atof(path);
6119 *setting->value.target.fraction = (float)val;
6120 }
6121 break;
6122 case ST_STRING_OPTIONS:
6123 if (setting->get_string_representation)
6124 {
6125 struct string_list tmp_str_list = { 0 };
6126 string_list_initialize(&tmp_str_list);
6127 string_split_noalloc(&tmp_str_list,
6128 setting->values, "|");
6129
6130 if (idx < tmp_str_list.size)
6131 {
6132 strlcpy(setting->value.target.string,
6133 tmp_str_list.elems[idx].data, setting->size);
6134 }
6135
6136 string_list_deinitialize(&tmp_str_list);
6137 break;
6138 }
6139 /* fallthrough */
6140 case ST_STRING:
6141 case ST_PATH:
6142 case ST_DIR:
6143 strlcpy(setting->value.target.string, path,
6144 setting->size);
6145 break;
6146 default:
6147 break;
6148 }
6149
6150 if (setting->change_handler)
6151 setting->change_handler(setting);
6152
6153 return action_cancel_pop_default(NULL, NULL, 0, 0);
6154 }
6155
action_ok_push_dropdown_setting(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6156 static int action_ok_push_dropdown_setting(const char *path,
6157 const char *label, unsigned type, size_t idx, size_t entry_idx)
6158 {
6159 return generic_action_ok_dropdown_setting(path, label, type, idx);
6160 }
6161
action_ok_push_dropdown_item(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6162 static int action_ok_push_dropdown_item(const char *path,
6163 const char *label, unsigned type, size_t idx, size_t entry_idx)
6164 {
6165 #if 0
6166 RARCH_LOG("dropdown: \n");
6167 RARCH_LOG("path: %s \n", path);
6168 RARCH_LOG("label: %s \n", label);
6169 RARCH_LOG("type: %d \n", type);
6170 RARCH_LOG("idx: %d \n", idx);
6171 RARCH_LOG("entry_idx: %d \n", entry_idx);
6172 #endif
6173 return 0;
6174 }
6175
action_cb_push_dropdown_item_resolution(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6176 int action_cb_push_dropdown_item_resolution(const char *path,
6177 const char *label, unsigned type, size_t idx, size_t entry_idx)
6178 {
6179 char str[100];
6180 char *pch = NULL;
6181 unsigned width = 0;
6182 unsigned height = 0;
6183 unsigned refreshrate = 0;
6184
6185 strlcpy(str, path, sizeof(str));
6186 pch = strtok(str, "x");
6187 if (pch)
6188 width = (unsigned)strtoul(pch, NULL, 0);
6189 pch = strtok(NULL, " ");
6190 if (pch)
6191 height = (unsigned)strtoul(pch, NULL, 0);
6192 pch = strtok(NULL, "(");
6193 if (pch)
6194 refreshrate = (unsigned)strtoul(pch, NULL, 0);
6195
6196 if (video_display_server_set_resolution(width, height,
6197 refreshrate, (float)refreshrate, 0, 0, 0, 0))
6198 {
6199 settings_t *settings = config_get_ptr();
6200
6201 video_monitor_set_refresh_rate((float)refreshrate);
6202
6203 settings->uints.video_fullscreen_x = width;
6204 settings->uints.video_fullscreen_y = height;
6205
6206 return 1;
6207 }
6208
6209 return 0;
6210 }
6211
action_ok_push_dropdown_item_video_shader_num_pass(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6212 static int action_ok_push_dropdown_item_video_shader_num_pass(const char *path,
6213 const char *label, unsigned type, size_t idx, size_t entry_idx)
6214 {
6215 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
6216 struct video_shader *shader = menu_shader_get();
6217
6218 if (!shader)
6219 return menu_cbs_exit();
6220
6221 shader->passes = (unsigned)idx;
6222
6223 video_shader_resolve_parameters(shader);
6224
6225 shader->modified = true;
6226
6227 return action_cancel_pop_default(NULL, NULL, 0, 0);
6228 #else
6229 return 0;
6230 #endif
6231 }
6232
action_ok_push_dropdown_item_video_shader_param_generic(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx,size_t setting_offset)6233 static int action_ok_push_dropdown_item_video_shader_param_generic(const char *path,
6234 const char *label, unsigned type, size_t idx, size_t entry_idx,
6235 size_t setting_offset)
6236 {
6237 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
6238 video_shader_ctx_t shader_info;
6239 unsigned offset = (unsigned)setting_offset;
6240 float val = atof(path);
6241 struct video_shader *shader = menu_shader_get();
6242 struct video_shader_parameter *param_menu = NULL;
6243 struct video_shader_parameter *param_prev = NULL;
6244
6245 video_shader_driver_get_current_shader(&shader_info);
6246
6247 param_prev = &shader_info.data->parameters[entry_idx - offset];
6248 if (shader)
6249 param_menu = &shader->parameters [entry_idx - offset];
6250
6251 if (!param_prev || !param_menu)
6252 return menu_cbs_exit();
6253
6254 param_prev->current = val;
6255 param_menu->current = param_prev->current;
6256
6257 shader->modified = true;
6258
6259 return action_cancel_pop_default(NULL, NULL, 0, 0);
6260 #else
6261 return 0;
6262 #endif
6263 }
6264
action_ok_push_dropdown_item_video_shader_param(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6265 static int action_ok_push_dropdown_item_video_shader_param(const char *path,
6266 const char *label, unsigned type, size_t idx, size_t entry_idx)
6267 {
6268 return action_ok_push_dropdown_item_video_shader_param_generic(
6269 path, label, type,
6270 idx, entry_idx, MENU_SETTINGS_SHADER_PARAMETER_0);
6271 }
6272
action_ok_push_dropdown_item_video_shader_preset_param(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6273 static int action_ok_push_dropdown_item_video_shader_preset_param(
6274 const char *path,
6275 const char *label, unsigned type, size_t idx, size_t entry_idx)
6276 {
6277 return action_ok_push_dropdown_item_video_shader_param_generic(
6278 path, label, type,
6279 idx, entry_idx, MENU_SETTINGS_SHADER_PRESET_PARAMETER_0);
6280 }
6281
action_ok_push_dropdown_item_resolution(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6282 static int action_ok_push_dropdown_item_resolution(const char *path,
6283 const char *label, unsigned type, size_t idx, size_t entry_idx)
6284 {
6285 if (action_cb_push_dropdown_item_resolution(path,
6286 label, type, idx, entry_idx) == 1)
6287 {
6288 /* TODO/FIXME - menu drivers like XMB don't rescale
6289 * automatically */
6290 return menu_cbs_exit();
6291 }
6292 return 0;
6293 }
6294
action_ok_push_dropdown_item_playlist_default_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6295 static int action_ok_push_dropdown_item_playlist_default_core(
6296 const char *path,
6297 const char *label, unsigned type, size_t idx, size_t entry_idx)
6298 {
6299 core_info_list_t *core_info_list = NULL;
6300 playlist_t *playlist = playlist_get_cached();
6301 const char* core_name = path;
6302
6303 /* Get core list */
6304 core_info_get_list(&core_info_list);
6305
6306 if (!core_info_list || !playlist)
6307 return -1;
6308
6309 /* Handle N/A or empty path input */
6310 if (string_is_empty(core_name) ||
6311 string_is_equal(core_name, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)))
6312 {
6313 playlist_set_default_core_path(playlist, "DETECT");
6314 playlist_set_default_core_name(playlist, "DETECT");
6315 }
6316 else
6317 {
6318 core_info_t *core_info = NULL;
6319 bool found = false;
6320 size_t i;
6321
6322 /* Loop through cores until we find a match */
6323 for (i = 0; i < core_info_list->count; i++)
6324 {
6325 core_info = NULL;
6326 core_info = core_info_get(core_info_list, i);
6327
6328 if (core_info)
6329 {
6330 if (string_is_equal(core_name, core_info->display_name))
6331 {
6332 /* Update playlist */
6333 playlist_set_default_core_path(playlist, core_info->path);
6334 playlist_set_default_core_name(playlist, core_info->display_name);
6335
6336 found = true;
6337 break;
6338 }
6339 }
6340 }
6341
6342 /* Fallback... */
6343 if (!found)
6344 {
6345 playlist_set_default_core_path(playlist, "DETECT");
6346 playlist_set_default_core_name(playlist, "DETECT");
6347 }
6348 }
6349
6350 /* In all cases, update file on disk */
6351 playlist_write_file(playlist);
6352
6353 return action_cancel_pop_default(NULL, NULL, 0, 0);
6354 }
6355
6356
action_ok_push_dropdown_item_playlist_label_display_mode(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6357 static int action_ok_push_dropdown_item_playlist_label_display_mode(
6358 const char *path,
6359 const char *label, unsigned type, size_t idx, size_t entry_idx)
6360 {
6361 playlist_t *playlist = playlist_get_cached();
6362
6363 playlist_set_label_display_mode(playlist,
6364 (enum playlist_label_display_mode)idx);
6365
6366 /* In all cases, update file on disk */
6367 playlist_write_file(playlist);
6368
6369 return action_cancel_pop_default(NULL, NULL, 0, 0);
6370 }
6371
generic_set_thumbnail_mode(enum playlist_thumbnail_id thumbnail_id,size_t idx)6372 static int generic_set_thumbnail_mode(
6373 enum playlist_thumbnail_id thumbnail_id, size_t idx)
6374 {
6375 playlist_t *playlist = playlist_get_cached();
6376
6377 if (!playlist)
6378 return -1;
6379
6380 playlist_set_thumbnail_mode(playlist, thumbnail_id,
6381 (enum playlist_thumbnail_mode)idx);
6382 playlist_write_file(playlist);
6383
6384 return action_cancel_pop_default(NULL, NULL, 0, 0);
6385 }
6386
action_ok_push_dropdown_item_playlist_right_thumbnail_mode(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6387 static int action_ok_push_dropdown_item_playlist_right_thumbnail_mode(
6388 const char *path,
6389 const char *label, unsigned type, size_t idx, size_t entry_idx)
6390 {
6391 return generic_set_thumbnail_mode(PLAYLIST_THUMBNAIL_RIGHT, idx);
6392 }
6393
action_ok_push_dropdown_item_playlist_left_thumbnail_mode(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6394 static int action_ok_push_dropdown_item_playlist_left_thumbnail_mode(
6395 const char *path,
6396 const char *label, unsigned type, size_t idx, size_t entry_idx)
6397 {
6398 return generic_set_thumbnail_mode(PLAYLIST_THUMBNAIL_LEFT, idx);
6399 }
6400
action_ok_push_dropdown_item_playlist_sort_mode(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6401 static int action_ok_push_dropdown_item_playlist_sort_mode(
6402 const char *path,
6403 const char *label, unsigned type, size_t idx, size_t entry_idx)
6404 {
6405 playlist_t *playlist = playlist_get_cached();
6406
6407 playlist_set_sort_mode(playlist, (enum playlist_sort_mode)idx);
6408 playlist_write_file(playlist);
6409
6410 return action_cancel_pop_default(NULL, NULL, 0, 0);
6411 }
6412
action_ok_push_dropdown_item_manual_content_scan_system_name(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6413 static int action_ok_push_dropdown_item_manual_content_scan_system_name(
6414 const char *path,
6415 const char *label, unsigned type, size_t idx, size_t entry_idx)
6416 {
6417 const char* system_name = path;
6418 enum manual_content_scan_system_name_type system_name_type =
6419 MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE;
6420
6421 /* Get system name type (i.e. check if setting is
6422 * 'use content directory' or 'use custom') */
6423 switch (idx)
6424 {
6425 case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR:
6426 case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM:
6427 system_name_type = (enum manual_content_scan_system_name_type)idx;
6428 break;
6429 default:
6430 break;
6431 }
6432
6433 /* Set system name */
6434 manual_content_scan_set_menu_system_name(
6435 system_name_type, system_name);
6436
6437 return action_cancel_pop_default(NULL, NULL, 0, 0);
6438 }
6439
action_ok_push_dropdown_item_manual_content_scan_core_name(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6440 static int action_ok_push_dropdown_item_manual_content_scan_core_name(
6441 const char *path,
6442 const char *label, unsigned type, size_t idx, size_t entry_idx)
6443 {
6444 const char* core_name = path;
6445 enum manual_content_scan_core_type core_type =
6446 MANUAL_CONTENT_SCAN_CORE_SET;
6447
6448 /* Get core type (i.e. check if setting is
6449 * DETECT/Unspecified) */
6450 if (idx == (size_t)MANUAL_CONTENT_SCAN_CORE_DETECT)
6451 core_type = MANUAL_CONTENT_SCAN_CORE_DETECT;
6452
6453 /* Set core name */
6454 manual_content_scan_set_menu_core_name(
6455 core_type, core_name);
6456
6457 return action_cancel_pop_default(NULL, NULL, 0, 0);
6458 }
6459
action_ok_push_dropdown_item_disk_index(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6460 static int action_ok_push_dropdown_item_disk_index(const char *path,
6461 const char *label, unsigned type, size_t idx, size_t entry_idx)
6462 {
6463 unsigned disk_index = (unsigned)idx;
6464
6465 command_event(CMD_EVENT_DISK_INDEX, &disk_index);
6466
6467 /* When choosing a disk, menu selection should
6468 * automatically be reset to the 'insert disk'
6469 * option */
6470 menu_entries_pop_stack(NULL, 0, 1);
6471 menu_navigation_set_selection(0);
6472
6473 return 0;
6474 }
6475
action_ok_push_dropdown_item_input_device_type(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6476 static int action_ok_push_dropdown_item_input_device_type(const char *path,
6477 const char *label, unsigned type, size_t idx, size_t entry_idx)
6478 {
6479 retro_ctx_controller_info_t pad;
6480 unsigned port = 0;
6481 unsigned device = 0;
6482
6483 const char *menu_path = NULL;
6484 enum msg_hash_enums enum_idx;
6485 rarch_setting_t *setting;
6486 menu_entries_get_last_stack(&menu_path, NULL, NULL, NULL, NULL);
6487 enum_idx = (enum msg_hash_enums)atoi(menu_path);
6488 setting = menu_setting_find_enum(enum_idx);
6489
6490 if (!setting)
6491 return menu_cbs_exit();
6492
6493 port = setting->index_offset;
6494 device = atoi(label);
6495
6496 input_config_set_device(port, device);
6497
6498 pad.port = port;
6499 pad.device = device;
6500
6501 core_set_controller_port_device(&pad);
6502
6503 return action_cancel_pop_default(NULL, NULL, 0, 0);
6504 }
6505
action_ok_push_dropdown_item_input_device_index(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6506 static int action_ok_push_dropdown_item_input_device_index(const char *path,
6507 const char *label, unsigned type, size_t idx, size_t entry_idx)
6508 {
6509 settings_t *settings = config_get_ptr();
6510
6511 const char *menu_path = NULL;
6512 enum msg_hash_enums enum_idx;
6513 rarch_setting_t *setting;
6514 menu_entries_get_last_stack(&menu_path, NULL, NULL, NULL, NULL);
6515 enum_idx = (enum msg_hash_enums)atoi(menu_path);
6516 setting = menu_setting_find_enum(enum_idx);
6517
6518 if (!setting)
6519 return menu_cbs_exit();
6520
6521 settings->uints.input_joypad_index[setting->index_offset] = (unsigned)entry_idx;
6522
6523 return action_cancel_pop_default(NULL, NULL, 0, 0);
6524 }
6525
action_ok_push_dropdown_item_input_description(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6526 static int action_ok_push_dropdown_item_input_description(const char *path,
6527 const char *label, unsigned type, size_t idx, size_t entry_idx)
6528 {
6529 unsigned remap_idx = (unsigned)entry_idx;
6530 unsigned entry_type = string_to_unsigned(label);
6531 settings_t *settings = config_get_ptr();
6532 unsigned user_idx;
6533 unsigned btn_idx;
6534
6535 if (!settings ||
6536 (entry_type < MENU_SETTINGS_INPUT_DESC_BEGIN) ||
6537 ((remap_idx >= RARCH_CUSTOM_BIND_LIST_END) &&
6538 (remap_idx != RARCH_UNMAPPED)))
6539 return menu_cbs_exit();
6540
6541 /* Determine user/button indices */
6542 user_idx = (entry_type - MENU_SETTINGS_INPUT_DESC_BEGIN)
6543 / (RARCH_FIRST_CUSTOM_BIND + 8);
6544 btn_idx = (entry_type - MENU_SETTINGS_INPUT_DESC_BEGIN)
6545 - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
6546
6547 if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END))
6548 return menu_cbs_exit();
6549
6550 /* Assign new mapping */
6551 settings->uints.input_remap_ids[user_idx][btn_idx] = remap_idx;
6552
6553 return action_cancel_pop_default(NULL, NULL, 0, 0);
6554 }
6555
action_ok_push_dropdown_item_input_description_kbd(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6556 static int action_ok_push_dropdown_item_input_description_kbd(
6557 const char *path,
6558 const char *label, unsigned type, size_t idx, size_t entry_idx)
6559 {
6560 unsigned key_id = (unsigned)entry_idx;
6561 unsigned entry_type = string_to_unsigned(label);
6562 settings_t *settings = config_get_ptr();
6563 unsigned user_idx;
6564 unsigned btn_idx;
6565
6566 if (!settings ||
6567 (entry_type < MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) ||
6568 (key_id >= (RARCH_MAX_KEYS + MENU_SETTINGS_INPUT_DESC_KBD_BEGIN)))
6569 return menu_cbs_exit();
6570
6571 /* Determine user/button indices */
6572 user_idx = (entry_type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN)
6573 / RARCH_ANALOG_BIND_LIST_END;
6574 btn_idx = (entry_type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN)
6575 - RARCH_ANALOG_BIND_LIST_END * user_idx;
6576
6577 if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END))
6578 return menu_cbs_exit();
6579
6580 /* Assign new mapping */
6581 settings->uints.input_keymapper_ids[user_idx][btn_idx] = key_id;
6582
6583 return action_cancel_pop_default(NULL, NULL, 0, 0);
6584 }
6585
action_ok_push_default(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6586 static int action_ok_push_default(const char *path,
6587 const char *label, unsigned type, size_t idx, size_t entry_idx)
6588 {
6589 filebrowser_clear_type();
6590 return generic_action_ok_displaylist_push(path, NULL, label, type, idx,
6591 entry_idx, ACTION_OK_DL_PUSH_DEFAULT);
6592 }
6593
action_ok_start_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6594 static int action_ok_start_core(const char *path,
6595 const char *label, unsigned type, size_t idx, size_t entry_idx)
6596 {
6597 content_ctx_info_t content_info;
6598
6599 content_info.argc = 0;
6600 content_info.argv = NULL;
6601 content_info.args = NULL;
6602 content_info.environ_get = NULL;
6603
6604 path_clear(RARCH_PATH_BASENAME);
6605 if (!task_push_start_current_core(&content_info))
6606 return -1;
6607
6608 return 0;
6609 }
6610
action_ok_load_archive(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6611 static int action_ok_load_archive(const char *path,
6612 const char *label, unsigned type, size_t idx, size_t entry_idx)
6613 {
6614 const char *menu_path = NULL;
6615 const char *content_path = NULL;
6616 menu_handle_t *menu = menu_driver_get_ptr();
6617
6618 if (!menu)
6619 return menu_cbs_exit();
6620
6621 menu_path = menu->scratch2_buf;
6622 content_path = menu->scratch_buf;
6623
6624 fill_pathname_join(menu->detect_content_path,
6625 menu_path, content_path,
6626 sizeof(menu->detect_content_path));
6627
6628 generic_action_ok_command(CMD_EVENT_LOAD_CORE);
6629
6630 return default_action_ok_load_content_with_core_from_menu(
6631 menu->detect_content_path,
6632 CORE_TYPE_PLAIN);
6633 }
6634
action_ok_load_archive_detect_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6635 static int action_ok_load_archive_detect_core(const char *path,
6636 const char *label, unsigned type, size_t idx, size_t entry_idx)
6637 {
6638 char new_core_path[PATH_MAX_LENGTH];
6639 menu_content_ctx_defer_info_t def_info;
6640 int ret = 0;
6641 core_info_list_t *list = NULL;
6642 const char *menu_path = NULL;
6643 const char *content_path = NULL;
6644 menu_handle_t *menu = menu_driver_get_ptr();
6645
6646 if (!menu)
6647 return menu_cbs_exit();
6648
6649 menu_path = menu->scratch2_buf;
6650 content_path = menu->scratch_buf;
6651
6652 core_info_get_list(&list);
6653
6654 def_info.data = list;
6655 def_info.dir = menu_path;
6656 def_info.path = content_path;
6657 def_info.menu_label = label;
6658 def_info.s = menu->deferred_path;
6659 def_info.len = sizeof(menu->deferred_path);
6660
6661 new_core_path[0] = '\0';
6662
6663 if (menu_content_find_first_core(&def_info, false,
6664 new_core_path, sizeof(new_core_path)))
6665 ret = -1;
6666
6667 fill_pathname_join(menu->detect_content_path, menu_path, content_path,
6668 sizeof(menu->detect_content_path));
6669
6670 switch (ret)
6671 {
6672 case -1:
6673 {
6674 content_ctx_info_t content_info;
6675
6676 content_info.argc = 0;
6677 content_info.argv = NULL;
6678 content_info.args = NULL;
6679 content_info.environ_get = NULL;
6680
6681 ret = 0;
6682
6683 if (!task_push_load_content_with_new_core_from_menu(
6684 new_core_path, def_info.s,
6685 &content_info,
6686 CORE_TYPE_PLAIN,
6687 NULL, NULL))
6688 ret = -1;
6689 else
6690 menu_driver_set_last_start_content(def_info.s);
6691 }
6692 break;
6693 case 0:
6694 idx = menu_navigation_get_selection();
6695 ret = generic_action_ok_displaylist_push(path, NULL,
6696 label, type,
6697 idx, entry_idx, ACTION_OK_DL_DEFERRED_CORE_LIST);
6698 break;
6699 default:
6700 break;
6701 }
6702
6703 return ret;
6704 }
6705
action_ok_help_send_debug_info(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6706 static int action_ok_help_send_debug_info(const char *path,
6707 const char *label, unsigned type, size_t idx, size_t entry_idx)
6708 {
6709 command_event(CMD_EVENT_SEND_DEBUG_INFO, NULL);
6710 return 0;
6711 }
6712
DEFAULT_ACTION_OK_HELP(action_ok_help_audio_video_troubleshooting,MENU_ENUM_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING,MENU_DIALOG_HELP_AUDIO_VIDEO_TROUBLESHOOTING)6713 DEFAULT_ACTION_OK_HELP(action_ok_help_audio_video_troubleshooting, MENU_ENUM_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING, MENU_DIALOG_HELP_AUDIO_VIDEO_TROUBLESHOOTING)
6714 DEFAULT_ACTION_OK_HELP(action_ok_help, MENU_ENUM_LABEL_HELP, MENU_DIALOG_WELCOME)
6715 DEFAULT_ACTION_OK_HELP(action_ok_help_controls, MENU_ENUM_LABEL_HELP_CONTROLS, MENU_DIALOG_HELP_CONTROLS)
6716 DEFAULT_ACTION_OK_HELP(action_ok_help_what_is_a_core, MENU_ENUM_LABEL_HELP_WHAT_IS_A_CORE, MENU_DIALOG_HELP_WHAT_IS_A_CORE)
6717 DEFAULT_ACTION_OK_HELP(action_ok_help_scanning_content, MENU_ENUM_LABEL_HELP_SCANNING_CONTENT, MENU_DIALOG_HELP_SCANNING_CONTENT)
6718 DEFAULT_ACTION_OK_HELP(action_ok_help_change_virtual_gamepad, MENU_ENUM_LABEL_HELP_CHANGE_VIRTUAL_GAMEPAD, MENU_DIALOG_HELP_CHANGE_VIRTUAL_GAMEPAD)
6719 DEFAULT_ACTION_OK_HELP(action_ok_help_load_content, MENU_ENUM_LABEL_HELP_LOADING_CONTENT, MENU_DIALOG_HELP_LOADING_CONTENT)
6720
6721 static int generic_dropdown_box_list(size_t idx, unsigned lbl)
6722 {
6723 generic_action_ok_displaylist_push(
6724 NULL,
6725 NULL, NULL, 0, idx, 0,
6726 lbl);
6727 return 0;
6728 }
6729
action_ok_video_resolution(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6730 static int action_ok_video_resolution(const char *path,
6731 const char *label, unsigned type, size_t idx, size_t entry_idx)
6732 {
6733 #if defined(GEKKO) || !defined(__PSL1GHT__) && defined(__PS3__)
6734 unsigned width = 0;
6735 unsigned height = 0;
6736
6737 if (video_driver_get_video_output_size(&width, &height))
6738 {
6739 char msg[PATH_MAX_LENGTH];
6740
6741 msg[0] = '\0';
6742
6743 #if defined(_WIN32) || !defined(__PSL1GHT__) && defined(__PS3__)
6744 generic_action_ok_command(CMD_EVENT_REINIT);
6745 #endif
6746 video_driver_set_video_mode(width, height, true);
6747 #ifdef GEKKO
6748 if (width == 0 || height == 0)
6749 strcpy_literal(msg, "Applying: DEFAULT");
6750 else
6751 #endif
6752 snprintf(msg, sizeof(msg),
6753 "Applying: %dx%d\n START to reset",
6754 width, height);
6755 runloop_msg_queue_push(msg, 1, 100, true, NULL,
6756 MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
6757 }
6758
6759 return 0;
6760 #else
6761 return generic_dropdown_box_list(idx,
6762 ACTION_OK_DL_DROPDOWN_BOX_LIST_RESOLUTION);
6763 #endif
6764 }
6765
action_ok_playlist_default_core(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6766 static int action_ok_playlist_default_core(const char *path,
6767 const char *label, unsigned type, size_t idx, size_t entry_idx)
6768 {
6769 return generic_dropdown_box_list(idx,
6770 ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE);
6771 }
6772
action_ok_playlist_label_display_mode(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6773 static int action_ok_playlist_label_display_mode(const char *path,
6774 const char *label, unsigned type, size_t idx, size_t entry_idx)
6775 {
6776 return generic_dropdown_box_list(idx,
6777 ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE);
6778 }
6779
action_ok_playlist_right_thumbnail_mode(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6780 static int action_ok_playlist_right_thumbnail_mode(const char *path,
6781 const char *label, unsigned type, size_t idx, size_t entry_idx)
6782 {
6783 return generic_dropdown_box_list(idx,
6784 ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE);
6785 }
6786
action_ok_playlist_left_thumbnail_mode(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6787 static int action_ok_playlist_left_thumbnail_mode(const char *path,
6788 const char *label, unsigned type, size_t idx, size_t entry_idx)
6789 {
6790 return generic_dropdown_box_list(idx,
6791 ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE);
6792 }
6793
action_ok_playlist_sort_mode(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6794 static int action_ok_playlist_sort_mode(const char *path,
6795 const char *label, unsigned type, size_t idx, size_t entry_idx)
6796 {
6797 return generic_dropdown_box_list(idx,
6798 ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_SORT_MODE);
6799 }
6800
action_ok_remappings_port_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6801 static int action_ok_remappings_port_list(const char *path,
6802 const char *label, unsigned type, size_t idx, size_t entry_idx)
6803 {
6804 generic_action_ok_displaylist_push(
6805 path,
6806 NULL, label, 0, idx, 0,
6807 ACTION_OK_DL_REMAPPINGS_PORT_LIST);
6808 return 0;
6809 }
6810
action_ok_shader_parameter_dropdown_box_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6811 static int action_ok_shader_parameter_dropdown_box_list(const char *path,
6812 const char *label, unsigned type, size_t idx, size_t entry_idx)
6813 {
6814 return generic_dropdown_box_list(idx,
6815 ACTION_OK_DL_DROPDOWN_BOX_LIST_SHADER_PARAMETER);
6816 }
6817
action_ok_shader_preset_parameter_dropdown_box_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6818 static int action_ok_shader_preset_parameter_dropdown_box_list(
6819 const char *path,
6820 const char *label, unsigned type, size_t idx, size_t entry_idx)
6821 {
6822 return generic_dropdown_box_list(idx,
6823 ACTION_OK_DL_DROPDOWN_BOX_LIST_SHADER_PRESET_PARAMETER);
6824 }
6825
action_ok_manual_content_scan_system_name(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6826 static int action_ok_manual_content_scan_system_name(const char *path,
6827 const char *label, unsigned type, size_t idx, size_t entry_idx)
6828 {
6829 return generic_dropdown_box_list(idx,
6830 ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME);
6831 }
6832
action_ok_manual_content_scan_core_name(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6833 static int action_ok_manual_content_scan_core_name(const char *path,
6834 const char *label, unsigned type, size_t idx, size_t entry_idx)
6835 {
6836 return generic_dropdown_box_list(idx,
6837 ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME);
6838 }
6839
action_ok_video_shader_num_passes_dropdown_box_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6840 static int action_ok_video_shader_num_passes_dropdown_box_list(
6841 const char *path,
6842 const char *label, unsigned type, size_t idx, size_t entry_idx)
6843 {
6844 return generic_dropdown_box_list(idx,
6845 ACTION_OK_DL_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES);
6846 }
6847
action_ok_disk_index_dropdown_box_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6848 static int action_ok_disk_index_dropdown_box_list(const char *path,
6849 const char *label, unsigned type, size_t idx, size_t entry_idx)
6850 {
6851 return generic_dropdown_box_list(idx,
6852 ACTION_OK_DL_DROPDOWN_BOX_LIST_DISK_INDEX);
6853 }
6854
action_ok_input_description_dropdown_box_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6855 static int action_ok_input_description_dropdown_box_list(const char *path,
6856 const char *label, unsigned type, size_t idx, size_t entry_idx)
6857 {
6858 return generic_action_ok_displaylist_push(
6859 path, NULL, label, type, idx, entry_idx,
6860 ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION);
6861 }
6862
action_ok_input_description_kbd_dropdown_box_list(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6863 static int action_ok_input_description_kbd_dropdown_box_list(
6864 const char *path,
6865 const char *label, unsigned type, size_t idx, size_t entry_idx)
6866 {
6867 return generic_action_ok_displaylist_push(
6868 path, NULL, label, type, idx, entry_idx,
6869 ACTION_OK_DL_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD);
6870 }
6871
action_ok_disk_cycle_tray_status(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6872 static int action_ok_disk_cycle_tray_status(const char *path,
6873 const char *label, unsigned type, size_t idx, size_t entry_idx)
6874 {
6875 bool disk_ejected = false;
6876 bool print_log = false;
6877 rarch_system_info_t *sys_info = runloop_get_system_info();
6878 settings_t *settings = config_get_ptr();
6879 #ifdef HAVE_AUDIOMIXER
6880 bool audio_enable_menu = settings->bools.audio_enable_menu;
6881 bool audio_enable_menu_ok = settings->bools.audio_enable_menu_ok;
6882 #endif
6883 bool menu_insert_disk_resume = settings->bools.menu_insert_disk_resume;
6884
6885 if (!settings)
6886 return menu_cbs_exit();
6887
6888 #ifdef HAVE_AUDIOMIXER
6889 if (audio_enable_menu && audio_enable_menu_ok)
6890 audio_driver_mixer_play_menu_sound(AUDIO_MIXER_SYSTEM_SLOT_OK);
6891 #endif
6892
6893 /* Get disk eject state *before* toggling drive status */
6894 if (sys_info)
6895 disk_ejected = disk_control_get_eject_state(&sys_info->disk_control);
6896
6897 /* Only want to display a notification if we are
6898 * going to resume content immediately after
6899 * inserting a disk (i.e. if quick menu remains
6900 * open, there is sufficient visual feedback
6901 * without a notification) */
6902 print_log = menu_insert_disk_resume && disk_ejected;
6903
6904 if (!command_event(CMD_EVENT_DISK_EJECT_TOGGLE, &print_log))
6905 return menu_cbs_exit();
6906
6907 /* If we reach this point, then tray toggle
6908 * was successful */
6909 disk_ejected = !disk_ejected;
6910
6911 /* If disk is now ejected, menu selection should
6912 * automatically increment to the 'current disk
6913 * index' option */
6914 if (disk_ejected)
6915 menu_navigation_set_selection(1);
6916
6917 /* If disk is now inserted and user has enabled
6918 * 'menu_insert_disk_resume', resume running content */
6919 if (!disk_ejected && menu_insert_disk_resume)
6920 generic_action_ok_command(CMD_EVENT_RESUME);
6921
6922 return 0;
6923 }
6924
action_ok_disk_image_append(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6925 static int action_ok_disk_image_append(const char *path,
6926 const char *label, unsigned type, size_t idx, size_t entry_idx)
6927 {
6928 char image_path[PATH_MAX_LENGTH];
6929 rarch_system_info_t *sys_info = runloop_get_system_info();
6930 menu_handle_t *menu = menu_driver_get_ptr();
6931 const char *menu_path = NULL;
6932 settings_t *settings = config_get_ptr();
6933 #ifdef HAVE_AUDIOMIXER
6934 bool audio_enable_menu = settings->bools.audio_enable_menu;
6935 bool audio_enable_menu_ok = settings->bools.audio_enable_menu_ok;
6936 #endif
6937 bool menu_insert_disk_resume = settings->bools.menu_insert_disk_resume;
6938
6939 image_path[0] = '\0';
6940
6941 if (!menu)
6942 return menu_cbs_exit();
6943
6944 #ifdef HAVE_AUDIOMIXER
6945 if (audio_enable_menu && audio_enable_menu_ok)
6946 audio_driver_mixer_play_menu_sound(AUDIO_MIXER_SYSTEM_SLOT_OK);
6947 #endif
6948
6949 /* Get file path of new disk image */
6950 menu_entries_get_last_stack(&menu_path,
6951 NULL, NULL, NULL, NULL);
6952
6953 if (!string_is_empty(menu_path))
6954 {
6955 if (!string_is_empty(path))
6956 fill_pathname_join(image_path,
6957 menu_path, path, sizeof(image_path));
6958 else
6959 strlcpy(image_path, menu_path, sizeof(image_path));
6960 }
6961
6962 /* Append image */
6963 command_event(CMD_EVENT_DISK_APPEND_IMAGE, image_path);
6964
6965 /* In all cases, return to the disk options menu */
6966 menu_entries_flush_stack(msg_hash_to_str(MENU_ENUM_LABEL_DISK_OPTIONS), 0);
6967
6968 /* > If disk tray is open, reset menu selection to
6969 * the 'insert disk' option
6970 * > If disk try is closed and user has enabled
6971 * 'menu_insert_disk_resume', resume running content */
6972 if (sys_info && disk_control_get_eject_state(&sys_info->disk_control))
6973 menu_navigation_set_selection(0);
6974 else if (menu_insert_disk_resume)
6975 generic_action_ok_command(CMD_EVENT_RESUME);
6976
6977 return 0;
6978 }
6979
action_ok_manual_content_scan_start(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6980 static int action_ok_manual_content_scan_start(const char *path,
6981 const char *label, unsigned type, size_t idx, size_t entry_idx)
6982 {
6983 playlist_config_t playlist_config;
6984 settings_t *settings = config_get_ptr();
6985 const char *directory_playlist = settings->paths.directory_playlist;
6986
6987 /* Note: playlist_config.path will set by the
6988 * task itself */
6989 playlist_config.capacity = COLLECTION_SIZE;
6990 playlist_config.old_format = settings->bools.playlist_use_old_format;
6991 playlist_config.compress = settings->bools.playlist_compression;
6992 playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
6993 playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
6994
6995 task_push_manual_content_scan(&playlist_config, directory_playlist);
6996 return 0;
6997 }
6998
action_ok_netplay_enable_host(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)6999 static int action_ok_netplay_enable_host(const char *path,
7000 const char *label, unsigned type, size_t idx, size_t entry_idx)
7001 {
7002 #ifdef HAVE_NETWORKING
7003 if (command_event(CMD_EVENT_NETPLAY_ENABLE_HOST, NULL))
7004 return generic_action_ok_command(CMD_EVENT_RESUME);
7005 #endif
7006 return -1;
7007 }
7008
7009 #ifdef HAVE_NETWORKING
action_ok_netplay_enable_client_hostname_cb(void * ignore,const char * hostname)7010 static void action_ok_netplay_enable_client_hostname_cb(
7011 void *ignore, const char *hostname)
7012 {
7013
7014 if (hostname && hostname[0])
7015 {
7016 bool contentless = false;
7017 bool is_inited = false;
7018 char *tmp_hostname = strdup(hostname);
7019
7020 content_get_status(&contentless, &is_inited);
7021
7022 if (!is_inited)
7023 {
7024 command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
7025 (void*)tmp_hostname);
7026 runloop_msg_queue_push(
7027 msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED),
7028 1, 480, true,
7029 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
7030 }
7031 else
7032 {
7033 command_event(CMD_EVENT_NETPLAY_INIT_DIRECT,
7034 (void*)tmp_hostname);
7035 generic_action_ok_command(CMD_EVENT_RESUME);
7036 }
7037
7038 free(tmp_hostname);
7039 }
7040 else
7041 {
7042 menu_input_dialog_end();
7043 return;
7044 }
7045
7046 menu_input_dialog_end();
7047 retroarch_menu_running_finished(false);
7048 }
7049 #endif
7050
action_ok_netplay_enable_client(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7051 static int action_ok_netplay_enable_client(const char *path,
7052 const char *label, unsigned type, size_t idx, size_t entry_idx)
7053 {
7054 #ifdef HAVE_NETWORKING
7055 menu_input_ctx_line_t line;
7056 settings_t *settings = config_get_ptr();
7057 const char *netplay_server = settings->paths.netplay_server;
7058
7059 if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
7060 generic_action_ok_command(CMD_EVENT_NETPLAY_DEINIT);
7061 netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
7062
7063 if (!string_is_empty(netplay_server))
7064 {
7065 action_ok_netplay_enable_client_hostname_cb(NULL, netplay_server);
7066 return 0;
7067 }
7068 else
7069 {
7070 line.label = msg_hash_to_str(
7071 MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS);
7072 line.label_setting = "no_setting";
7073 line.type = 0;
7074 line.idx = 0;
7075 line.cb = action_ok_netplay_enable_client_hostname_cb;
7076
7077 if (menu_input_dialog_start(&line))
7078 return 0;
7079 }
7080 #endif
7081 return -1;
7082 }
7083
action_ok_netplay_disconnect(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7084 static int action_ok_netplay_disconnect(const char *path,
7085 const char *label, unsigned type, size_t idx, size_t entry_idx)
7086 {
7087 #ifdef HAVE_NETWORKING
7088 generic_action_ok_command(CMD_EVENT_NETPLAY_DISCONNECT);
7089
7090 return generic_action_ok_command(CMD_EVENT_RESUME);
7091 #else
7092 return -1;
7093 #endif
7094 }
7095
action_ok_core_create_backup(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7096 static int action_ok_core_create_backup(const char *path,
7097 const char *label, unsigned type, size_t idx, size_t entry_idx)
7098 {
7099 const char *core_path = label;
7100 settings_t *settings = config_get_ptr();
7101 unsigned auto_backup_history_size = settings->uints.core_updater_auto_backup_history_size;
7102 const char *dir_core_assets = settings->paths.directory_core_assets;
7103
7104 if (string_is_empty(core_path))
7105 return -1;
7106
7107 task_push_core_backup(core_path, NULL, 0, CORE_BACKUP_MODE_MANUAL,
7108 (size_t)auto_backup_history_size, dir_core_assets, false);
7109
7110 return 0;
7111 }
7112
action_ok_core_restore_backup(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7113 static int action_ok_core_restore_backup(const char *path,
7114 const char *label, unsigned type, size_t idx, size_t entry_idx)
7115 {
7116 const char *backup_path = label;
7117 bool core_loaded = false;
7118 settings_t *settings = config_get_ptr();
7119 const char *dir_libretro = settings->paths.directory_libretro;
7120
7121 if (string_is_empty(backup_path))
7122 return -1;
7123
7124 /* If core to be restored is currently loaded, the task
7125 * will unload it
7126 * > In this case, must flush the menu stack
7127 * (otherwise user will be faced with 'no information
7128 * available' when popping the stack - this would be
7129 * confusing/ugly) */
7130 if (task_push_core_restore(backup_path, dir_libretro, &core_loaded) &&
7131 core_loaded)
7132 menu_entries_flush_stack(NULL, 0);
7133
7134 return 0;
7135 }
7136
action_ok_core_delete_backup(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7137 static int action_ok_core_delete_backup(const char *path,
7138 const char *label, unsigned type, size_t idx, size_t entry_idx)
7139 {
7140 const char *backup_path = label;
7141 bool refresh = false;
7142
7143 if (string_is_empty(backup_path))
7144 return -1;
7145
7146 /* Delete backup file (if it exists) */
7147 if (path_is_valid(backup_path))
7148 filestream_delete(backup_path);
7149
7150 /* Refresh menu */
7151 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
7152 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
7153
7154 return 0;
7155 }
7156
7157 /* Do not declare this static - it is also used
7158 * in menu_cbs_left.c and menu_cbs_right.c */
action_ok_core_lock(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7159 int action_ok_core_lock(const char *path,
7160 const char *label, unsigned type, size_t idx, size_t entry_idx)
7161 {
7162 const char *core_path = path;
7163 bool lock = false;
7164 bool refresh = false;
7165 int ret = 0;
7166
7167 if (string_is_empty(core_path))
7168 return -1;
7169
7170 /* Simply toggle current lock status */
7171 lock = !core_info_get_core_lock(core_path, true);
7172
7173 if (!core_info_set_core_lock(core_path, lock))
7174 {
7175 const char *core_name = NULL;
7176 core_info_t *core_info = NULL;
7177 char msg[PATH_MAX_LENGTH];
7178
7179 msg[0] = '\0';
7180
7181 /* Need to fetch core name for error message */
7182
7183 /* If core is found, use display name */
7184 if (core_info_find(core_path, &core_info) &&
7185 core_info->display_name)
7186 core_name = core_info->display_name;
7187 /* If not, use core file name */
7188 else
7189 core_name = path_basename_nocompression(core_path);
7190
7191 /* Build error message */
7192 strlcpy(
7193 msg,
7194 msg_hash_to_str(lock ?
7195 MSG_CORE_LOCK_FAILED : MSG_CORE_UNLOCK_FAILED),
7196 sizeof(msg));
7197
7198 if (!string_is_empty(core_name))
7199 strlcat(msg, core_name, sizeof(msg));
7200
7201 /* Generate log + notification */
7202 RARCH_ERR("%s\n", msg);
7203
7204 runloop_msg_queue_push(
7205 msg,
7206 1, 100, true,
7207 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
7208
7209 ret = -1;
7210 }
7211
7212 /* Whenever lock status is changed, menu must be
7213 * refreshed - do this even in the event of an error,
7214 * since we don't want to leave the menu in an
7215 * undefined state */
7216 menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
7217 menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
7218
7219 return ret;
7220 }
7221
action_ok_core_delete(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7222 static int action_ok_core_delete(const char *path,
7223 const char *label, unsigned type, size_t idx, size_t entry_idx)
7224 {
7225 const char *core_path = label;
7226
7227 if (string_is_empty(core_path))
7228 return -1;
7229
7230 /* Check whether core is locked */
7231 if (core_info_get_core_lock(core_path, true))
7232 {
7233 const char *core_name = NULL;
7234 core_info_t *core_info = NULL;
7235 char msg[PATH_MAX_LENGTH];
7236
7237 msg[0] = '\0';
7238
7239 /* Need to fetch core name for notification */
7240
7241 /* If core is found, use display name */
7242 if (core_info_find(core_path, &core_info) &&
7243 core_info->display_name)
7244 core_name = core_info->display_name;
7245 /* If not, use core file name */
7246 else
7247 core_name = path_basename_nocompression(core_path);
7248
7249 /* Build notification message */
7250 strlcpy(msg, msg_hash_to_str(MSG_CORE_DELETE_DISABLED), sizeof(msg));
7251
7252 if (!string_is_empty(core_name))
7253 strlcat(msg, core_name, sizeof(msg));
7254
7255 runloop_msg_queue_push(
7256 msg,
7257 1, 100, true,
7258 NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
7259
7260 /* We do not consider this an 'error' - we are
7261 * merely telling the user that this operation
7262 * is not currently supported */
7263 return 0;
7264 }
7265
7266 /* Check if core to be deleted is currently
7267 * loaded - if so, unload it */
7268 if (rarch_ctl(RARCH_CTL_IS_CORE_LOADED, (void*)core_path))
7269 generic_action_ok_command(CMD_EVENT_UNLOAD_CORE);
7270
7271 /* Delete core file */
7272 #if defined(ANDROID)
7273 /* If this is a Play Store build and the
7274 * core is currently installed via
7275 * play feature delivery, must delete
7276 * the core via the play feature delivery
7277 * interface */
7278 if (play_feature_delivery_enabled())
7279 {
7280 const char *core_filename = path_basename_nocompression(core_path);
7281 char backup_core_path[PATH_MAX_LENGTH];
7282
7283 backup_core_path[0] = '\0';
7284
7285 if (play_feature_delivery_core_installed(core_filename))
7286 play_feature_delivery_delete(core_filename);
7287 else
7288 filestream_delete(core_path);
7289
7290 /* When installing cores via play feature
7291 * delivery, there is a low probability of
7292 * backup core files being left behind if
7293 * something interrupts the install process
7294 * (i.e. a crash or user exit while the
7295 * install task is running). To prevent the
7296 * accumulation of mess, additionally check
7297 * for and remove any such backups when deleting
7298 * a core */
7299 strlcpy(backup_core_path, core_path,
7300 sizeof(backup_core_path));
7301 strlcat(backup_core_path, FILE_PATH_BACKUP_EXTENSION,
7302 sizeof(backup_core_path));
7303
7304 if (!string_is_empty(backup_core_path) &&
7305 path_is_valid(backup_core_path))
7306 filestream_delete(backup_core_path);
7307 }
7308 else
7309 #endif
7310 filestream_delete(core_path);
7311
7312 /* Reload core info files */
7313 command_event(CMD_EVENT_CORE_INFO_INIT, NULL);
7314
7315 /* Return to higher level menu */
7316 return action_cancel_pop_default(NULL, NULL, 0, 0);
7317 }
7318
action_ok_delete_playlist(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7319 static int action_ok_delete_playlist(const char *path,
7320 const char *label, unsigned type, size_t idx, size_t entry_idx)
7321 {
7322 playlist_t *playlist = playlist_get_cached();
7323 menu_ctx_environment_t menu_environ;
7324
7325 if (!playlist)
7326 return -1;
7327
7328 menu_environ.type = MENU_ENVIRON_NONE;
7329 menu_environ.data = NULL;
7330
7331 path = playlist_get_conf_path(playlist);
7332
7333 filestream_delete(path);
7334
7335 menu_environ.type = MENU_ENVIRON_RESET_HORIZONTAL_LIST;
7336
7337 menu_driver_ctl(RARCH_MENU_CTL_ENVIRONMENT, &menu_environ);
7338
7339 return action_cancel_pop_default(NULL, NULL, 0, 0);
7340 }
7341
action_ok_pl_content_thumbnails(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7342 static int action_ok_pl_content_thumbnails(const char *path,
7343 const char *label, unsigned type, size_t idx, size_t entry_idx)
7344 {
7345 #ifdef HAVE_NETWORKING
7346 settings_t *settings = config_get_ptr();
7347
7348 if (settings)
7349 {
7350 playlist_config_t playlist_config;
7351 const char *path_dir_playlist = settings->paths.directory_playlist;
7352 const char *path_dir_thumbnails = settings->paths.directory_thumbnails;
7353
7354 playlist_config.capacity = COLLECTION_SIZE;
7355 playlist_config.old_format = settings->bools.playlist_use_old_format;
7356 playlist_config.compress = settings->bools.playlist_compression;
7357 playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
7358
7359 if (!string_is_empty(path_dir_playlist))
7360 {
7361 char playlist_path[PATH_MAX_LENGTH];
7362 playlist_path[0] = '\0';
7363
7364 fill_pathname_join(
7365 playlist_path, path_dir_playlist, label,
7366 sizeof(playlist_path));
7367 playlist_config_set_path(&playlist_config, playlist_path);
7368
7369 task_push_pl_thumbnail_download(path, &playlist_config,
7370 path_dir_thumbnails);
7371
7372 return 0;
7373 }
7374 }
7375 #endif
7376 return -1;
7377 }
7378
7379 #ifdef HAVE_NETWORKING
action_ok_pl_entry_content_thumbnails(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7380 static int action_ok_pl_entry_content_thumbnails(const char *path,
7381 const char *label, unsigned type, size_t idx, size_t entry_idx)
7382 {
7383 char system[PATH_MAX_LENGTH];
7384 playlist_t *playlist = playlist_get_cached();
7385 menu_handle_t *menu = menu_driver_get_ptr();
7386
7387 system[0] = '\0';
7388
7389 if (!playlist)
7390 return -1;
7391
7392 if (!menu)
7393 return menu_cbs_exit();
7394
7395 menu_driver_get_thumbnail_system(system, sizeof(system));
7396
7397 task_push_pl_entry_thumbnail_download(system,
7398 playlist, menu->rpl_entry_selection_ptr,
7399 true, false);
7400
7401 return 0;
7402 }
7403 #endif
7404
action_ok_playlist_reset_cores(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7405 static int action_ok_playlist_reset_cores(const char *path,
7406 const char *label, unsigned type, size_t idx, size_t entry_idx)
7407 {
7408 playlist_t *playlist = playlist_get_cached();
7409 playlist_config_t *playlist_config = NULL;
7410
7411 if (!playlist)
7412 return -1;
7413
7414 playlist_config = playlist_get_config(playlist);
7415
7416 if (!playlist_config || string_is_empty(playlist_config->path))
7417 return -1;
7418
7419 task_push_pl_manager_reset_cores(playlist_config);
7420
7421 return 0;
7422 }
7423
action_ok_playlist_clean(const char * path,const char * label,unsigned type,size_t idx,size_t entry_idx)7424 static int action_ok_playlist_clean(const char *path,
7425 const char *label, unsigned type, size_t idx, size_t entry_idx)
7426 {
7427 playlist_t *playlist = playlist_get_cached();
7428 playlist_config_t *playlist_config = NULL;
7429
7430 if (!playlist)
7431 return -1;
7432
7433 playlist_config = playlist_get_config(playlist);
7434
7435 if (!playlist_config || string_is_empty(playlist_config->path))
7436 return -1;
7437
7438 task_push_pl_manager_clean_playlist(playlist_config);
7439
7440 return 0;
7441 }
7442
is_rdb_entry(enum msg_hash_enums enum_idx)7443 static int is_rdb_entry(enum msg_hash_enums enum_idx)
7444 {
7445 switch (enum_idx)
7446 {
7447 case MENU_ENUM_LABEL_RDB_ENTRY_PUBLISHER:
7448 case MENU_ENUM_LABEL_RDB_ENTRY_DEVELOPER:
7449 case MENU_ENUM_LABEL_RDB_ENTRY_ORIGIN:
7450 case MENU_ENUM_LABEL_RDB_ENTRY_FRANCHISE:
7451 case MENU_ENUM_LABEL_RDB_ENTRY_ENHANCEMENT_HW:
7452 case MENU_ENUM_LABEL_RDB_ENTRY_ESRB_RATING:
7453 case MENU_ENUM_LABEL_RDB_ENTRY_BBFC_RATING:
7454 case MENU_ENUM_LABEL_RDB_ENTRY_ELSPA_RATING:
7455 case MENU_ENUM_LABEL_RDB_ENTRY_PEGI_RATING:
7456 case MENU_ENUM_LABEL_RDB_ENTRY_CERO_RATING:
7457 case MENU_ENUM_LABEL_RDB_ENTRY_EDGE_MAGAZINE_RATING:
7458 case MENU_ENUM_LABEL_RDB_ENTRY_EDGE_MAGAZINE_ISSUE:
7459 case MENU_ENUM_LABEL_RDB_ENTRY_FAMITSU_MAGAZINE_RATING:
7460 case MENU_ENUM_LABEL_RDB_ENTRY_RELEASE_MONTH:
7461 case MENU_ENUM_LABEL_RDB_ENTRY_RELEASE_YEAR:
7462 case MENU_ENUM_LABEL_RDB_ENTRY_MAX_USERS:
7463 break;
7464 default:
7465 return -1;
7466 }
7467
7468 return 0;
7469 }
7470
menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t * cbs,const char * label)7471 static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
7472 const char *label)
7473 {
7474 if (cbs->enum_idx != MSG_UNKNOWN)
7475 {
7476 const char *str = msg_hash_to_str(cbs->enum_idx);
7477
7478 if (str)
7479 {
7480 if (is_rdb_entry(cbs->enum_idx) == 0)
7481 {
7482 BIND_ACTION_OK(cbs, action_ok_rdb_entry_submenu);
7483 return 0;
7484 }
7485
7486 if (string_ends_with_size(str, "input_binds_list",
7487 strlen(str),
7488 STRLEN_CONST("input_binds_list")))
7489 {
7490 unsigned i;
7491
7492 for (i = 0; i < MAX_USERS; i++)
7493 {
7494 unsigned first_char = atoi(&str[0]);
7495
7496 if (first_char != ((i+1)))
7497 continue;
7498
7499 BIND_ACTION_OK(cbs, action_ok_push_user_binds_list);
7500 return 0;
7501 }
7502 }
7503 }
7504 }
7505
7506 if (menu_setting_get_browser_selection_type(cbs->setting) == ST_DIR)
7507 {
7508 BIND_ACTION_OK(cbs, action_ok_push_filebrowser_list_dir_select);
7509 return 0;
7510 }
7511
7512 if (cbs->enum_idx != MSG_UNKNOWN)
7513 {
7514 unsigned i;
7515 typedef struct temp_ok_list
7516 {
7517 enum msg_hash_enums type;
7518 int (*cb)(const char *path, const char *label, unsigned type,
7519 size_t idx, size_t entry_idx);
7520 } temp_ok_list_t;
7521
7522 temp_ok_list_t ok_list[] = {
7523 {MENU_ENUM_LABEL_QUICK_MENU_START_RECORDING, action_ok_start_recording},
7524 {MENU_ENUM_LABEL_QUICK_MENU_START_STREAMING, action_ok_start_streaming},
7525 {MENU_ENUM_LABEL_QUICK_MENU_STOP_RECORDING, action_ok_stop_recording},
7526 {MENU_ENUM_LABEL_QUICK_MENU_STOP_STREAMING, action_ok_stop_streaming},
7527 #ifdef HAVE_CHEATS
7528 {MENU_ENUM_LABEL_CHEAT_START_OR_CONT, action_ok_cheat_start_or_cont},
7529 {MENU_ENUM_LABEL_CHEAT_ADD_NEW_TOP, action_ok_cheat_add_top},
7530 {MENU_ENUM_LABEL_CHEAT_RELOAD_CHEATS, action_ok_cheat_reload_cheats},
7531 {MENU_ENUM_LABEL_CHEAT_ADD_NEW_BOTTOM, action_ok_cheat_add_bottom},
7532 {MENU_ENUM_LABEL_CHEAT_DELETE_ALL, action_ok_cheat_delete_all},
7533 {MENU_ENUM_LABEL_CHEAT_ADD_NEW_AFTER, action_ok_cheat_add_new_after},
7534 {MENU_ENUM_LABEL_CHEAT_ADD_NEW_BEFORE, action_ok_cheat_add_new_before},
7535 {MENU_ENUM_LABEL_CHEAT_COPY_AFTER, action_ok_cheat_copy_after},
7536 {MENU_ENUM_LABEL_CHEAT_COPY_BEFORE, action_ok_cheat_copy_before},
7537 {MENU_ENUM_LABEL_CHEAT_DELETE, action_ok_cheat_delete},
7538 #endif
7539 {MENU_ENUM_LABEL_RUN_MUSIC, action_ok_audio_run},
7540 #ifdef HAVE_AUDIOMIXER
7541 {MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION, action_ok_audio_add_to_mixer_and_collection},
7542 {MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION_AND_PLAY,action_ok_audio_add_to_mixer_and_collection_and_play},
7543 {MENU_ENUM_LABEL_ADD_TO_MIXER, action_ok_audio_add_to_mixer},
7544 {MENU_ENUM_LABEL_ADD_TO_MIXER_AND_PLAY, action_ok_audio_add_to_mixer_and_play},
7545 #endif
7546 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
7547 {MENU_ENUM_LABEL_VIDEO_SHADER_PASS, action_ok_shader_pass},
7548 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET, action_ok_shader_preset},
7549 {MENU_ENUM_LABEL_VIDEO_SHADER_PARAMETERS, action_ok_shader_parameters},
7550 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_PARAMETERS, action_ok_shader_parameters},
7551 {MENU_ENUM_LABEL_SHADER_APPLY_CHANGES, action_ok_shader_apply_changes},
7552 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_REMOVE, action_ok_shader_preset_remove},
7553 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE, action_ok_shader_preset_save},
7554 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_AS, action_ok_shader_preset_save_as},
7555 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_GLOBAL, action_ok_shader_preset_save_global},
7556 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_CORE, action_ok_shader_preset_save_core},
7557 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_PARENT, action_ok_shader_preset_save_parent},
7558 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_GAME, action_ok_shader_preset_save_game},
7559 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_REMOVE_GLOBAL, action_ok_shader_preset_remove_global},
7560 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_REMOVE_CORE, action_ok_shader_preset_remove_core},
7561 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_REMOVE_PARENT, action_ok_shader_preset_remove_parent},
7562 {MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_REMOVE_GAME, action_ok_shader_preset_remove_game},
7563 {MENU_ENUM_LABEL_UPDATE_GLSL_SHADERS, action_ok_update_shaders_glsl},
7564 {MENU_ENUM_LABEL_UPDATE_CG_SHADERS, action_ok_update_shaders_cg},
7565 {MENU_ENUM_LABEL_UPDATE_SLANG_SHADERS, action_ok_update_shaders_slang},
7566 #endif
7567 #ifdef HAVE_AUDIOMIXER
7568 {MENU_ENUM_LABEL_AUDIO_MIXER_SETTINGS, action_ok_push_audio_mixer_settings_list},
7569 #endif
7570 #ifdef HAVE_NETWORKING
7571 {MENU_ENUM_LABEL_DOWNLOAD_CORE_CONTENT, action_ok_core_content_list},
7572 {MENU_ENUM_LABEL_DOWNLOAD_CORE_CONTENT_DIRS, action_ok_core_content_dirs_list},
7573 {MENU_ENUM_LABEL_CORE_UPDATER_LIST, action_ok_core_updater_list},
7574 {MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES, action_ok_update_installed_cores},
7575 #if defined(ANDROID)
7576 {MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD, action_ok_switch_installed_cores_pfd},
7577 #endif
7578 {MENU_ENUM_LABEL_THUMBNAILS_UPDATER_LIST, action_ok_thumbnails_updater_list},
7579 {MENU_ENUM_LABEL_PL_THUMBNAILS_UPDATER_LIST, action_ok_pl_thumbnails_updater_list},
7580 {MENU_ENUM_LABEL_DOWNLOAD_PL_ENTRY_THUMBNAILS, action_ok_pl_entry_content_thumbnails},
7581 {MENU_ENUM_LABEL_UPDATE_LAKKA, action_ok_lakka_list},
7582 {MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS, action_ok_push_netplay_refresh_rooms},
7583 #endif
7584 #ifdef HAVE_VIDEO_LAYOUT
7585 {MENU_ENUM_LABEL_ONSCREEN_VIDEO_LAYOUT_SETTINGS, action_ok_onscreen_video_layout_list},
7586 #endif
7587 #ifdef HAVE_LAKKA_SWITCH
7588 {MENU_ENUM_LABEL_SWITCH_GPU_PROFILE, action_ok_push_default},
7589 #endif
7590 #if defined(HAVE_LAKKA_SWITCH) || defined(HAVE_LIBNX)
7591 {MENU_ENUM_LABEL_SWITCH_CPU_PROFILE, action_ok_push_default},
7592 #endif
7593 {MENU_ENUM_LABEL_MENU_WALLPAPER, action_ok_menu_wallpaper},
7594 {MENU_ENUM_LABEL_VIDEO_FONT_PATH, action_ok_video_font},
7595 {MENU_ENUM_LABEL_GOTO_FAVORITES, action_ok_goto_favorites},
7596 {MENU_ENUM_LABEL_GOTO_MUSIC, action_ok_goto_music},
7597 {MENU_ENUM_LABEL_GOTO_IMAGES, action_ok_goto_images},
7598 {MENU_ENUM_LABEL_GOTO_VIDEO, action_ok_goto_video},
7599 {MENU_ENUM_LABEL_GOTO_EXPLORE, action_ok_goto_explore},
7600 {MENU_ENUM_LABEL_BROWSE_START, action_ok_browse_url_start},
7601 {MENU_ENUM_LABEL_FILE_BROWSER_CORE, action_ok_load_core},
7602 {MENU_ENUM_LABEL_FILE_BROWSER_CORE_SELECT_FROM_COLLECTION, action_ok_core_deferred_set},
7603 {MENU_ENUM_LABEL_FILE_BROWSER_CORE_SELECT_FROM_COLLECTION_CURRENT_CORE,action_ok_core_deferred_set},
7604 {MENU_ENUM_LABEL_START_CORE, action_ok_start_core},
7605 {MENU_ENUM_LABEL_START_NET_RETROPAD, action_ok_start_net_retropad_core},
7606 {MENU_ENUM_LABEL_START_GONG, action_ok_start_gong_core},
7607 {MENU_ENUM_LABEL_START_VIDEO_PROCESSOR, action_ok_start_video_processor_core},
7608 {MENU_ENUM_LABEL_OPEN_ARCHIVE_DETECT_CORE, action_ok_open_archive_detect_core},
7609 {MENU_ENUM_LABEL_OPEN_ARCHIVE, action_ok_open_archive},
7610 {MENU_ENUM_LABEL_LOAD_ARCHIVE_DETECT_CORE, action_ok_load_archive_detect_core},
7611 {MENU_ENUM_LABEL_LOAD_ARCHIVE, action_ok_load_archive},
7612 {MENU_ENUM_LABEL_CUSTOM_BIND_ALL, action_ok_lookup_setting},
7613 {MENU_ENUM_LABEL_SAVE_STATE, action_ok_save_state},
7614 {MENU_ENUM_LABEL_LOAD_STATE, action_ok_load_state},
7615 {MENU_ENUM_LABEL_UNDO_LOAD_STATE, action_ok_undo_load_state},
7616 {MENU_ENUM_LABEL_UNDO_SAVE_STATE, action_ok_undo_save_state},
7617 {MENU_ENUM_LABEL_RESUME_CONTENT, action_ok_resume_content},
7618 {MENU_ENUM_LABEL_ADD_TO_FAVORITES_PLAYLIST, action_ok_add_to_favorites_playlist},
7619 {MENU_ENUM_LABEL_SET_CORE_ASSOCIATION, action_ok_set_core_association},
7620 {MENU_ENUM_LABEL_RESET_CORE_ASSOCIATION, action_ok_reset_core_association},
7621 {MENU_ENUM_LABEL_ADD_TO_FAVORITES, action_ok_add_to_favorites},
7622 {MENU_ENUM_LABEL_RESTART_CONTENT, action_ok_restart_content},
7623 {MENU_ENUM_LABEL_TAKE_SCREENSHOT, action_ok_screenshot},
7624 {MENU_ENUM_LABEL_RENAME_ENTRY, action_ok_rename_entry},
7625 {MENU_ENUM_LABEL_DELETE_ENTRY, action_ok_delete_entry},
7626 {MENU_ENUM_LABEL_MENU_DISABLE_KIOSK_MODE, action_ok_disable_kiosk_mode},
7627 {MENU_ENUM_LABEL_XMB_MAIN_MENU_ENABLE_SETTINGS, action_ok_enable_settings},
7628 {MENU_ENUM_LABEL_SHOW_WIMP, action_ok_show_wimp},
7629 {MENU_ENUM_LABEL_QUIT_RETROARCH, action_ok_quit},
7630 {MENU_ENUM_LABEL_CLOSE_CONTENT, action_ok_close_content},
7631 {MENU_ENUM_LABEL_SAVE_NEW_CONFIG, action_ok_save_new_config},
7632 {MENU_ENUM_LABEL_HELP, action_ok_help},
7633 {MENU_ENUM_LABEL_HELP_CONTROLS, action_ok_help_controls},
7634 {MENU_ENUM_LABEL_HELP_WHAT_IS_A_CORE, action_ok_help_what_is_a_core},
7635 {MENU_ENUM_LABEL_HELP_CHANGE_VIRTUAL_GAMEPAD, action_ok_help_change_virtual_gamepad},
7636 {MENU_ENUM_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING, action_ok_help_audio_video_troubleshooting},
7637 {MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO, action_ok_help_send_debug_info},
7638 {MENU_ENUM_LABEL_HELP_SCANNING_CONTENT, action_ok_help_scanning_content},
7639 {MENU_ENUM_LABEL_HELP_LOADING_CONTENT, action_ok_help_load_content},
7640 #ifdef HAVE_CHEATS
7641 {MENU_ENUM_LABEL_CHEAT_FILE_LOAD, action_ok_cheat_file},
7642 {MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND, action_ok_cheat_file_append},
7643 {MENU_ENUM_LABEL_UPDATE_CHEATS, action_ok_update_cheats},
7644 {MENU_ENUM_LABEL_CHEAT_ADD_MATCHES, cheat_manager_add_matches},
7645 #endif
7646 {MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN, action_ok_audio_dsp_plugin},
7647 {MENU_ENUM_LABEL_VIDEO_FILTER, action_ok_video_filter},
7648 {MENU_ENUM_LABEL_OVERLAY_PRESET, action_ok_overlay_preset},
7649 #if defined(HAVE_VIDEO_LAYOUT)
7650 {MENU_ENUM_LABEL_VIDEO_LAYOUT_PATH, action_ok_video_layout},
7651 #endif
7652 {MENU_ENUM_LABEL_REMAP_FILE_LOAD, action_ok_remap_file},
7653 {MENU_ENUM_LABEL_RECORD_CONFIG, action_ok_record_configfile},
7654 {MENU_ENUM_LABEL_STREAM_CONFIG, action_ok_stream_configfile},
7655 #ifdef HAVE_RGUI
7656 {MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET, action_ok_rgui_menu_theme_preset},
7657 #endif
7658 {MENU_ENUM_LABEL_ACCOUNTS_LIST, action_ok_push_accounts_list},
7659 {MENU_ENUM_LABEL_ACCESSIBILITY_SETTINGS, action_ok_push_accessibility_settings_list},
7660 {MENU_ENUM_LABEL_AI_SERVICE_SETTINGS, action_ok_push_ai_service_settings_list},
7661 {MENU_ENUM_LABEL_INPUT_SETTINGS, action_ok_push_input_settings_list},
7662 {MENU_ENUM_LABEL_INPUT_MENU_SETTINGS, action_ok_push_input_menu_settings_list},
7663 {MENU_ENUM_LABEL_INPUT_TURBO_FIRE_SETTINGS, action_ok_push_input_turbo_fire_settings_list},
7664 {MENU_ENUM_LABEL_INPUT_HAPTIC_FEEDBACK_SETTINGS, action_ok_push_input_haptic_feedback_settings_list},
7665 {MENU_ENUM_LABEL_DRIVER_SETTINGS, action_ok_push_driver_settings_list},
7666 {MENU_ENUM_LABEL_VIDEO_SETTINGS, action_ok_push_video_settings_list},
7667 {MENU_ENUM_LABEL_VIDEO_SYNCHRONIZATION_SETTINGS, action_ok_push_video_synchronization_settings_list},
7668 {MENU_ENUM_LABEL_VIDEO_FULLSCREEN_MODE_SETTINGS, action_ok_push_video_fullscreen_mode_settings_list},
7669 {MENU_ENUM_LABEL_VIDEO_WINDOWED_MODE_SETTINGS, action_ok_push_video_windowed_mode_settings_list},
7670 {MENU_ENUM_LABEL_VIDEO_SCALING_SETTINGS, action_ok_push_video_scaling_settings_list},
7671 {MENU_ENUM_LABEL_VIDEO_OUTPUT_SETTINGS, action_ok_push_video_output_settings_list},
7672 {MENU_ENUM_LABEL_CRT_SWITCHRES_SETTINGS, action_ok_push_crt_switchres_settings_list},
7673 {MENU_ENUM_LABEL_AUDIO_SETTINGS, action_ok_push_audio_settings_list},
7674 {MENU_ENUM_LABEL_AUDIO_SYNCHRONIZATION_SETTINGS, action_ok_push_audio_synchronization_settings_list},
7675 {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR, action_ok_push_manual_content_scan_dir_select},
7676 {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME, action_ok_manual_content_scan_system_name},
7677 {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME, action_ok_manual_content_scan_core_name},
7678 {MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES, action_ok_video_shader_num_passes_dropdown_box_list},
7679 {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DAT_FILE, action_ok_manual_content_scan_dat_file},
7680 {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_START, action_ok_manual_content_scan_start},
7681 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE, action_ok_playlist_label_display_mode},
7682 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_RIGHT_THUMBNAIL_MODE,action_ok_playlist_right_thumbnail_mode},
7683 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE,action_ok_playlist_left_thumbnail_mode},
7684 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE, action_ok_playlist_sort_mode},
7685 {MENU_ENUM_LABEL_UPDATE_ASSETS, action_ok_update_assets},
7686 {MENU_ENUM_LABEL_UPDATE_CORE_INFO_FILES, action_ok_update_core_info_files},
7687 {MENU_ENUM_LABEL_UPDATE_OVERLAYS, action_ok_update_overlays},
7688 {MENU_ENUM_LABEL_UPDATE_DATABASES, action_ok_update_databases},
7689 {MENU_ENUM_LABEL_UPDATE_AUTOCONFIG_PROFILES, action_ok_update_autoconfig_profiles},
7690 {MENU_ENUM_LABEL_NETPLAY_ENABLE_HOST, action_ok_netplay_enable_host},
7691 {MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT, action_ok_netplay_enable_client},
7692 {MENU_ENUM_LABEL_NETPLAY_DISCONNECT, action_ok_netplay_disconnect},
7693 {MENU_ENUM_LABEL_CORE_DELETE, action_ok_core_delete},
7694 {MENU_ENUM_LABEL_CORE_CREATE_BACKUP, action_ok_core_create_backup},
7695 {MENU_ENUM_LABEL_DELETE_PLAYLIST, action_ok_delete_playlist},
7696 {MENU_ENUM_LABEL_ACHIEVEMENT_PAUSE_MENU, action_ok_push_default},
7697 {MENU_ENUM_LABEL_ACHIEVEMENT_PAUSE, action_ok_cheevos_toggle_hardcore_mode},
7698 {MENU_ENUM_LABEL_ACHIEVEMENT_PAUSE_CANCEL, action_ok_close_submenu},
7699 {MENU_ENUM_LABEL_ACHIEVEMENT_RESUME, action_ok_cheevos_toggle_hardcore_mode},
7700 {MENU_ENUM_LABEL_ACHIEVEMENT_RESUME_CANCEL, action_ok_close_submenu },
7701 {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST, action_ok_push_manual_content_scan_list},
7702 {MENU_ENUM_LABEL_AUDIO_OUTPUT_SETTINGS, action_ok_push_audio_output_settings_list},
7703 {MENU_ENUM_LABEL_AUDIO_RESAMPLER_SETTINGS, action_ok_push_audio_resampler_settings_list},
7704 {MENU_ENUM_LABEL_LATENCY_SETTINGS, action_ok_push_latency_settings_list},
7705 {MENU_ENUM_LABEL_CORE_SETTINGS, action_ok_push_core_settings_list},
7706 {MENU_ENUM_LABEL_CORE_INFORMATION, action_ok_push_core_information_list},
7707 {MENU_ENUM_LABEL_CORE_MANAGER_ENTRY, action_ok_push_core_information_list},
7708 {MENU_ENUM_LABEL_CORE_RESTORE_BACKUP_LIST, action_ok_push_core_restore_backup_list},
7709 {MENU_ENUM_LABEL_CORE_DELETE_BACKUP_LIST, action_ok_push_core_delete_backup_list},
7710 {MENU_ENUM_LABEL_CONFIGURATION_SETTINGS, action_ok_push_configuration_settings_list},
7711 {MENU_ENUM_LABEL_PLAYLIST_SETTINGS, action_ok_push_playlist_settings_list},
7712 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_LIST, action_ok_push_playlist_manager_list},
7713 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_SETTINGS, action_ok_push_playlist_manager_settings},
7714 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_RESET_CORES, action_ok_playlist_reset_cores},
7715 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_CLEAN_PLAYLIST, action_ok_playlist_clean},
7716 {MENU_ENUM_LABEL_RECORDING_SETTINGS, action_ok_push_recording_settings_list},
7717 {MENU_ENUM_LABEL_INPUT_HOTKEY_BINDS, action_ok_push_input_hotkey_binds_list},
7718 {MENU_ENUM_LABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, action_ok_push_accounts_cheevos_list},
7719 {MENU_ENUM_LABEL_ACCOUNTS_YOUTUBE, action_ok_push_accounts_youtube_list},
7720 {MENU_ENUM_LABEL_ACCOUNTS_TWITCH, action_ok_push_accounts_twitch_list},
7721 {MENU_ENUM_LABEL_ACCOUNTS_FACEBOOK, action_ok_push_accounts_facebook_list},
7722 {MENU_ENUM_LABEL_DUMP_DISC, action_ok_push_dump_disc_list},
7723 {MENU_ENUM_LABEL_LOAD_DISC, action_ok_push_load_disc_list},
7724 {MENU_ENUM_LABEL_SHADER_OPTIONS, action_ok_push_default},
7725 {MENU_ENUM_LABEL_CORE_OPTIONS, action_ok_push_default},
7726 {MENU_ENUM_LABEL_CORE_OPTION_OVERRIDE_LIST, action_ok_push_core_option_override_list},
7727 {MENU_ENUM_LABEL_CORE_CHEAT_OPTIONS, action_ok_push_default},
7728 {MENU_ENUM_LABEL_CORE_INPUT_REMAPPING_OPTIONS, action_ok_push_default},
7729 {MENU_ENUM_LABEL_DISC_INFORMATION, action_ok_push_default},
7730 {MENU_ENUM_LABEL_SYSTEM_INFORMATION, action_ok_push_default},
7731 {MENU_ENUM_LABEL_NETWORK_INFORMATION, action_ok_push_default},
7732 {MENU_ENUM_LABEL_ACHIEVEMENT_LIST, action_ok_push_default},
7733 {MENU_ENUM_LABEL_ACHIEVEMENT_LIST_HARDCORE, action_ok_push_default},
7734 {MENU_ENUM_LABEL_DISK_OPTIONS, action_ok_push_default},
7735 {MENU_ENUM_LABEL_SETTINGS, action_ok_push_default},
7736 {MENU_ENUM_LABEL_FRONTEND_COUNTERS, action_ok_push_default},
7737 {MENU_ENUM_LABEL_CORE_COUNTERS, action_ok_push_default},
7738 {MENU_ENUM_LABEL_MANAGEMENT, action_ok_push_default},
7739 {MENU_ENUM_LABEL_ONLINE_UPDATER, action_ok_push_default},
7740 {MENU_ENUM_LABEL_NETPLAY, action_ok_push_default},
7741 {MENU_ENUM_LABEL_LOAD_CONTENT_LIST, action_ok_push_default},
7742 {MENU_ENUM_LABEL_ADD_CONTENT_LIST, action_ok_push_default},
7743 {MENU_ENUM_LABEL_CONFIGURATIONS_LIST, action_ok_push_default},
7744 {MENU_ENUM_LABEL_HELP_LIST, action_ok_push_default},
7745 {MENU_ENUM_LABEL_INFORMATION_LIST, action_ok_push_default},
7746 {MENU_ENUM_LABEL_INFORMATION, action_ok_push_default},
7747 {MENU_ENUM_LABEL_CONTENT_SETTINGS, action_ok_push_default},
7748 {MENU_ENUM_LABEL_LOAD_CONTENT_SPECIAL, action_ok_push_filebrowser_list_file_select},
7749 {MENU_ENUM_LABEL_SCAN_DIRECTORY, action_ok_scan_directory_list},
7750 {MENU_ENUM_LABEL_SCAN_FILE, action_ok_push_scan_file},
7751 {MENU_ENUM_LABEL_FAVORITES, action_ok_push_content_list},
7752 {MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR, action_ok_push_random_dir},
7753 {MENU_ENUM_LABEL_DOWNLOADED_FILE_DETECT_CORE_LIST, action_ok_push_downloads_dir},
7754 {MENU_ENUM_LABEL_DETECT_CORE_LIST_OK, action_ok_file_load_detect_core},
7755 {MENU_ENUM_LABEL_DETECT_CORE_LIST_OK_CURRENT_CORE, action_ok_file_load_current_core},
7756 {MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY, action_ok_push_generic_list},
7757 {MENU_ENUM_LABEL_CURSOR_MANAGER_LIST, action_ok_push_generic_list},
7758 {MENU_ENUM_LABEL_DATABASE_MANAGER_LIST, action_ok_push_generic_list},
7759 #ifdef HAVE_CHEATS
7760 {MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES, action_ok_cheat_apply_changes},
7761 {MENU_ENUM_LABEL_CHEAT_FILE_SAVE_AS, action_ok_cheat_file_save_as},
7762 #endif
7763 {MENU_ENUM_LABEL_REMAP_FILE_SAVE_CORE, action_ok_remap_file_save_core},
7764 {MENU_ENUM_LABEL_REMAP_FILE_SAVE_CONTENT_DIR, action_ok_remap_file_save_content_dir},
7765 {MENU_ENUM_LABEL_REMAP_FILE_SAVE_GAME, action_ok_remap_file_save_game},
7766 {MENU_ENUM_LABEL_REMAP_FILE_REMOVE_CORE, action_ok_remap_file_remove_core},
7767 {MENU_ENUM_LABEL_REMAP_FILE_REMOVE_CONTENT_DIR, action_ok_remap_file_remove_content_dir},
7768 {MENU_ENUM_LABEL_REMAP_FILE_REMOVE_GAME, action_ok_remap_file_remove_game},
7769 {MENU_ENUM_LABEL_PLAYLISTS_TAB, action_ok_content_collection_list},
7770 {MENU_ENUM_LABEL_BROWSE_URL_LIST, action_ok_browse_url_list},
7771 {MENU_ENUM_LABEL_CORE_LIST, action_ok_core_list},
7772 {MENU_ENUM_LABEL_SIDELOAD_CORE_LIST, action_ok_sideload_core_list},
7773 {MENU_ENUM_LABEL_DISK_IMAGE_APPEND, action_ok_disk_image_append_list},
7774 {MENU_ENUM_LABEL_SUBSYSTEM_ADD, action_ok_subsystem_add_list},
7775 {MENU_ENUM_LABEL_SUBSYSTEM_LOAD, action_ok_subsystem_add_load},
7776 {MENU_ENUM_LABEL_CONFIGURATIONS, action_ok_configurations_list},
7777 {MENU_ENUM_LABEL_SAVING_SETTINGS, action_ok_saving_list},
7778 {MENU_ENUM_LABEL_LOGGING_SETTINGS, action_ok_logging_list},
7779 {MENU_ENUM_LABEL_FRAME_THROTTLE_SETTINGS, action_ok_frame_throttle_list},
7780 {MENU_ENUM_LABEL_FRAME_TIME_COUNTER_SETTINGS, action_ok_frame_time_counter_list},
7781 {MENU_ENUM_LABEL_REWIND_SETTINGS, action_ok_rewind_list},
7782 {MENU_ENUM_LABEL_ONSCREEN_DISPLAY_SETTINGS, action_ok_onscreen_display_list},
7783 {MENU_ENUM_LABEL_ONSCREEN_NOTIFICATIONS_SETTINGS, action_ok_onscreen_notifications_list},
7784 {MENU_ENUM_LABEL_ONSCREEN_NOTIFICATIONS_VIEWS_SETTINGS, action_ok_onscreen_notifications_views_list},
7785 {MENU_ENUM_LABEL_ONSCREEN_OVERLAY_SETTINGS, action_ok_onscreen_overlay_list},
7786 {MENU_ENUM_LABEL_MENU_SETTINGS, action_ok_menu_list},
7787 {MENU_ENUM_LABEL_MENU_VIEWS_SETTINGS, action_ok_menu_views_list},
7788 {MENU_ENUM_LABEL_QUICK_MENU_OVERRIDE_OPTIONS, action_ok_quick_menu_override_options},
7789 {MENU_ENUM_LABEL_SETTINGS_VIEWS_SETTINGS, action_ok_settings_views_list},
7790 {MENU_ENUM_LABEL_QUICK_MENU_VIEWS_SETTINGS, action_ok_quick_menu_views_list},
7791 {MENU_ENUM_LABEL_USER_INTERFACE_SETTINGS, action_ok_user_interface_list},
7792 {MENU_ENUM_LABEL_POWER_MANAGEMENT_SETTINGS, action_ok_power_management_list},
7793 {MENU_ENUM_LABEL_CPU_PERFPOWER, action_ok_cpu_perfpower_list},
7794 {MENU_ENUM_LABEL_CPU_POLICY_ENTRY, action_ok_cpu_policy_entry},
7795 {MENU_ENUM_LABEL_MENU_SOUNDS, action_ok_menu_sounds_list},
7796 {MENU_ENUM_LABEL_MENU_FILE_BROWSER_SETTINGS, action_ok_menu_file_browser_list},
7797 {MENU_ENUM_LABEL_FILE_BROWSER_OPEN_UWP_PERMISSIONS, action_ok_open_uwp_permission_settings},
7798 {MENU_ENUM_LABEL_FILE_BROWSER_OPEN_PICKER, action_ok_open_picker},
7799 {MENU_ENUM_LABEL_RETRO_ACHIEVEMENTS_SETTINGS, action_ok_retro_achievements_list},
7800 {MENU_ENUM_LABEL_UPDATER_SETTINGS, action_ok_updater_list},
7801 {MENU_ENUM_LABEL_BLUETOOTH_SETTINGS, action_ok_bluetooth_list},
7802 #ifdef HAVE_NETWORKING
7803 {MENU_ENUM_LABEL_WIFI_SETTINGS, action_ok_wifi_list},
7804 {MENU_ENUM_LABEL_WIFI_NETWORK_SCAN, action_ok_wifi_networks_list},
7805 {MENU_ENUM_LABEL_WIFI_DISCONNECT, action_ok_wifi_disconnect},
7806 #endif
7807 {MENU_ENUM_LABEL_NETWORK_HOSTING_SETTINGS, action_ok_network_hosting_list},
7808 {MENU_ENUM_LABEL_SUBSYSTEM_SETTINGS, action_ok_subsystem_list},
7809 {MENU_ENUM_LABEL_NETWORK_SETTINGS, action_ok_network_list},
7810 {MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM, action_ok_netplay_connect_room},
7811 {MENU_ENUM_LABEL_LAKKA_SERVICES, action_ok_lakka_services},
7812 {MENU_ENUM_LABEL_NETPLAY_SETTINGS, action_ok_netplay_sublist},
7813 {MENU_ENUM_LABEL_USER_SETTINGS, action_ok_user_list},
7814 {MENU_ENUM_LABEL_DIRECTORY_SETTINGS, action_ok_directory_list},
7815 {MENU_ENUM_LABEL_PRIVACY_SETTINGS, action_ok_privacy_list},
7816 {MENU_ENUM_LABEL_MIDI_SETTINGS, action_ok_midi_list},
7817 {MENU_ENUM_LABEL_SCREEN_RESOLUTION, action_ok_video_resolution},
7818 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_DEFAULT_CORE, action_ok_playlist_default_core},
7819 {MENU_ENUM_LABEL_CORE_MANAGER_LIST, action_ok_push_core_manager_list},
7820 {MENU_ENUM_LABEL_EXPLORE_TAB, action_ok_push_default},
7821 };
7822
7823 for (i = 0; i < ARRAY_SIZE(ok_list); i++)
7824 {
7825 if (cbs->enum_idx == ok_list[i].type)
7826 {
7827 BIND_ACTION_OK(cbs, ok_list[i].cb);
7828 return 0;
7829 }
7830 }
7831 }
7832 else
7833 {
7834 unsigned i;
7835 typedef struct temp_ok_list
7836 {
7837 enum msg_hash_enums type;
7838 int (*cb)(const char *path, const char *label, unsigned type,
7839 size_t idx, size_t entry_idx);
7840 } temp_ok_list_t;
7841
7842 temp_ok_list_t ok_list[] = {
7843 {MENU_ENUM_LABEL_OPEN_ARCHIVE_DETECT_CORE, action_ok_open_archive_detect_core},
7844 {MENU_ENUM_LABEL_OPEN_ARCHIVE, action_ok_open_archive},
7845 {MENU_ENUM_LABEL_LOAD_ARCHIVE_DETECT_CORE, action_ok_load_archive_detect_core},
7846 {MENU_ENUM_LABEL_LOAD_ARCHIVE, action_ok_load_archive},
7847 {MENU_ENUM_LABEL_CHEAT_FILE_LOAD, action_ok_cheat_file},
7848 {MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND, action_ok_cheat_file_append},
7849 {MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN, action_ok_audio_dsp_plugin},
7850 {MENU_ENUM_LABEL_VIDEO_FILTER, action_ok_video_filter},
7851 {MENU_ENUM_LABEL_OVERLAY_PRESET, action_ok_overlay_preset},
7852 #if defined(HAVE_VIDEO_LAYOUT)
7853 {MENU_ENUM_LABEL_VIDEO_LAYOUT_PATH, action_ok_video_layout},
7854 #endif
7855 {MENU_ENUM_LABEL_REMAP_FILE_LOAD, action_ok_remap_file},
7856 {MENU_ENUM_LABEL_RECORD_CONFIG, action_ok_record_configfile},
7857 {MENU_ENUM_LABEL_STREAM_CONFIG, action_ok_stream_configfile},
7858 {MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET, action_ok_rgui_menu_theme_preset},
7859 {MENU_ENUM_LABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, action_ok_push_accounts_cheevos_list},
7860 {MENU_ENUM_LABEL_FAVORITES, action_ok_push_content_list},
7861 {MENU_ENUM_LABEL_DOWNLOADED_FILE_DETECT_CORE_LIST, action_ok_push_downloads_dir},
7862 {MENU_ENUM_LABEL_DETECT_CORE_LIST_OK, action_ok_file_load_detect_core},
7863 #ifdef HAVE_CHEATS
7864 {MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES, action_ok_cheat_apply_changes},
7865 {MENU_ENUM_LABEL_CHEAT_FILE_SAVE_AS, action_ok_cheat_file_save_as},
7866 #endif
7867 {MENU_ENUM_LABEL_REMAP_FILE_SAVE_CORE, action_ok_remap_file_save_core},
7868 {MENU_ENUM_LABEL_REMAP_FILE_SAVE_CONTENT_DIR, action_ok_remap_file_save_content_dir},
7869 {MENU_ENUM_LABEL_REMAP_FILE_SAVE_GAME, action_ok_remap_file_save_game},
7870 {MENU_ENUM_LABEL_DISK_IMAGE_APPEND, action_ok_disk_image_append_list},
7871 {MENU_ENUM_LABEL_SUBSYSTEM_ADD, action_ok_subsystem_add_list},
7872 {MENU_ENUM_LABEL_SCREEN_RESOLUTION, action_ok_video_resolution},
7873 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_DEFAULT_CORE, action_ok_playlist_default_core},
7874 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE, action_ok_playlist_label_display_mode},
7875 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_RIGHT_THUMBNAIL_MODE, action_ok_playlist_right_thumbnail_mode},
7876 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE, action_ok_playlist_left_thumbnail_mode},
7877 {MENU_ENUM_LABEL_PLAYLIST_MANAGER_SORT_MODE, action_ok_playlist_sort_mode},
7878 {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME, action_ok_manual_content_scan_system_name},
7879 {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME, action_ok_manual_content_scan_core_name},
7880 {MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DAT_FILE, action_ok_manual_content_scan_dat_file},
7881 };
7882
7883 for (i = 0; i < ARRAY_SIZE(ok_list); i++)
7884 {
7885 if (string_is_equal(label, msg_hash_to_str(ok_list[i].type)))
7886 {
7887 BIND_ACTION_OK(cbs, ok_list[i].cb);
7888 return 0;
7889 }
7890 }
7891 }
7892
7893 return -1;
7894 }
7895
menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t * cbs,const char * label,const char * menu_label,unsigned type)7896 static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs,
7897 const char *label, const char *menu_label, unsigned type)
7898 {
7899 if (type == MENU_SET_CDROM_LIST)
7900 {
7901 BIND_ACTION_OK(cbs, action_ok_dump_cdrom);
7902 }
7903 else if (type == MENU_SET_CDROM_INFO)
7904 {
7905 BIND_ACTION_OK(cbs, action_ok_cdrom_info_list);
7906 }
7907 else if (type == MENU_SET_LOAD_CDROM_LIST)
7908 {
7909 BIND_ACTION_OK(cbs, action_ok_load_cdrom);
7910 }
7911 else if (type == MENU_SETTINGS_CUSTOM_BIND_KEYBOARD ||
7912 type == MENU_SETTINGS_CUSTOM_BIND)
7913 {
7914 BIND_ACTION_OK(cbs, action_ok_lookup_setting);
7915 }
7916 #ifdef HAVE_AUDIOMIXER
7917 else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN
7918 && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_END)
7919 {
7920 BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_play);
7921 }
7922 else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN
7923 && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_END)
7924 {
7925 BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_play_looped);
7926 }
7927 else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_BEGIN
7928 && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_SEQUENTIAL_END)
7929 {
7930 BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_play_sequential);
7931 }
7932 else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN
7933 && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_END)
7934 {
7935 BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_remove);
7936 }
7937 else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_BEGIN
7938 && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_END)
7939 {
7940 BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_stop);
7941 }
7942 else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_BEGIN
7943 && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_END)
7944 {
7945 BIND_ACTION_OK(cbs, action_ok_mixer_stream_actions);
7946 }
7947 #endif
7948 else if (type >= MENU_SETTINGS_REMAPPING_PORT_BEGIN
7949 && type <= MENU_SETTINGS_REMAPPING_PORT_END)
7950 {
7951 BIND_ACTION_OK(cbs, action_ok_remappings_port_list);
7952 }
7953 else if (type >= MENU_SETTINGS_SHADER_PARAMETER_0
7954 && type <= MENU_SETTINGS_SHADER_PARAMETER_LAST)
7955 {
7956 BIND_ACTION_OK(cbs, action_ok_shader_parameter_dropdown_box_list);
7957 }
7958 else if (type >= MENU_SETTINGS_SHADER_PRESET_PARAMETER_0
7959 && type <= MENU_SETTINGS_SHADER_PRESET_PARAMETER_LAST)
7960 {
7961 BIND_ACTION_OK(cbs, action_ok_shader_preset_parameter_dropdown_box_list);
7962 }
7963 else if (type >= MENU_SETTINGS_CHEAT_BEGIN
7964 && type <= MENU_SETTINGS_CHEAT_END)
7965 {
7966 BIND_ACTION_OK(cbs, action_ok_cheat);
7967 }
7968 else if ((type >= MENU_SETTINGS_CORE_OPTION_START) &&
7969 (type < MENU_SETTINGS_CHEEVOS_START))
7970 {
7971 BIND_ACTION_OK(cbs, action_ok_core_option_dropdown_list);
7972 }
7973 else if ((type >= MENU_SETTINGS_INPUT_DESC_BEGIN) &&
7974 (type <= MENU_SETTINGS_INPUT_DESC_END))
7975 {
7976 BIND_ACTION_OK(cbs, action_ok_input_description_dropdown_box_list);
7977 }
7978 else if ((type >= MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) &&
7979 (type <= MENU_SETTINGS_INPUT_DESC_KBD_END))
7980 {
7981 BIND_ACTION_OK(cbs, action_ok_input_description_kbd_dropdown_box_list);
7982 }
7983 else
7984 {
7985 switch (type)
7986 {
7987 case MENU_SETTING_DROPDOWN_SETTING_CORE_OPTIONS_ITEM:
7988 BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting_core_options_item);
7989 break;
7990 case MENU_SETTING_DROPDOWN_SETTING_CORE_OPTIONS_ITEM_SPECIAL:
7991 BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting_core_options_item_special);
7992 break;
7993 case MENU_SETTING_DROPDOWN_SETTING_STRING_OPTIONS_ITEM:
7994 case MENU_SETTING_DROPDOWN_SETTING_INT_ITEM:
7995 case MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM:
7996 case MENU_SETTING_DROPDOWN_SETTING_UINT_ITEM:
7997 case MENU_SETTING_DROPDOWN_SETTING_STRING_OPTIONS_ITEM_SPECIAL:
7998 case MENU_SETTING_DROPDOWN_SETTING_INT_ITEM_SPECIAL:
7999 case MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM_SPECIAL:
8000 BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting);
8001 break;
8002 case MENU_SETTING_DROPDOWN_SETTING_UINT_ITEM_SPECIAL:
8003 BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting_uint_item_special);
8004 break;
8005 case MENU_SETTING_DROPDOWN_ITEM:
8006 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item);
8007 break;
8008 case MENU_SETTING_DROPDOWN_ITEM_VIDEO_SHADER_PARAM:
8009 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_video_shader_param);
8010 break;
8011 case MENU_SETTING_DROPDOWN_ITEM_VIDEO_SHADER_PRESET_PARAM:
8012 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_video_shader_preset_param);
8013 break;
8014 case MENU_SETTING_DROPDOWN_ITEM_RESOLUTION:
8015 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_resolution);
8016 break;
8017 case MENU_SETTING_DROPDOWN_ITEM_VIDEO_SHADER_NUM_PASS:
8018 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_video_shader_num_pass);
8019 break;
8020 case MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_DEFAULT_CORE:
8021 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_playlist_default_core);
8022 break;
8023 case MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LABEL_DISPLAY_MODE:
8024 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_playlist_label_display_mode);
8025 break;
8026 case MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_RIGHT_THUMBNAIL_MODE:
8027 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_playlist_right_thumbnail_mode);
8028 break;
8029 case MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LEFT_THUMBNAIL_MODE:
8030 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_playlist_left_thumbnail_mode);
8031 break;
8032 case MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_SORT_MODE:
8033 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_playlist_sort_mode);
8034 break;
8035 case MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
8036 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_manual_content_scan_system_name);
8037 break;
8038 case MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_CORE_NAME:
8039 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_manual_content_scan_core_name);
8040 break;
8041 case MENU_SETTING_DROPDOWN_ITEM_DISK_INDEX:
8042 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_disk_index);
8043 break;
8044 case MENU_SETTING_DROPDOWN_ITEM_INPUT_DEVICE_TYPE:
8045 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_input_device_type);
8046 break;
8047 case MENU_SETTING_DROPDOWN_ITEM_INPUT_DEVICE_INDEX:
8048 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_input_device_index);
8049 break;
8050 case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION:
8051 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_input_description);
8052 break;
8053 case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION_KBD:
8054 BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_input_description_kbd);
8055 break;
8056 case MENU_SETTING_ACTION_CORE_DISK_OPTIONS:
8057 BIND_ACTION_OK(cbs, action_ok_push_default);
8058 break;
8059 case FILE_TYPE_PLAYLIST_ENTRY:
8060 BIND_ACTION_OK(cbs, action_ok_playlist_entry_collection);
8061 break;
8062 #ifdef HAVE_LAKKA_SWITCH
8063 case MENU_SET_SWITCH_GPU_PROFILE:
8064 BIND_ACTION_OK(cbs, action_ok_set_switch_gpu_profile);
8065 break;
8066 #endif
8067 #if defined(HAVE_LAKKA_SWITCH) || defined(HAVE_LIBNX)
8068 case MENU_SET_SWITCH_CPU_PROFILE:
8069 BIND_ACTION_OK(cbs, action_ok_set_switch_cpu_profile);
8070 break;
8071 #endif
8072 case FILE_TYPE_RPL_ENTRY:
8073 BIND_ACTION_OK(cbs, action_ok_rpl_entry);
8074 break;
8075 case FILE_TYPE_PLAYLIST_COLLECTION:
8076 BIND_ACTION_OK(cbs, action_ok_playlist_collection);
8077 break;
8078 case FILE_TYPE_CONTENTLIST_ENTRY:
8079 BIND_ACTION_OK(cbs, action_ok_push_generic_list);
8080 break;
8081 case FILE_TYPE_CHEAT:
8082 if (string_is_equal(menu_label,
8083 msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_FILE_LOAD_APPEND)))
8084 {
8085 BIND_ACTION_OK(cbs, action_ok_cheat_file_load_append);
8086 }
8087 else
8088 {
8089 BIND_ACTION_OK(cbs, action_ok_cheat_file_load);
8090 }
8091 break;
8092 case FILE_TYPE_RECORD_CONFIG:
8093 BIND_ACTION_OK(cbs, action_ok_record_configfile_load);
8094 break;
8095 case FILE_TYPE_STREAM_CONFIG:
8096 BIND_ACTION_OK(cbs, action_ok_stream_configfile_load);
8097 break;
8098 case FILE_TYPE_RGUI_THEME_PRESET:
8099 BIND_ACTION_OK(cbs, action_ok_rgui_menu_theme_preset_load);
8100 break;
8101 case FILE_TYPE_REMAP:
8102 BIND_ACTION_OK(cbs, action_ok_remap_file_load);
8103 break;
8104 case FILE_TYPE_SHADER_PRESET:
8105 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
8106 /* TODO/FIXME - handle scan case */
8107 BIND_ACTION_OK(cbs, action_ok_shader_preset_load);
8108 #endif
8109 break;
8110 case FILE_TYPE_SHADER:
8111 #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
8112 /* TODO/FIXME - handle scan case */
8113 BIND_ACTION_OK(cbs, action_ok_shader_pass_load);
8114 #endif
8115 break;
8116 case FILE_TYPE_IMAGE:
8117 /* TODO/FIXME - handle scan case */
8118 BIND_ACTION_OK(cbs, action_ok_menu_wallpaper_load);
8119 break;
8120 case FILE_TYPE_USE_DIRECTORY:
8121 BIND_ACTION_OK(cbs, action_ok_path_use_directory);
8122 break;
8123 #ifdef HAVE_LIBRETRODB
8124 case FILE_TYPE_SCAN_DIRECTORY:
8125 BIND_ACTION_OK(cbs, action_ok_path_scan_directory);
8126 break;
8127 #endif
8128 case FILE_TYPE_MANUAL_SCAN_DIRECTORY:
8129 BIND_ACTION_OK(cbs, action_ok_path_manual_scan_directory);
8130 break;
8131 case FILE_TYPE_MANUAL_SCAN_DAT:
8132 BIND_ACTION_OK(cbs, action_ok_set_manual_content_scan_dat_file);
8133 break;
8134 case FILE_TYPE_CONFIG:
8135 BIND_ACTION_OK(cbs, action_ok_config_load);
8136 break;
8137 case FILE_TYPE_PARENT_DIRECTORY:
8138 BIND_ACTION_OK(cbs, action_ok_parent_directory_push);
8139 break;
8140 case FILE_TYPE_DIRECTORY:
8141 if (cbs->enum_idx != MSG_UNKNOWN
8142 || string_is_equal(menu_label,
8143 msg_hash_to_str(MENU_ENUM_LABEL_DISK_IMAGE_APPEND))
8144 || string_is_equal(menu_label,
8145 msg_hash_to_str(MENU_ENUM_LABEL_SUBSYSTEM_ADD))
8146 || string_is_equal(menu_label,
8147 msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_FONT_PATH))
8148 || string_is_equal(menu_label,
8149 msg_hash_to_str(MENU_ENUM_LABEL_XMB_FONT))
8150 || string_is_equal(menu_label,
8151 msg_hash_to_str(MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN))
8152 || string_is_equal(menu_label,
8153 msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_FILTER)))
8154 BIND_ACTION_OK(cbs, action_ok_directory_push);
8155 else
8156 BIND_ACTION_OK(cbs, action_ok_push_random_dir);
8157 break;
8158 case FILE_TYPE_CARCHIVE:
8159 if (filebrowser_get_type() == FILEBROWSER_SCAN_FILE)
8160 {
8161 #ifdef HAVE_LIBRETRODB
8162 BIND_ACTION_OK(cbs, action_ok_scan_file);
8163 #endif
8164 }
8165 else
8166 {
8167 if (string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES)))
8168 {
8169 BIND_ACTION_OK(cbs, action_ok_compressed_archive_push_detect_core);
8170 }
8171 else
8172 {
8173 BIND_ACTION_OK(cbs, action_ok_compressed_archive_push);
8174 }
8175 }
8176 break;
8177 case FILE_TYPE_CORE:
8178 if (cbs->enum_idx != MSG_UNKNOWN)
8179 {
8180 switch (cbs->enum_idx)
8181 {
8182 case MENU_ENUM_LABEL_CORE_UPDATER_LIST:
8183 BIND_ACTION_OK(cbs, action_ok_deferred_list_stub);
8184 break;
8185 case MSG_UNKNOWN:
8186 default:
8187 break;
8188 }
8189 }
8190 else
8191 {
8192 if (string_is_equal(menu_label,
8193 msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CORE_LIST)))
8194 {
8195 BIND_ACTION_OK(cbs, action_ok_load_core_deferred);
8196 }
8197 else if (string_is_equal(menu_label,
8198 msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CORE_LIST_SET)))
8199 {
8200 BIND_ACTION_OK(cbs, action_ok_core_deferred_set);
8201 }
8202 else if (string_is_equal(menu_label,
8203 msg_hash_to_str(MENU_ENUM_LABEL_CORE_LIST)))
8204 {
8205 BIND_ACTION_OK(cbs, action_ok_load_core);
8206 }
8207 }
8208 break;
8209 case FILE_TYPE_DOWNLOAD_CORE_CONTENT:
8210 BIND_ACTION_OK(cbs, action_ok_core_content_download);
8211 break;
8212 case FILE_TYPE_DOWNLOAD_THUMBNAIL_CONTENT:
8213 BIND_ACTION_OK(cbs, action_ok_core_content_thumbnails);
8214 break;
8215 case FILE_TYPE_DOWNLOAD_PL_THUMBNAIL_CONTENT:
8216 BIND_ACTION_OK(cbs, action_ok_pl_content_thumbnails);
8217 break;
8218 case FILE_TYPE_DOWNLOAD_CORE:
8219 BIND_ACTION_OK(cbs, action_ok_core_updater_download);
8220 break;
8221 case FILE_TYPE_SIDELOAD_CORE:
8222 BIND_ACTION_OK(cbs, action_ok_sideload_core);
8223 break;
8224 case FILE_TYPE_DOWNLOAD_URL:
8225 BIND_ACTION_OK(cbs, action_ok_download_url);
8226 break;
8227 case FILE_TYPE_DOWNLOAD_THUMBNAIL:
8228 BIND_ACTION_OK(cbs, action_ok_thumbnails_updater_download);
8229 break;
8230 case FILE_TYPE_DOWNLOAD_LAKKA:
8231 BIND_ACTION_OK(cbs, action_ok_lakka_download);
8232 break;
8233 case FILE_TYPE_DOWNLOAD_CORE_INFO:
8234 break;
8235 case FILE_TYPE_RDB:
8236 if (string_is_equal(menu_label,
8237 msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DATABASE_MANAGER_LIST)))
8238 {
8239 BIND_ACTION_OK(cbs, action_ok_deferred_list_stub);
8240 }
8241 else if (string_is_equal(menu_label,
8242 msg_hash_to_str(MENU_ENUM_LABEL_DATABASE_MANAGER_LIST)))
8243 {
8244 BIND_ACTION_OK(cbs, action_ok_database_manager_list);
8245 }
8246 /* TODO/FIXME - refactor this */
8247 else if (string_is_equal(menu_label, "Horizontal Menu"))
8248 {
8249 BIND_ACTION_OK(cbs, action_ok_database_manager_list);
8250 }
8251 break;
8252 case FILE_TYPE_RDB_ENTRY:
8253 BIND_ACTION_OK(cbs, action_ok_rdb_entry);
8254 break;
8255 case MENU_BLUETOOTH:
8256 BIND_ACTION_OK(cbs, action_ok_bluetooth);
8257 break;
8258 case MENU_WIFI:
8259 #ifdef HAVE_NETWORKING
8260 BIND_ACTION_OK(cbs, action_ok_wifi);
8261 #endif
8262 break;
8263 case MENU_NETPLAY_LAN_SCAN:
8264 BIND_ACTION_OK(cbs, action_ok_netplay_lan_scan);
8265 break;
8266 case FILE_TYPE_CURSOR:
8267 if (string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DATABASE_MANAGER_LIST)))
8268 {
8269 BIND_ACTION_OK(cbs, action_ok_deferred_list_stub);
8270 }
8271 else if (string_is_equal(menu_label,
8272 msg_hash_to_str(MENU_ENUM_LABEL_CURSOR_MANAGER_LIST)))
8273 {
8274 BIND_ACTION_OK(cbs, action_ok_cursor_manager_list);
8275 }
8276 break;
8277 case FILE_TYPE_VIDEOFILTER:
8278 BIND_ACTION_OK(cbs, action_ok_set_path_videofilter);
8279 break;
8280 case FILE_TYPE_FONT:
8281 BIND_ACTION_OK(cbs, action_ok_set_path);
8282 break;
8283 case FILE_TYPE_VIDEO_FONT:
8284 BIND_ACTION_OK(cbs, action_ok_set_path_video_font);
8285 break;
8286 case FILE_TYPE_OVERLAY:
8287 BIND_ACTION_OK(cbs, action_ok_set_path_overlay);
8288 break;
8289 #ifdef HAVE_VIDEO_LAYOUT
8290 case FILE_TYPE_VIDEO_LAYOUT:
8291 BIND_ACTION_OK(cbs, action_ok_set_path_video_layout);
8292 break;
8293 #endif
8294 case FILE_TYPE_AUDIOFILTER:
8295 BIND_ACTION_OK(cbs, action_ok_set_path_audiofilter);
8296 break;
8297 case FILE_TYPE_IN_CARCHIVE:
8298 case FILE_TYPE_PLAIN:
8299 if (filebrowser_get_type() == FILEBROWSER_SCAN_FILE)
8300 {
8301 #ifdef HAVE_LIBRETRODB
8302 BIND_ACTION_OK(cbs, action_ok_scan_file);
8303 #endif
8304 }
8305 else if (cbs->enum_idx != MSG_UNKNOWN)
8306 {
8307 switch (cbs->enum_idx)
8308 {
8309 case MENU_ENUM_LABEL_DOWNLOADED_FILE_DETECT_CORE_LIST:
8310 case MENU_ENUM_LABEL_FAVORITES:
8311 case MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN_DETECT_CORE:
8312 #ifdef HAVE_COMPRESSION
8313 if (type == FILE_TYPE_IN_CARCHIVE)
8314 {
8315 BIND_ACTION_OK(cbs, action_ok_file_load_with_detect_core_carchive);
8316 }
8317 else
8318 #endif
8319 {
8320 BIND_ACTION_OK(cbs, action_ok_file_load_with_detect_core);
8321 }
8322 break;
8323 case MENU_ENUM_LABEL_DISK_IMAGE_APPEND:
8324 BIND_ACTION_OK(cbs, action_ok_disk_image_append);
8325 break;
8326 case MENU_ENUM_LABEL_SUBSYSTEM_ADD:
8327 BIND_ACTION_OK(cbs, action_ok_subsystem_add);
8328 break;
8329 default:
8330 BIND_ACTION_OK(cbs, action_ok_file_load);
8331 break;
8332 }
8333 }
8334 else
8335 {
8336 if (
8337 string_is_equal(menu_label, "deferred_archive_open_detect_core") ||
8338 string_is_equal(menu_label, "downloaded_file_detect_core_list") ||
8339 string_is_equal(menu_label, "favorites")
8340 )
8341 {
8342 #ifdef HAVE_COMPRESSION
8343 if (type == FILE_TYPE_IN_CARCHIVE)
8344 {
8345 BIND_ACTION_OK(cbs, action_ok_file_load_with_detect_core_carchive);
8346 }
8347 else
8348 #endif
8349 {
8350 BIND_ACTION_OK(cbs, action_ok_file_load_with_detect_core);
8351 }
8352 }
8353 else if (string_is_equal(menu_label, "disk_image_append"))
8354 {
8355 BIND_ACTION_OK(cbs, action_ok_disk_image_append);
8356 }
8357 else if (string_is_equal(menu_label, "subsystem_add"))
8358 {
8359 BIND_ACTION_OK(cbs, action_ok_subsystem_add);
8360 }
8361 else
8362 {
8363 BIND_ACTION_OK(cbs, action_ok_file_load);
8364 }
8365 }
8366 break;
8367 case FILE_TYPE_MOVIE:
8368 #if defined(HAVE_FFMPEG) || defined(HAVE_MPV)
8369 /* TODO/FIXME - handle scan case */
8370 BIND_ACTION_OK(cbs, action_ok_file_load_ffmpeg);
8371 #endif
8372 break;
8373 case FILE_TYPE_MUSIC:
8374 BIND_ACTION_OK(cbs, action_ok_file_load_music);
8375 break;
8376 case FILE_TYPE_IMAGEVIEWER:
8377 /* TODO/FIXME - handle scan case */
8378 BIND_ACTION_OK(cbs, action_ok_file_load_imageviewer);
8379 break;
8380 case FILE_TYPE_DIRECT_LOAD:
8381 BIND_ACTION_OK(cbs, action_ok_file_load);
8382 break;
8383 case MENU_SETTINGS:
8384 case MENU_SETTING_GROUP:
8385 case MENU_SETTING_SUBGROUP:
8386 BIND_ACTION_OK(cbs, action_ok_push_default);
8387 break;
8388 case MENU_SETTINGS_CORE_DISK_OPTIONS_DISK_CYCLE_TRAY_STATUS:
8389 BIND_ACTION_OK(cbs, action_ok_disk_cycle_tray_status);
8390 break;
8391 case MENU_SETTINGS_CORE_DISK_OPTIONS_DISK_INDEX:
8392 BIND_ACTION_OK(cbs, action_ok_disk_index_dropdown_box_list);
8393 break;
8394 case MENU_SETTING_ACTION_GAME_SPECIFIC_CORE_OPTIONS_CREATE:
8395 BIND_ACTION_OK(cbs, action_ok_game_specific_core_options_create);
8396 break;
8397 case MENU_SETTING_ACTION_FOLDER_SPECIFIC_CORE_OPTIONS_CREATE:
8398 BIND_ACTION_OK(cbs, action_ok_folder_specific_core_options_create);
8399 break;
8400 case MENU_SETTING_ACTION_GAME_SPECIFIC_CORE_OPTIONS_REMOVE:
8401 BIND_ACTION_OK(cbs, action_ok_game_specific_core_options_remove);
8402 break;
8403 case MENU_SETTING_ACTION_FOLDER_SPECIFIC_CORE_OPTIONS_REMOVE:
8404 BIND_ACTION_OK(cbs, action_ok_folder_specific_core_options_remove);
8405 break;
8406 case MENU_SETTING_ACTION_CORE_OPTIONS_RESET:
8407 BIND_ACTION_OK(cbs, action_ok_core_options_reset);
8408 break;
8409 case MENU_SETTING_ITEM_CORE_RESTORE_BACKUP:
8410 BIND_ACTION_OK(cbs, action_ok_core_restore_backup);
8411 break;
8412 case MENU_SETTING_ITEM_CORE_DELETE_BACKUP:
8413 BIND_ACTION_OK(cbs, action_ok_core_delete_backup);
8414 break;
8415 case MENU_SETTING_ACTION_CORE_LOCK:
8416 BIND_ACTION_OK(cbs, action_ok_core_lock);
8417 break;
8418 case MENU_SETTING_ACTION_VIDEO_FILTER_REMOVE:
8419 BIND_ACTION_OK(cbs, action_ok_video_filter_remove);
8420 break;
8421 case MENU_SETTING_ACTION_AUDIO_DSP_PLUGIN_REMOVE:
8422 BIND_ACTION_OK(cbs, action_ok_audio_dsp_plugin_remove);
8423 break;
8424 default:
8425 return -1;
8426 }
8427 }
8428
8429 return 0;
8430 }
8431
menu_cbs_init_bind_ok(menu_file_list_cbs_t * cbs,const char * path,const char * label,unsigned type,size_t idx,const char * menu_label)8432 int menu_cbs_init_bind_ok(menu_file_list_cbs_t *cbs,
8433 const char *path, const char *label, unsigned type, size_t idx,
8434 const char *menu_label)
8435 {
8436 if (!cbs)
8437 return -1;
8438
8439 BIND_ACTION_OK(cbs, action_ok_lookup_setting);
8440
8441 if (menu_cbs_init_bind_ok_compare_label(cbs, label) == 0)
8442 return 0;
8443
8444 if (menu_cbs_init_bind_ok_compare_type(cbs, label,
8445 menu_label, type) == 0)
8446 return 0;
8447
8448 return -1;
8449 }
8450