1 /*  RetroArch - A frontend for libretro.
2  *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3  *  Copyright (C) 2011-2017 - Daniel De Matteis
4  *  Copyright (C) 2014-2017 - Jean-André Santoni
5  *  Copyright (C) 2015-2019 - Andrés Suárez (input remapping + other things)
6  *  Copyright (C) 2016-2019 - Brad Parker
7  *
8  *  RetroArch is free software: you can redistribute it and/or modify it under the terms
9  *  of the GNU General Public License as published by the Free Software Found-
10  *  ation, either version 3 of the License, or (at your option) any later version.
11  *
12  *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  *  PURPOSE.  See the GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License along with RetroArch.
17  *  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <ctype.h>
21 
22 #include <libretro.h>
23 #include <file/config_file.h>
24 #include <file/file_path.h>
25 #include <compat/strl.h>
26 #include <compat/posix_string.h>
27 #include <retro_assert.h>
28 #include <string/stdstring.h>
29 #include <streams/file_stream.h>
30 
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 
35 #include "file_path_special.h"
36 #include "configuration.h"
37 #include "content.h"
38 #include "config.def.h"
39 #include "config.features.h"
40 #include "input/input_keymaps.h"
41 #include "input/input_remapping.h"
42 #include "led/led_defines.h"
43 #include "defaults.h"
44 #include "core.h"
45 #include "paths.h"
46 #include "retroarch.h"
47 #include "verbosity.h"
48 #include "lakka.h"
49 
50 #include "gfx/gfx_animation.h"
51 
52 #include "tasks/task_content.h"
53 #include "tasks/tasks_internal.h"
54 
55 #include "list_special.h"
56 
57 #if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
58 #include "uwp/uwp_func.h"
59 #endif
60 
61 enum video_driver_enum
62 {
63    VIDEO_GL                 = 0,
64    VIDEO_GL1,
65    VIDEO_GL_CORE,
66    VIDEO_VULKAN,
67    VIDEO_METAL,
68    VIDEO_DRM,
69    VIDEO_XVIDEO,
70    VIDEO_SDL,
71    VIDEO_SDL2,
72    VIDEO_SDL_DINGUX,
73    VIDEO_SDL_RS90,
74    VIDEO_EXT,
75    VIDEO_WII,
76    VIDEO_WIIU,
77    VIDEO_XENON360,
78    VIDEO_PSP1,
79    VIDEO_VITA2D,
80    VIDEO_PS2,
81    VIDEO_CTR,
82    VIDEO_SWITCH,
83    VIDEO_D3D8,
84    VIDEO_D3D9,
85    VIDEO_D3D10,
86    VIDEO_D3D11,
87    VIDEO_D3D12,
88    VIDEO_VG,
89    VIDEO_OMAP,
90    VIDEO_EXYNOS,
91    VIDEO_SUNXI,
92    VIDEO_DISPMANX,
93    VIDEO_CACA,
94    VIDEO_GDI,
95    VIDEO_VGA,
96    VIDEO_FPGA,
97    VIDEO_RSX,
98    VIDEO_NULL
99 };
100 
101 enum audio_driver_enum
102 {
103    AUDIO_RSOUND             = VIDEO_NULL + 1,
104    AUDIO_AUDIOIO,
105    AUDIO_OSS,
106    AUDIO_ALSA,
107    AUDIO_ALSATHREAD,
108    AUDIO_TINYALSA,
109    AUDIO_ROAR,
110    AUDIO_AL,
111    AUDIO_SL,
112    AUDIO_JACK,
113    AUDIO_SDL,
114    AUDIO_SDL2,
115    AUDIO_XAUDIO,
116    AUDIO_PULSE,
117    AUDIO_EXT,
118    AUDIO_DSOUND,
119    AUDIO_WASAPI,
120    AUDIO_COREAUDIO,
121    AUDIO_COREAUDIO3,
122    AUDIO_PS3,
123    AUDIO_XENON360,
124    AUDIO_WII,
125    AUDIO_WIIU,
126    AUDIO_RWEBAUDIO,
127    AUDIO_PSP,
128    AUDIO_PS2,
129    AUDIO_CTR,
130    AUDIO_SWITCH,
131    AUDIO_NULL
132 };
133 
134 enum audio_resampler_driver_enum
135 {
136    AUDIO_RESAMPLER_CC       = AUDIO_NULL + 1,
137    AUDIO_RESAMPLER_SINC,
138    AUDIO_RESAMPLER_NEAREST,
139    AUDIO_RESAMPLER_NULL
140 };
141 
142 enum input_driver_enum
143 {
144    INPUT_ANDROID            = AUDIO_RESAMPLER_NULL + 1,
145    INPUT_SDL,
146    INPUT_SDL2,
147    INPUT_SDL_DINGUX,
148    INPUT_X,
149    INPUT_WAYLAND,
150    INPUT_DINPUT,
151    INPUT_PS4,
152    INPUT_PS3,
153    INPUT_PSP,
154    INPUT_PS2,
155    INPUT_CTR,
156    INPUT_SWITCH,
157    INPUT_XENON360,
158    INPUT_WII,
159    INPUT_WIIU,
160    INPUT_XINPUT,
161    INPUT_UWP,
162    INPUT_UDEV,
163    INPUT_LINUXRAW,
164    INPUT_COCOA,
165    INPUT_QNX,
166    INPUT_RWEBINPUT,
167    INPUT_DOS,
168    INPUT_WINRAW,
169    INPUT_NULL
170 };
171 
172 enum joypad_driver_enum
173 {
174    JOYPAD_PS3               = INPUT_NULL + 1,
175    JOYPAD_XINPUT,
176    JOYPAD_GX,
177    JOYPAD_WIIU,
178    JOYPAD_XDK,
179    JOYPAD_PS4,
180    JOYPAD_PSP,
181    JOYPAD_PS2,
182    JOYPAD_CTR,
183    JOYPAD_SWITCH,
184    JOYPAD_DINPUT,
185    JOYPAD_UDEV,
186    JOYPAD_LINUXRAW,
187    JOYPAD_ANDROID,
188    JOYPAD_SDL,
189    JOYPAD_SDL_DINGUX,
190    JOYPAD_DOS,
191    JOYPAD_HID,
192    JOYPAD_QNX,
193    JOYPAD_RWEBPAD,
194    JOYPAD_MFI,
195    JOYPAD_NULL
196 };
197 
198 enum camera_driver_enum
199 {
200    CAMERA_V4L2              = JOYPAD_NULL + 1,
201    CAMERA_RWEBCAM,
202    CAMERA_ANDROID,
203    CAMERA_AVFOUNDATION,
204    CAMERA_NULL
205 };
206 
207 enum bluetooth_driver_enum
208 {
209    BLUETOOTH_BLUETOOTHCTL          = CAMERA_NULL + 1,
210    BLUETOOTH_BLUEZ,
211    BLUETOOTH_NULL
212 };
213 
214 enum wifi_driver_enum
215 {
216    WIFI_CONNMANCTL          = BLUETOOTH_NULL + 1,
217    WIFI_NMCLI,
218    WIFI_NULL
219 };
220 
221 enum location_driver_enum
222 {
223    LOCATION_ANDROID         = WIFI_NULL + 1,
224    LOCATION_CORELOCATION,
225    LOCATION_NULL
226 };
227 
228 enum osk_driver_enum
229 {
230    OSK_PS3                  = LOCATION_NULL + 1,
231    OSK_NULL
232 };
233 
234 enum menu_driver_enum
235 {
236    MENU_RGUI                = OSK_NULL + 1,
237    MENU_MATERIALUI,
238    MENU_XMB,
239    MENU_STRIPES,
240    MENU_OZONE,
241    MENU_NULL
242 };
243 
244 enum record_driver_enum
245 {
246    RECORD_FFMPEG            = MENU_NULL + 1,
247    RECORD_NULL
248 };
249 
250 enum midi_driver_enum
251 {
252    MIDI_WINMM               = RECORD_NULL + 1,
253    MIDI_ALSA,
254    MIDI_NULL
255 };
256 
257 #if defined(HAVE_METAL)
258 /* iOS supports both the OpenGL and Metal video drivers; default to OpenGL since Metal support is preliminary */
259 #if defined(HAVE_COCOATOUCH) && defined(HAVE_OPENGL)
260 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL;
261 #else
262 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_METAL;
263 #endif
264 #elif defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
265 /* Lets default to D3D11 in UWP, even when its compiled with ANGLE, since ANGLE is just calling D3D anyway.*/
266 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D11;
267 #elif defined(HAVE_OPENGL1) && defined(_MSC_VER) && (_MSC_VER <= 1600)
268 /* On Windows XP and earlier, use gl1 by default
269  * (regular opengl has compatibility issues with
270  * obsolete hardware drivers...) */
271 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL1;
272 #elif defined(HAVE_VITA2D)
273 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VITA2D;
274 #elif defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(HAVE_PSGL)
275 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL;
276 #elif defined(HAVE_OPENGL_CORE) && !defined(__HAIKU__)
277 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL_CORE;
278 #elif defined(HAVE_OPENGL1)
279 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL1;
280 #elif defined(GEKKO)
281 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WII;
282 #elif defined(WIIU)
283 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WIIU;
284 #elif defined(XENON)
285 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XENON360;
286 #elif defined(HAVE_D3D11)
287 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D11;
288 #elif defined(HAVE_D3D12)
289 /* FIXME/WARNING: DX12 performance on Xbox is horrible for
290  * some reason. For now, we will default to D3D11 when possible. */
291 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D12;
292 #elif defined(HAVE_D3D10)
293 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D10;
294 #elif defined(HAVE_D3D9)
295 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D9;
296 #elif defined(HAVE_D3D8)
297 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D8;
298 #elif defined(HAVE_VG)
299 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VG;
300 #elif defined(PSP)
301 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_PSP1;
302 #elif defined(PS2)
303 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_PS2;
304 #elif defined(_3DS)
305 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_CTR;
306 #elif defined(SWITCH)
307 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SWITCH;
308 #elif defined(HAVE_XVIDEO)
309 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XVIDEO;
310 #elif defined(HAVE_SDL) && !defined(HAVE_SDL_DINGUX)
311 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL;
312 #elif defined(HAVE_SDL2)
313 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL2;
314 #elif defined(HAVE_SDL_DINGUX)
315 #if defined(RS90)
316 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL_RS90;
317 #else
318 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_SDL_DINGUX;
319 #endif
320 #elif defined(_WIN32) && !defined(_XBOX)
321 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GDI;
322 #elif defined(DJGPP)
323 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VGA;
324 #elif defined(HAVE_FPGA)
325 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_FPGA;
326 #elif defined(HAVE_DYLIB) && !defined(ANDROID)
327 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_EXT;
328 #elif defined(__PSL1GHT__)
329 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_RSX;
330 #else
331 static const enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_NULL;
332 #endif
333 
334 #if defined(XENON)
335 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_XENON360;
336 #elif defined(GEKKO)
337 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_WII;
338 #elif defined(WIIU)
339 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_WIIU;
340 #elif defined(PSP) || defined(VITA) || defined(ORBIS)
341 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PSP;
342 #elif defined(PS2)
343 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PS2;
344 #elif defined(__PS3__)
345 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PS3;
346 #elif defined(_3DS)
347 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_CTR;
348 #elif defined(SWITCH)
349 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SWITCH;
350 #elif defined(DINGUX_BETA) && defined(HAVE_ALSA)
351 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ALSA;
352 #elif defined(DINGUX) && defined(HAVE_AL)
353 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_AL;
354 #elif defined(HAVE_PULSE)
355 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_PULSE;
356 #elif defined(HAVE_ALSA) && defined(HAVE_THREADS)
357 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ALSATHREAD;
358 #elif defined(HAVE_ALSA)
359 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ALSA;
360 #elif defined(HAVE_TINYALSA)
361 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_TINYALSA;
362 #elif defined(HAVE_AUDIOIO)
363 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_AUDIOIO;
364 #elif defined(HAVE_OSS)
365 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_OSS;
366 #elif defined(HAVE_JACK)
367 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_JACK;
368 #elif defined(HAVE_COREAUDIO3)
369 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO3;
370 #elif defined(HAVE_COREAUDIO)
371 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO;
372 #elif defined(HAVE_XAUDIO)
373 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_XAUDIO;
374 #elif defined(HAVE_DSOUND)
375 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_DSOUND;
376 #elif defined(HAVE_WASAPI)
377 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_WASAPI;
378 #elif defined(HAVE_AL)
379 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_AL;
380 #elif defined(HAVE_SL)
381 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SL;
382 #elif defined(EMSCRIPTEN)
383 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_RWEBAUDIO;
384 #elif defined(HAVE_SDL)
385 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SDL;
386 #elif defined(HAVE_SDL2)
387 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_SDL2;
388 #elif defined(HAVE_RSOUND)
389 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_RSOUND;
390 #elif defined(HAVE_ROAR)
391 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_ROAR;
392 #elif defined(HAVE_DYLIB) && !defined(ANDROID)
393 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_EXT;
394 #else
395 static const enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_NULL;
396 #endif
397 
398 #if defined(RS90)
399 static const enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_NEAREST;
400 #elif defined(PSP) || defined(EMSCRIPTEN)
401 static const enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_CC;
402 #else
403 static const enum audio_resampler_driver_enum AUDIO_DEFAULT_RESAMPLER_DRIVER = AUDIO_RESAMPLER_SINC;
404 #endif
405 
406 #if defined(HAVE_FFMPEG)
407 static const enum record_driver_enum RECORD_DEFAULT_DRIVER = RECORD_FFMPEG;
408 #else
409 static const enum record_driver_enum RECORD_DEFAULT_DRIVER = RECORD_NULL;
410 #endif
411 
412 #ifdef HAVE_WINMM
413 static const enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_WINMM;
414 #elif defined(HAVE_ALSA) && !defined(HAVE_HAKCHI) && !defined(HAVE_SEGAM) && !defined(DINGUX)
415 static const enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_ALSA;
416 #else
417 static const enum midi_driver_enum MIDI_DEFAULT_DRIVER = MIDI_NULL;
418 #endif
419 
420 #if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
421 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_UWP;
422 #elif defined(XENON)
423 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_XENON360;
424 #elif defined(_XBOX360) || defined(_XBOX) || defined(HAVE_XINPUT2) || defined(HAVE_XINPUT_XBOX1)
425 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_XINPUT;
426 #elif defined(ANDROID)
427 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_ANDROID;
428 #elif defined(EMSCRIPTEN) && defined(HAVE_SDL2)
429 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL2;
430 #elif defined(EMSCRIPTEN)
431 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_RWEBINPUT;
432 #elif defined(_WIN32) && defined(HAVE_DINPUT)
433 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_DINPUT;
434 #elif defined(_WIN32) && !defined(HAVE_DINPUT) && _WIN32_WINNT >= 0x0501
435 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WINRAW;
436 #elif defined(PS2)
437 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS2;
438 #elif defined(__PS3__)
439 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS3;
440 #elif defined(ORBIS)
441 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PS4;
442 #elif defined(PSP) || defined(VITA)
443 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_PSP;
444 #elif defined(_3DS)
445 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_CTR;
446 #elif defined(SWITCH)
447 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SWITCH;
448 #elif defined(GEKKO)
449 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WII;
450 #elif defined(WIIU)
451 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WIIU;
452 #elif defined(DINGUX) && defined(HAVE_SDL_DINGUX)
453 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL_DINGUX;
454 #elif defined(HAVE_X11)
455 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_X;
456 #elif defined(HAVE_UDEV)
457 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_UDEV;
458 #elif defined(__linux__) && !defined(ANDROID)
459 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_LINUXRAW;
460 #elif defined(HAVE_WAYLAND)
461 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WAYLAND;
462 #elif defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH) || defined(HAVE_COCOA_METAL)
463 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_COCOA;
464 #elif defined(__QNX__)
465 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_QNX;
466 #elif defined(HAVE_SDL)
467 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL;
468 #elif defined(HAVE_SDL2)
469 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL2;
470 #elif defined(DJGPP)
471 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_DOS;
472 #else
473 static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_NULL;
474 #endif
475 
476 #if defined(HAVE_XINPUT)
477 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_XINPUT;
478 #elif defined(GEKKO)
479 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_GX;
480 #elif defined(WIIU)
481 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_WIIU;
482 #elif defined(_XBOX)
483 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_XDK;
484 #elif defined(PS2)
485 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS2;
486 #elif defined(__PS3__) || defined(__PSL1GHT__)
487 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS3;
488 #elif defined(ORBIS)
489 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS4;
490 #elif defined(PSP) || defined(VITA)
491 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PSP;
492 #elif defined(_3DS)
493 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_CTR;
494 #elif defined(SWITCH)
495 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SWITCH;
496 #elif defined(DINGUX) && defined(HAVE_SDL_DINGUX)
497 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SDL_DINGUX;
498 #elif defined(HAVE_DINPUT)
499 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_DINPUT;
500 #elif defined(HAVE_UDEV)
501 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_UDEV;
502 #elif defined(__linux) && !defined(ANDROID)
503 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_LINUXRAW;
504 #elif defined(ANDROID)
505 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_ANDROID;
506 #elif defined(HAVE_SDL) || defined(HAVE_SDL2)
507 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SDL;
508 #elif defined(DJGPP)
509 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_DOS;
510 #elif defined(IOS)
511 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_MFI;
512 #elif defined(HAVE_HID)
513 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_HID;
514 #elif defined(__QNX__)
515 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_QNX;
516 #elif defined(EMSCRIPTEN)
517 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_RWEBPAD;
518 #else
519 static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_NULL;
520 #endif
521 
522 #if defined(HAVE_V4L2)
523 static const enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_V4L2;
524 #elif defined(EMSCRIPTEN)
525 static const enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_RWEBCAM;
526 #elif defined(ANDROID)
527 static const enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_ANDROID;
528 #else
529 static const enum camera_driver_enum CAMERA_DEFAULT_DRIVER = CAMERA_NULL;
530 #endif
531 
532 #if defined(HAVE_BLUETOOTH)
533 # if defined(HAVE_DBUS)
534 static const enum bluetooth_driver_enum BLUETOOTH_DEFAULT_DRIVER = BLUETOOTH_BLUEZ;
535 # else
536 static const enum bluetooth_driver_enum BLUETOOTH_DEFAULT_DRIVER = BLUETOOTH_BLUETOOTHCTL;
537 # endif
538 #else
539 static const enum bluetooth_driver_enum BLUETOOTH_DEFAULT_DRIVER = BLUETOOTH_NULL;
540 #endif
541 
542 #if defined(HAVE_LAKKA)
543 static const enum wifi_driver_enum WIFI_DEFAULT_DRIVER = WIFI_CONNMANCTL;
544 #else
545 static const enum wifi_driver_enum WIFI_DEFAULT_DRIVER = WIFI_NULL;
546 #endif
547 
548 #if defined(ANDROID)
549 static const enum location_driver_enum LOCATION_DEFAULT_DRIVER = LOCATION_ANDROID;
550 #else
551 static const enum location_driver_enum LOCATION_DEFAULT_DRIVER = LOCATION_NULL;
552 #endif
553 
554 #if (defined(_3DS) || defined(DINGUX)) && defined(HAVE_RGUI)
555 static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI;
556 #elif defined(HAVE_MATERIALUI) && defined(RARCH_MOBILE)
557 static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_MATERIALUI;
558 #elif defined(HAVE_OZONE)
559 static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_OZONE;
560 #elif defined(HAVE_XMB) && !defined(_XBOX)
561 static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_XMB;
562 #elif defined(HAVE_RGUI)
563 static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI;
564 #else
565 static const enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_NULL;
566 #endif
567 
568 /* All config related settings go here. */
569 
570 struct config_bool_setting
571 {
572    const char *ident;
573    bool *ptr;
574    enum rarch_override_setting override;
575    bool def_enable;
576    bool def;
577    bool handle;
578 };
579 
580 struct config_int_setting
581 {
582    const char *ident;
583    int *ptr;
584    int def;
585    enum rarch_override_setting override;
586    bool def_enable;
587    bool handle;
588 };
589 
590 struct config_uint_setting
591 {
592    const char *ident;
593    unsigned *ptr;
594    unsigned def;
595    enum rarch_override_setting override;
596    bool def_enable;
597    bool handle;
598 };
599 
600 struct config_size_setting
601 {
602    const char *ident;
603    size_t *ptr;
604    size_t def;
605    enum rarch_override_setting override;
606    bool def_enable;
607    bool handle;
608 };
609 
610 struct config_float_setting
611 {
612    const char *ident;
613    float *ptr;
614    float def;
615    enum rarch_override_setting override;
616    bool def_enable;
617    bool handle;
618 };
619 
620 struct config_array_setting
621 {
622    const char *ident;
623    const char *def;
624    char *ptr;
625    enum rarch_override_setting override;
626    bool def_enable;
627    bool handle;
628 };
629 
630 struct config_path_setting
631 {
632    const char *ident;
633    char *ptr;
634    char *def;
635    bool def_enable;
636    bool handle;
637 };
638 
639 
640 #define GENERAL_SETTING(key, configval, default_enable, default_setting, type, handle_setting) \
641 { \
642    tmp[count].ident      = key; \
643    tmp[count].ptr        = configval; \
644    tmp[count].def_enable = default_enable; \
645    if (default_enable) \
646       tmp[count].def     = default_setting; \
647    tmp[count].handle   = handle_setting; \
648    count++; \
649 }
650 
651 #define SETTING_BOOL(key, configval, default_enable, default_setting, handle_setting) \
652    GENERAL_SETTING(key, configval, default_enable, default_setting, struct config_bool_setting, handle_setting)
653 
654 #define SETTING_FLOAT(key, configval, default_enable, default_setting, handle_setting) \
655    GENERAL_SETTING(key, configval, default_enable, default_setting, struct config_float_setting, handle_setting)
656 
657 #define SETTING_INT(key, configval, default_enable, default_setting, handle_setting) \
658    GENERAL_SETTING(key, configval, default_enable, default_setting, struct config_int_setting, handle_setting)
659 
660 #define SETTING_UINT(key, configval, default_enable, default_setting, handle_setting) \
661    GENERAL_SETTING(key, configval, default_enable, default_setting, struct config_uint_setting, handle_setting)
662 
663 #define SETTING_SIZE(key, configval, default_enable, default_setting, handle_setting) \
664    GENERAL_SETTING(key, configval, default_enable, default_setting, struct config_size_setting, handle_setting)
665 
666 #define SETTING_PATH(key, configval, default_enable, default_setting, handle_setting) \
667    GENERAL_SETTING(key, configval, default_enable, default_setting, struct config_path_setting, handle_setting)
668 
669 #define SETTING_ARRAY(key, configval, default_enable, default_setting, handle_setting) \
670    GENERAL_SETTING(key, configval, default_enable, default_setting, struct config_array_setting, handle_setting)
671 
672 #define SETTING_OVERRIDE(override_setting) \
673    tmp[count-1].override = override_setting
674 
675 /* Forward declarations */
676 #ifdef HAVE_CONFIGFILE
677 static void config_parse_file(global_t *global);
678 #endif
679 
680 struct defaults g_defaults;
681 
682 /**
683  * config_get_default_audio:
684  *
685  * Gets default audio driver.
686  *
687  * Returns: Default audio driver.
688  **/
config_get_default_audio(void)689 const char *config_get_default_audio(void)
690 {
691    enum audio_driver_enum default_driver = AUDIO_DEFAULT_DRIVER;
692 
693    switch (default_driver)
694    {
695       case AUDIO_RSOUND:
696          return "rsound";
697       case AUDIO_AUDIOIO:
698          return "audioio";
699       case AUDIO_OSS:
700          return "oss";
701       case AUDIO_ALSA:
702          return "alsa";
703       case AUDIO_ALSATHREAD:
704          return "alsathread";
705       case AUDIO_TINYALSA:
706          return "tinyalsa";
707       case AUDIO_ROAR:
708          return "roar";
709       case AUDIO_COREAUDIO:
710          return "coreaudio";
711       case AUDIO_COREAUDIO3:
712          return "coreaudio3";
713       case AUDIO_AL:
714          return "openal";
715       case AUDIO_SL:
716          return "opensl";
717       case AUDIO_SDL:
718          return "sdl";
719       case AUDIO_SDL2:
720          return "sdl2";
721       case AUDIO_DSOUND:
722          return "dsound";
723       case AUDIO_WASAPI:
724          return "wasapi";
725       case AUDIO_XAUDIO:
726          return "xaudio";
727       case AUDIO_PULSE:
728          return "pulse";
729       case AUDIO_EXT:
730          return "ext";
731       case AUDIO_XENON360:
732          return "xenon360";
733       case AUDIO_PS3:
734          return "ps3";
735       case AUDIO_WII:
736          return "gx";
737       case AUDIO_WIIU:
738          return "AX";
739       case AUDIO_PSP:
740 #if defined(VITA)
741          return "vita";
742 #elif defined(ORBIS)
743          return "orbis";
744 #else
745          return "psp";
746 #endif
747       case AUDIO_PS2:
748          return "ps2";
749       case AUDIO_CTR:
750          return "dsp";
751       case AUDIO_SWITCH:
752 #if defined(HAVE_LIBNX)
753          return "switch_audren_thread";
754 #else
755          return "switch";
756 #endif
757       case AUDIO_RWEBAUDIO:
758          return "rwebaudio";
759       case AUDIO_JACK:
760          return "jack";
761       case AUDIO_NULL:
762          break;
763    }
764 
765    return "null";
766 }
767 
config_get_default_record(void)768 const char *config_get_default_record(void)
769 {
770    enum record_driver_enum default_driver = RECORD_DEFAULT_DRIVER;
771 
772    switch (default_driver)
773    {
774       case RECORD_FFMPEG:
775          return "ffmpeg";
776       case RECORD_NULL:
777          break;
778    }
779 
780    return "null";
781 }
782 
783 /**
784  * config_get_default_audio_resampler:
785  *
786  * Gets default audio resampler driver.
787  *
788  * Returns: Default audio resampler driver.
789  **/
config_get_default_audio_resampler(void)790 const char *config_get_default_audio_resampler(void)
791 {
792    enum audio_resampler_driver_enum default_driver = AUDIO_DEFAULT_RESAMPLER_DRIVER;
793 
794    switch (default_driver)
795    {
796       case AUDIO_RESAMPLER_CC:
797          return "cc";
798       case AUDIO_RESAMPLER_SINC:
799          return "sinc";
800       case AUDIO_RESAMPLER_NEAREST:
801          return "nearest";
802       case AUDIO_RESAMPLER_NULL:
803          break;
804    }
805 
806    return "null";
807 }
808 
809 /**
810  * config_get_default_video:
811  *
812  * Gets default video driver.
813  *
814  * Returns: Default video driver.
815  **/
config_get_default_video(void)816 const char *config_get_default_video(void)
817 {
818    enum video_driver_enum default_driver = VIDEO_DEFAULT_DRIVER;
819 
820    switch (default_driver)
821    {
822       case VIDEO_GL:
823          return "gl";
824       case VIDEO_GL1:
825          return "gl1";
826       case VIDEO_GL_CORE:
827          return "glcore";
828       case VIDEO_VULKAN:
829          return "vulkan";
830       case VIDEO_METAL:
831          return "metal";
832       case VIDEO_DRM:
833          return "drm";
834       case VIDEO_WII:
835          return "gx";
836       case VIDEO_WIIU:
837          return "gx2";
838       case VIDEO_XENON360:
839          return "xenon360";
840       case VIDEO_D3D8:
841          return "d3d8";
842       case VIDEO_D3D9:
843          return "d3d9";
844       case VIDEO_D3D10:
845          return "d3d10";
846       case VIDEO_D3D11:
847          return "d3d11";
848       case VIDEO_D3D12:
849          return "d3d12";
850       case VIDEO_PSP1:
851          return "psp1";
852       case VIDEO_PS2:
853          return "ps2";
854       case VIDEO_VITA2D:
855          return "vita2d";
856       case VIDEO_CTR:
857          return "ctr";
858       case VIDEO_SWITCH:
859          return "switch";
860       case VIDEO_XVIDEO:
861          return "xvideo";
862       case VIDEO_SDL_DINGUX:
863          return "sdl_dingux";
864       case VIDEO_SDL_RS90:
865          return "sdl_rs90";
866       case VIDEO_SDL:
867          return "sdl";
868       case VIDEO_SDL2:
869          return "sdl2";
870       case VIDEO_EXT:
871          return "ext";
872       case VIDEO_VG:
873          return "vg";
874       case VIDEO_OMAP:
875          return "omap";
876       case VIDEO_EXYNOS:
877          return "exynos";
878       case VIDEO_DISPMANX:
879          return "dispmanx";
880       case VIDEO_SUNXI:
881          return "sunxi";
882       case VIDEO_CACA:
883          return "caca";
884       case VIDEO_GDI:
885          return "gdi";
886       case VIDEO_VGA:
887          return "vga";
888       case VIDEO_FPGA:
889          return "fpga";
890       case VIDEO_RSX:
891          return "rsx";
892       case VIDEO_NULL:
893          break;
894    }
895 
896    return "null";
897 }
898 
899 /**
900  * config_get_default_input:
901  *
902  * Gets default input driver.
903  *
904  * Returns: Default input driver.
905  **/
config_get_default_input(void)906 const char *config_get_default_input(void)
907 {
908    enum input_driver_enum default_driver = INPUT_DEFAULT_DRIVER;
909 
910    switch (default_driver)
911    {
912       case INPUT_ANDROID:
913          return "android";
914       case INPUT_PS4:
915          return "ps4";
916       case INPUT_PS3:
917          return "ps3";
918       case INPUT_PSP:
919 #ifdef VITA
920          return "vita";
921 #else
922          return "psp";
923 #endif
924       case INPUT_PS2:
925          return "ps2";
926       case INPUT_CTR:
927          return "ctr";
928       case INPUT_SWITCH:
929          return "switch";
930       case INPUT_SDL:
931          return "sdl";
932       case INPUT_SDL2:
933          return "sdl2";
934       case INPUT_SDL_DINGUX:
935          return "sdl_dingux";
936       case INPUT_DINPUT:
937          return "dinput";
938       case INPUT_WINRAW:
939          return "raw";
940       case INPUT_X:
941          return "x";
942       case INPUT_WAYLAND:
943          return "wayland";
944       case INPUT_XENON360:
945          return "xenon360";
946       case INPUT_XINPUT:
947          return "xinput";
948       case INPUT_UWP:
949          return "uwp";
950       case INPUT_WII:
951          return "gx";
952       case INPUT_WIIU:
953          return "wiiu";
954       case INPUT_LINUXRAW:
955          return "linuxraw";
956       case INPUT_UDEV:
957          return "udev";
958       case INPUT_COCOA:
959          return "cocoa";
960       case INPUT_QNX:
961           return "qnx_input";
962       case INPUT_RWEBINPUT:
963           return "rwebinput";
964       case INPUT_DOS:
965          return "dos";
966       case INPUT_NULL:
967           break;
968    }
969 
970    return "null";
971 }
972 
973 /**
974  * config_get_default_joypad:
975  *
976  * Gets default input joypad driver.
977  *
978  * Returns: Default input joypad driver.
979  **/
config_get_default_joypad(void)980 const char *config_get_default_joypad(void)
981 {
982    enum joypad_driver_enum default_driver = JOYPAD_DEFAULT_DRIVER;
983 
984    switch (default_driver)
985    {
986       case JOYPAD_PS4:
987          return "ps4";
988       case JOYPAD_PS3:
989          return "ps3";
990       case JOYPAD_XINPUT:
991          return "xinput";
992       case JOYPAD_GX:
993          return "gx";
994       case JOYPAD_WIIU:
995          return "wiiu";
996       case JOYPAD_XDK:
997          return "xdk";
998       case JOYPAD_PSP:
999 #ifdef VITA
1000          return "vita";
1001 #else
1002          return "psp";
1003 #endif
1004       case JOYPAD_PS2:
1005          return "ps2";
1006       case JOYPAD_CTR:
1007          return "ctr";
1008       case JOYPAD_SWITCH:
1009          return "switch";
1010       case JOYPAD_DINPUT:
1011          return "dinput";
1012       case JOYPAD_UDEV:
1013          return "udev";
1014       case JOYPAD_LINUXRAW:
1015          return "linuxraw";
1016       case JOYPAD_ANDROID:
1017          return "android";
1018       case JOYPAD_SDL:
1019 #ifdef HAVE_SDL2
1020          return "sdl2";
1021 #else
1022          return "sdl";
1023 #endif
1024       case JOYPAD_SDL_DINGUX:
1025          return "sdl_dingux";
1026       case JOYPAD_HID:
1027          return "hid";
1028       case JOYPAD_QNX:
1029          return "qnx";
1030       case JOYPAD_RWEBPAD:
1031          return "rwebpad";
1032       case JOYPAD_DOS:
1033          return "dos";
1034       case JOYPAD_MFI:
1035          return "mfi";
1036       case JOYPAD_NULL:
1037          break;
1038    }
1039 
1040    return "null";
1041 }
1042 
1043 /**
1044  * config_get_default_camera:
1045  *
1046  * Gets default camera driver.
1047  *
1048  * Returns: Default camera driver.
1049  **/
config_get_default_camera(void)1050 const char *config_get_default_camera(void)
1051 {
1052    enum camera_driver_enum default_driver = CAMERA_DEFAULT_DRIVER;
1053 
1054    switch (default_driver)
1055    {
1056       case CAMERA_V4L2:
1057          return "video4linux2";
1058       case CAMERA_RWEBCAM:
1059          return "rwebcam";
1060       case CAMERA_ANDROID:
1061          return "android";
1062       case CAMERA_AVFOUNDATION:
1063          return "avfoundation";
1064       case CAMERA_NULL:
1065          break;
1066    }
1067 
1068    return "null";
1069 }
1070 
1071 /**
1072  * config_get_default_bluetooth:
1073  *
1074  * Gets default bluetooth driver.
1075  *
1076  * Returns: Default bluetooth driver.
1077  **/
config_get_default_bluetooth(void)1078 const char *config_get_default_bluetooth(void)
1079 {
1080    enum bluetooth_driver_enum default_driver = BLUETOOTH_DEFAULT_DRIVER;
1081 
1082    switch (default_driver)
1083    {
1084       case BLUETOOTH_BLUETOOTHCTL:
1085          return "bluetoothctl";
1086       case BLUETOOTH_BLUEZ:
1087          return "bluez";
1088       case BLUETOOTH_NULL:
1089          break;
1090    }
1091 
1092    return "null";
1093 }
1094 
1095 /**
1096  * config_get_default_wifi:
1097  *
1098  * Gets default wifi driver.
1099  *
1100  * Returns: Default wifi driver.
1101  **/
config_get_default_wifi(void)1102 const char *config_get_default_wifi(void)
1103 {
1104    enum wifi_driver_enum default_driver = WIFI_DEFAULT_DRIVER;
1105 
1106    switch (default_driver)
1107    {
1108       case WIFI_CONNMANCTL:
1109          return "connmanctl";
1110       case WIFI_NMCLI:
1111          return "nmcli";
1112       case WIFI_NULL:
1113          break;
1114    }
1115 
1116    return "null";
1117 }
1118 
1119 /**
1120  * config_get_default_led:
1121  *
1122  * Gets default led driver.
1123  *
1124  * Returns: Default led driver.
1125  **/
config_get_default_led(void)1126 const char *config_get_default_led(void)
1127 {
1128    return "null";
1129 }
1130 
1131 /**
1132  * config_get_default_location:
1133  *
1134  * Gets default location driver.
1135  *
1136  * Returns: Default location driver.
1137  **/
config_get_default_location(void)1138 const char *config_get_default_location(void)
1139 {
1140    enum location_driver_enum default_driver = LOCATION_DEFAULT_DRIVER;
1141 
1142    switch (default_driver)
1143    {
1144       case LOCATION_ANDROID:
1145          return "android";
1146       case LOCATION_CORELOCATION:
1147          return "corelocation";
1148       case LOCATION_NULL:
1149          break;
1150    }
1151 
1152    return "null";
1153 }
1154 
1155 /**
1156  * config_get_default_menu:
1157  *
1158  * Gets default menu driver.
1159  *
1160  * Returns: Default menu driver.
1161  **/
config_get_default_menu(void)1162 const char *config_get_default_menu(void)
1163 {
1164 #ifdef HAVE_MENU
1165    enum menu_driver_enum default_driver = MENU_DEFAULT_DRIVER;
1166 
1167    if (!string_is_empty(g_defaults.settings_menu))
1168       return g_defaults.settings_menu;
1169 
1170    switch (default_driver)
1171    {
1172       case MENU_RGUI:
1173          return "rgui";
1174       case MENU_OZONE:
1175          return "ozone";
1176       case MENU_MATERIALUI:
1177          return "glui";
1178       case MENU_XMB:
1179          return "xmb";
1180       case MENU_STRIPES:
1181          return "stripes";
1182       case MENU_NULL:
1183          break;
1184    }
1185 #endif
1186 
1187    return "null";
1188 }
1189 
config_get_default_midi(void)1190 const char *config_get_default_midi(void)
1191 {
1192    enum midi_driver_enum default_driver = MIDI_DEFAULT_DRIVER;
1193 
1194    switch (default_driver)
1195    {
1196       case MIDI_WINMM:
1197          return "winmm";
1198       case MIDI_ALSA:
1199          return "alsa";
1200       case MIDI_NULL:
1201          break;
1202    }
1203 
1204    return "null";
1205 }
1206 
config_get_midi_driver_options(void)1207 const char *config_get_midi_driver_options(void)
1208 {
1209    return char_list_new_special(STRING_LIST_MIDI_DRIVERS, NULL);
1210 }
1211 
1212 #ifdef HAVE_LAKKA
config_set_timezone(char * timezone)1213 void config_set_timezone(char *timezone)
1214 {
1215    setenv("TZ", timezone, 1);
1216    tzset();
1217 }
1218 
config_get_all_timezones(void)1219 const char *config_get_all_timezones(void)
1220 {
1221    return char_list_new_special(STRING_LIST_TIMEZONES, NULL);
1222 }
1223 
load_timezone(char * setting)1224 static void load_timezone(char *setting)
1225 {
1226    char haystack[TIMEZONE_LENGTH+32];
1227    static char *needle = "TIMEZONE=";
1228    size_t needle_len = strlen(needle);
1229 
1230    RFILE *tzfp = filestream_open(LAKKA_TIMEZONE_PATH,
1231                        RETRO_VFS_FILE_ACCESS_READ,
1232                        RETRO_VFS_FILE_ACCESS_HINT_NONE);
1233 
1234    if (tzfp != NULL)
1235    {
1236       filestream_gets(tzfp, haystack, sizeof(haystack)-1);
1237       filestream_close(tzfp);
1238 
1239       char *start = strstr(haystack, needle);
1240 
1241       if (start != NULL)
1242          snprintf(setting, TIMEZONE_LENGTH, "%s", start + needle_len);
1243       else
1244          snprintf(setting, TIMEZONE_LENGTH, "%s", DEFAULT_TIMEZONE);
1245    }
1246    else
1247       snprintf(setting, TIMEZONE_LENGTH, "%s", DEFAULT_TIMEZONE);
1248 
1249    config_set_timezone(setting);
1250 }
1251 #endif
1252 
config_overlay_enable_default(void)1253 bool config_overlay_enable_default(void)
1254 {
1255    if (g_defaults.overlay_set)
1256       return g_defaults.overlay_enable;
1257    return true;
1258 }
1259 
populate_settings_array(settings_t * settings,int * size)1260 static struct config_array_setting *populate_settings_array(settings_t *settings, int *size)
1261 {
1262    unsigned count                        = 0;
1263    struct config_array_setting  *tmp    = (struct config_array_setting*)calloc(1, (*size + 1) * sizeof(struct config_array_setting));
1264 
1265    if (!tmp)
1266       return NULL;
1267 
1268    /* Arrays */
1269    SETTING_ARRAY("video_driver",             settings->arrays.video_driver,   false, NULL, true);
1270    SETTING_ARRAY("record_driver",            settings->arrays.record_driver,  false, NULL, true);
1271    SETTING_ARRAY("camera_driver",            settings->arrays.camera_driver,  false, NULL, true);
1272    SETTING_ARRAY("bluetooth_driver",         settings->arrays.bluetooth_driver, false, NULL, true);
1273    SETTING_ARRAY("wifi_driver",              settings->arrays.wifi_driver,    false, NULL, true);
1274    SETTING_ARRAY("location_driver",          settings->arrays.location_driver,false, NULL, true);
1275 #ifdef HAVE_MENU
1276    SETTING_ARRAY("menu_driver",              settings->arrays.menu_driver,    false, NULL, true);
1277 #endif
1278    SETTING_ARRAY("audio_device",             settings->arrays.audio_device,   false, NULL, true);
1279    SETTING_ARRAY("camera_device",            settings->arrays.camera_device,  false, NULL, true);
1280 #ifdef HAVE_CHEEVOS
1281    SETTING_ARRAY("cheevos_username",         settings->arrays.cheevos_username, false, NULL, true);
1282    SETTING_ARRAY("cheevos_password",         settings->arrays.cheevos_password, false, NULL, true);
1283    SETTING_ARRAY("cheevos_token",            settings->arrays.cheevos_token, false, NULL, true);
1284    SETTING_ARRAY("cheevos_leaderboards_enable", settings->arrays.cheevos_leaderboards_enable, true, "false", true);
1285 #endif
1286    SETTING_ARRAY("video_context_driver",     settings->arrays.video_context_driver,   false, NULL, true);
1287    SETTING_ARRAY("audio_driver",             settings->arrays.audio_driver,           false, NULL, true);
1288    SETTING_ARRAY("audio_resampler",          settings->arrays.audio_resampler,        false, NULL, true);
1289    SETTING_ARRAY("input_driver",             settings->arrays.input_driver,           false, NULL, true);
1290    SETTING_ARRAY("input_joypad_driver",      settings->arrays.input_joypad_driver,    false, NULL, true);
1291    SETTING_ARRAY("input_keyboard_layout",    settings->arrays.input_keyboard_layout,  false, NULL, true);
1292    SETTING_ARRAY("bundle_assets_src_path",   settings->arrays.bundle_assets_src, false, NULL, true);
1293    SETTING_ARRAY("bundle_assets_dst_path",   settings->arrays.bundle_assets_dst, false, NULL, true);
1294    SETTING_ARRAY("bundle_assets_dst_path_subdir", settings->arrays.bundle_assets_dst_subdir, false, NULL, true);
1295    SETTING_ARRAY("led_driver",               settings->arrays.led_driver, false, NULL, true);
1296    SETTING_ARRAY("netplay_mitm_server",      settings->arrays.netplay_mitm_server, false, NULL, true);
1297    SETTING_ARRAY("midi_driver",              settings->arrays.midi_driver, false, NULL, true);
1298    SETTING_ARRAY("midi_input",               settings->arrays.midi_input, true, DEFAULT_MIDI_INPUT, true);
1299    SETTING_ARRAY("midi_output",              settings->arrays.midi_output, true, DEFAULT_MIDI_OUTPUT, true);
1300    SETTING_ARRAY("youtube_stream_key",       settings->arrays.youtube_stream_key, true, NULL, true);
1301    SETTING_ARRAY("twitch_stream_key",       settings->arrays.twitch_stream_key, true, NULL, true);
1302    SETTING_ARRAY("facebook_stream_key",      settings->arrays.facebook_stream_key, true, NULL, true);
1303    SETTING_ARRAY("discord_app_id",           settings->arrays.discord_app_id, true, DEFAULT_DISCORD_APP_ID, true);
1304    SETTING_ARRAY("ai_service_url",           settings->arrays.ai_service_url, true, DEFAULT_AI_SERVICE_URL, true);
1305    SETTING_ARRAY("crt_switch_timings",       settings->arrays.crt_switch_timings, false, NULL, true);
1306 #ifdef HAVE_LAKKA
1307    SETTING_ARRAY("cpu_main_gov",             settings->arrays.cpu_main_gov, false, NULL, true);
1308    SETTING_ARRAY("cpu_menu_gov",             settings->arrays.cpu_menu_gov, false, NULL, true);
1309 #endif
1310 
1311    *size = count;
1312 
1313    return tmp;
1314 }
1315 
populate_settings_path(settings_t * settings,int * size)1316 static struct config_path_setting *populate_settings_path(
1317       settings_t *settings, int *size)
1318 {
1319    unsigned count = 0;
1320    struct config_path_setting  *tmp    = (struct config_path_setting*)calloc(1, (*size + 1) * sizeof(struct config_path_setting));
1321 
1322    if (!tmp)
1323       return NULL;
1324 
1325    /* Paths */
1326 #ifdef HAVE_XMB
1327    SETTING_PATH("xmb_font",                   settings->paths.path_menu_xmb_font, false, NULL, true);
1328 #endif
1329    SETTING_PATH("content_show_settings_password", settings->paths.menu_content_show_settings_password, false, NULL, true);
1330    SETTING_PATH("kiosk_mode_password",        settings->paths.kiosk_mode_password, false, NULL, true);
1331    SETTING_PATH("netplay_nickname",           settings->paths.username, false, NULL, true);
1332    SETTING_PATH("video_filter",               settings->paths.path_softfilter_plugin, false, NULL, true);
1333    SETTING_PATH("audio_dsp_plugin",           settings->paths.path_audio_dsp_plugin, false, NULL, true);
1334    SETTING_PATH("core_updater_buildbot_cores_url", settings->paths.network_buildbot_url, false, NULL, true);
1335    SETTING_PATH("core_updater_buildbot_assets_url", settings->paths.network_buildbot_assets_url, false, NULL, true);
1336 #ifdef HAVE_NETWORKING
1337    SETTING_PATH("netplay_ip_address",       settings->paths.netplay_server, false, NULL, true);
1338    SETTING_PATH("netplay_password",           settings->paths.netplay_password, false, NULL, true);
1339    SETTING_PATH("netplay_spectate_password",  settings->paths.netplay_spectate_password, false, NULL, true);
1340 #endif
1341    SETTING_PATH("libretro_directory",
1342          settings->paths.directory_libretro, false, NULL, false);
1343    SETTING_PATH("core_options_path",
1344          settings->paths.path_core_options, false, NULL, true);
1345    SETTING_PATH("libretro_info_path",
1346          settings->paths.path_libretro_info, false, NULL, true);
1347    SETTING_PATH("content_database_path",
1348          settings->paths.path_content_database, false, NULL, true);
1349    SETTING_PATH("cheat_database_path",
1350          settings->paths.path_cheat_database, false, NULL, true);
1351 #ifdef HAVE_MENU
1352    SETTING_PATH("menu_wallpaper",
1353          settings->paths.path_menu_wallpaper, false, NULL, true);
1354    SETTING_PATH("rgui_menu_theme_preset",
1355          settings->paths.path_rgui_theme_preset, false, NULL, true);
1356 #endif
1357    SETTING_PATH("content_favorites_path",
1358          settings->paths.path_content_favorites, false, NULL, true);
1359    SETTING_PATH("content_history_path",
1360          settings->paths.path_content_history, false, NULL, true);
1361    SETTING_PATH("content_image_history_path",
1362          settings->paths.path_content_image_history, false, NULL, true);
1363    SETTING_PATH("content_music_history_path",
1364          settings->paths.path_content_music_history, false, NULL, true);
1365    SETTING_PATH("content_video_history_path",
1366          settings->paths.path_content_video_history, false, NULL, true);
1367 #ifdef HAVE_OVERLAY
1368    SETTING_PATH("input_overlay",
1369          settings->paths.path_overlay, false, NULL, true);
1370 #endif
1371 #ifdef HAVE_VIDEO_LAYOUT
1372    SETTING_PATH("video_layout_path",
1373          settings->paths.path_video_layout, false, NULL, true);
1374    SETTING_PATH("video_layout_directory",
1375          settings->paths.directory_video_layout, true, NULL, true);
1376 #endif
1377    SETTING_PATH("video_record_config",
1378          settings->paths.path_record_config, false, NULL, true);
1379    SETTING_PATH("video_stream_config",
1380          settings->paths.path_stream_config, false, NULL, true);
1381    SETTING_PATH("video_stream_url",
1382          settings->paths.path_stream_url, false, NULL, true);
1383    SETTING_PATH("video_font_path",
1384          settings->paths.path_font, false, NULL, true);
1385    SETTING_PATH("cursor_directory",
1386          settings->paths.directory_cursor, false, NULL, true);
1387    SETTING_PATH("screenshot_directory",
1388          settings->paths.directory_screenshot, true, NULL, true);
1389    SETTING_PATH("system_directory",
1390          settings->paths.directory_system, true, NULL, true);
1391    SETTING_PATH("cache_directory",
1392          settings->paths.directory_cache, false, NULL, true);
1393    SETTING_PATH("input_remapping_directory",
1394          settings->paths.directory_input_remapping, false, NULL, true);
1395    SETTING_PATH("resampler_directory",
1396          settings->paths.directory_resampler, false, NULL, true);
1397    SETTING_PATH("video_shader_dir",
1398          settings->paths.directory_video_shader, true, NULL, true);
1399    SETTING_PATH("video_filter_dir",
1400          settings->paths.directory_video_filter, true, NULL, true);
1401    SETTING_PATH("core_assets_directory",
1402          settings->paths.directory_core_assets, true, NULL, true);
1403    SETTING_PATH("assets_directory",
1404          settings->paths.directory_assets, true, NULL, true);
1405    SETTING_PATH("dynamic_wallpapers_directory",
1406          settings->paths.directory_dynamic_wallpapers, true, NULL, true);
1407    SETTING_PATH("thumbnails_directory",
1408          settings->paths.directory_thumbnails, true, NULL, true);
1409    SETTING_PATH("playlist_directory",
1410          settings->paths.directory_playlist, true, NULL, true);
1411    SETTING_PATH("content_favorites_directory",
1412          settings->paths.directory_content_favorites, true, NULL, true);
1413    SETTING_PATH("content_history_directory",
1414          settings->paths.directory_content_history, true, NULL, true);
1415    SETTING_PATH("content_image_history_directory",
1416          settings->paths.directory_content_image_history, true, NULL, true);
1417    SETTING_PATH("content_music_history_directory",
1418          settings->paths.directory_content_music_history, true, NULL, true);
1419    SETTING_PATH("content_video_directory",
1420          settings->paths.directory_content_video_history, true, NULL, true);
1421    SETTING_PATH("runtime_log_directory",
1422          settings->paths.directory_runtime_log, true, NULL, true);
1423    SETTING_PATH("joypad_autoconfig_dir",
1424          settings->paths.directory_autoconfig, false, NULL, true);
1425    SETTING_PATH("audio_filter_dir",
1426          settings->paths.directory_audio_filter, true, NULL, true);
1427    SETTING_PATH("savefile_directory",
1428          dir_get_ptr(RARCH_DIR_SAVEFILE), true, NULL, false);
1429    SETTING_PATH("savestate_directory",
1430          dir_get_ptr(RARCH_DIR_SAVESTATE), true, NULL, false);
1431 #ifdef HAVE_MENU
1432    SETTING_PATH("rgui_browser_directory",
1433          settings->paths.directory_menu_content, true, NULL, true);
1434    SETTING_PATH("rgui_config_directory",
1435          settings->paths.directory_menu_config, true, NULL, true);
1436 #endif
1437 #ifdef HAVE_OVERLAY
1438    SETTING_PATH("overlay_directory",
1439          settings->paths.directory_overlay, true, NULL, true);
1440 #endif
1441 #ifdef HAVE_VIDEO_LAYOUT
1442    SETTING_PATH("video_layout_directory",
1443          settings->paths.directory_video_layout, true, NULL, true);
1444 #endif
1445    SETTING_PATH(
1446          "screenshot_directory",
1447          settings->paths.directory_screenshot, true, NULL, false);
1448 
1449    {
1450       global_t   *global                  = global_get_ptr();
1451       if (global)
1452       {
1453          SETTING_PATH("recording_output_directory",
1454                global->record.output_dir, false, NULL, true);
1455          SETTING_PATH("recording_config_directory",
1456                global->record.config_dir, false, NULL, true);
1457       }
1458    }
1459 
1460    SETTING_ARRAY("log_dir", settings->paths.log_dir, true, NULL, true);
1461 
1462    *size = count;
1463 
1464    return tmp;
1465 }
1466 
populate_settings_bool(settings_t * settings,int * size)1467 static struct config_bool_setting *populate_settings_bool(
1468       settings_t *settings, int *size)
1469 {
1470    struct config_bool_setting  *tmp    = (struct config_bool_setting*)calloc(1, (*size + 1) * sizeof(struct config_bool_setting));
1471    unsigned count                      = 0;
1472 
1473    SETTING_BOOL("accessibility_enable", &settings->bools.accessibility_enable, true, DEFAULT_ACCESSIBILITY_ENABLE, false);
1474    SETTING_BOOL("driver_switch_enable", &settings->bools.driver_switch_enable, true, DEFAULT_DRIVER_SWITCH_ENABLE, false);
1475    SETTING_BOOL("frame_time_counter_reset_after_fastforwarding", &settings->bools.frame_time_counter_reset_after_fastforwarding, true, false, false);
1476    SETTING_BOOL("frame_time_counter_reset_after_load_state", &settings->bools.frame_time_counter_reset_after_load_state, true, false, false);
1477    SETTING_BOOL("frame_time_counter_reset_after_save_state", &settings->bools.frame_time_counter_reset_after_save_state, true, false, false);
1478    SETTING_BOOL("crt_switch_resolution_use_custom_refresh_rate", &settings->bools.crt_switch_custom_refresh_enable, true, false, false);
1479    SETTING_BOOL("crt_switch_hires_menu", &settings->bools.crt_switch_hires_menu, true, false, true);
1480    SETTING_BOOL("ui_companion_start_on_boot",    &settings->bools.ui_companion_start_on_boot, true, ui_companion_start_on_boot, false);
1481    SETTING_BOOL("ui_companion_enable",           &settings->bools.ui_companion_enable, true, ui_companion_enable, false);
1482    SETTING_BOOL("ui_companion_toggle",           &settings->bools.ui_companion_toggle, false, ui_companion_toggle, false);
1483    SETTING_BOOL("desktop_menu_enable",           &settings->bools.desktop_menu_enable, true, DEFAULT_DESKTOP_MENU_ENABLE, false);
1484    SETTING_BOOL("video_gpu_record",              &settings->bools.video_gpu_record, true, DEFAULT_GPU_RECORD, false);
1485    SETTING_BOOL("input_remap_binds_enable",      &settings->bools.input_remap_binds_enable, true, true, false);
1486    SETTING_BOOL("menu_swap_ok_cancel_buttons",   &settings->bools.input_menu_swap_ok_cancel_buttons, true, DEFAULT_MENU_SWAP_OK_CANCEL_BUTTONS, false);
1487 #ifdef HAVE_NETWORKING
1488    SETTING_BOOL("netplay_public_announce",       &settings->bools.netplay_public_announce, true, DEFAULT_NETPLAY_PUBLIC_ANNOUNCE, false);
1489    SETTING_BOOL("netplay_start_as_spectator",    &settings->bools.netplay_start_as_spectator, false, netplay_start_as_spectator, false);
1490    SETTING_BOOL("netplay_allow_slaves",          &settings->bools.netplay_allow_slaves, true, netplay_allow_slaves, false);
1491    SETTING_BOOL("netplay_require_slaves",        &settings->bools.netplay_require_slaves, true, netplay_require_slaves, false);
1492    SETTING_BOOL("netplay_stateless_mode",        &settings->bools.netplay_stateless_mode, true, netplay_stateless_mode, false);
1493    SETTING_OVERRIDE(RARCH_OVERRIDE_SETTING_NETPLAY_STATELESS_MODE);
1494    SETTING_BOOL("netplay_use_mitm_server",       &settings->bools.netplay_use_mitm_server, true, netplay_use_mitm_server, false);
1495    SETTING_BOOL("netplay_request_device_p1",     &settings->bools.netplay_request_devices[0], true, false, false);
1496    SETTING_BOOL("netplay_request_device_p2",     &settings->bools.netplay_request_devices[1], true, false, false);
1497    SETTING_BOOL("netplay_request_device_p3",     &settings->bools.netplay_request_devices[2], true, false, false);
1498    SETTING_BOOL("netplay_request_device_p4",     &settings->bools.netplay_request_devices[3], true, false, false);
1499    SETTING_BOOL("netplay_request_device_p5",     &settings->bools.netplay_request_devices[4], true, false, false);
1500    SETTING_BOOL("netplay_request_device_p6",     &settings->bools.netplay_request_devices[5], true, false, false);
1501    SETTING_BOOL("netplay_request_device_p7",     &settings->bools.netplay_request_devices[6], true, false, false);
1502    SETTING_BOOL("netplay_request_device_p8",     &settings->bools.netplay_request_devices[7], true, false, false);
1503    SETTING_BOOL("netplay_request_device_p9",     &settings->bools.netplay_request_devices[8], true, false, false);
1504    SETTING_BOOL("netplay_request_device_p10",    &settings->bools.netplay_request_devices[9], true, false, false);
1505    SETTING_BOOL("netplay_request_device_p11",    &settings->bools.netplay_request_devices[10], true, false, false);
1506    SETTING_BOOL("netplay_request_device_p12",    &settings->bools.netplay_request_devices[11], true, false, false);
1507    SETTING_BOOL("netplay_request_device_p13",    &settings->bools.netplay_request_devices[12], true, false, false);
1508    SETTING_BOOL("netplay_request_device_p14",    &settings->bools.netplay_request_devices[13], true, false, false);
1509    SETTING_BOOL("netplay_request_device_p15",    &settings->bools.netplay_request_devices[14], true, false, false);
1510    SETTING_BOOL("netplay_request_device_p16",    &settings->bools.netplay_request_devices[15], true, false, false);
1511    SETTING_BOOL("network_on_demand_thumbnails",  &settings->bools.network_on_demand_thumbnails, true, DEFAULT_NETWORK_ON_DEMAND_THUMBNAILS, false);
1512 #endif
1513    SETTING_BOOL("input_descriptor_label_show",   &settings->bools.input_descriptor_label_show, true, input_descriptor_label_show, false);
1514    SETTING_BOOL("input_descriptor_hide_unbound", &settings->bools.input_descriptor_hide_unbound, true, input_descriptor_hide_unbound, false);
1515    SETTING_BOOL("load_dummy_on_core_shutdown",   &settings->bools.load_dummy_on_core_shutdown, true, DEFAULT_LOAD_DUMMY_ON_CORE_SHUTDOWN, false);
1516    SETTING_BOOL("check_firmware_before_loading", &settings->bools.check_firmware_before_loading, true, DEFAULT_CHECK_FIRMWARE_BEFORE_LOADING, false);
1517    SETTING_BOOL("core_info_cache_enable",        &settings->bools.core_info_cache_enable, true, DEFAULT_CORE_INFO_CACHE_ENABLE, false);
1518 #ifndef HAVE_DYNAMIC
1519    SETTING_BOOL("always_reload_core_on_run_content", &settings->bools.always_reload_core_on_run_content, true, DEFAULT_ALWAYS_RELOAD_CORE_ON_RUN_CONTENT, false);
1520 #endif
1521    SETTING_BOOL("builtin_mediaplayer_enable",    &settings->bools.multimedia_builtin_mediaplayer_enable, true, DEFAULT_BUILTIN_MEDIAPLAYER_ENABLE, false);
1522    SETTING_BOOL("builtin_imageviewer_enable",    &settings->bools.multimedia_builtin_imageviewer_enable, true, DEFAULT_BUILTIN_IMAGEVIEWER_ENABLE, false);
1523    SETTING_BOOL("fps_show",                      &settings->bools.video_fps_show, true, DEFAULT_FPS_SHOW, false);
1524    SETTING_BOOL("statistics_show",               &settings->bools.video_statistics_show, true, DEFAULT_STATISTICS_SHOW, false);
1525    SETTING_BOOL("framecount_show",               &settings->bools.video_framecount_show, true, DEFAULT_FRAMECOUNT_SHOW, false);
1526    SETTING_BOOL("memory_show",                   &settings->bools.video_memory_show, true, DEFAULT_MEMORY_SHOW, false);
1527    SETTING_BOOL("ui_menubar_enable",             &settings->bools.ui_menubar_enable, true, DEFAULT_UI_MENUBAR_ENABLE, false);
1528    SETTING_BOOL("suspend_screensaver_enable",    &settings->bools.ui_suspend_screensaver_enable, true, true, false);
1529    SETTING_BOOL("rewind_enable",                 &settings->bools.rewind_enable, true, DEFAULT_REWIND_ENABLE, false);
1530    SETTING_BOOL("vrr_runloop_enable",            &settings->bools.vrr_runloop_enable, true, DEFAULT_VRR_RUNLOOP_ENABLE, false);
1531    SETTING_BOOL("apply_cheats_after_toggle",     &settings->bools.apply_cheats_after_toggle, true, DEFAULT_APPLY_CHEATS_AFTER_TOGGLE, false);
1532    SETTING_BOOL("apply_cheats_after_load",       &settings->bools.apply_cheats_after_load, true, DEFAULT_APPLY_CHEATS_AFTER_LOAD, false);
1533    SETTING_BOOL("run_ahead_enabled",             &settings->bools.run_ahead_enabled, true, false, false);
1534    SETTING_BOOL("run_ahead_secondary_instance",  &settings->bools.run_ahead_secondary_instance, true, DEFAULT_RUN_AHEAD_SECONDARY_INSTANCE, false);
1535    SETTING_BOOL("run_ahead_hide_warnings",       &settings->bools.run_ahead_hide_warnings, true, DEFAULT_RUN_AHEAD_HIDE_WARNINGS, false);
1536    SETTING_BOOL("audio_sync",                    &settings->bools.audio_sync, true, DEFAULT_AUDIO_SYNC, false);
1537    SETTING_BOOL("video_shader_enable",           &settings->bools.video_shader_enable, true, DEFAULT_SHADER_ENABLE, false);
1538    SETTING_BOOL("video_shader_watch_files",      &settings->bools.video_shader_watch_files, true, DEFAULT_VIDEO_SHADER_WATCH_FILES, false);
1539    SETTING_BOOL("video_shader_remember_last_dir", &settings->bools.video_shader_remember_last_dir, true, DEFAULT_VIDEO_SHADER_REMEMBER_LAST_DIR, false);
1540    SETTING_BOOL("video_shader_preset_save_reference_enable",   &settings->bools.video_shader_preset_save_reference_enable, true, DEFAULT_VIDEO_SHADER_PRESET_SAVE_REFERENCE_ENABLE, false);
1541 
1542    /* Let implementation decide if automatic, or 1:1 PAR. */
1543    SETTING_BOOL("video_aspect_ratio_auto",       &settings->bools.video_aspect_ratio_auto, true, DEFAULT_ASPECT_RATIO_AUTO, false);
1544 
1545    SETTING_BOOL("video_allow_rotate",            &settings->bools.video_allow_rotate, true, DEFAULT_ALLOW_ROTATE, false);
1546    SETTING_BOOL("video_windowed_fullscreen",     &settings->bools.video_windowed_fullscreen, true, DEFAULT_WINDOWED_FULLSCREEN, false);
1547    SETTING_BOOL("video_crop_overscan",           &settings->bools.video_crop_overscan, true, DEFAULT_CROP_OVERSCAN, false);
1548    SETTING_BOOL("video_scale_integer",           &settings->bools.video_scale_integer, true, DEFAULT_SCALE_INTEGER, false);
1549    SETTING_BOOL("video_scale_integer_overscale", &settings->bools.video_scale_integer_overscale, true, DEFAULT_SCALE_INTEGER_OVERSCALE, false);
1550    SETTING_BOOL("video_smooth",                  &settings->bools.video_smooth, true, DEFAULT_VIDEO_SMOOTH, false);
1551    SETTING_BOOL("video_ctx_scaling",              &settings->bools.video_ctx_scaling, true, DEFAULT_VIDEO_CTX_SCALING, false);
1552    SETTING_BOOL("video_force_aspect",            &settings->bools.video_force_aspect, true, DEFAULT_FORCE_ASPECT, false);
1553 #if defined(DINGUX)
1554    SETTING_BOOL("video_dingux_ipu_keep_aspect",  &settings->bools.video_dingux_ipu_keep_aspect, true, DEFAULT_DINGUX_IPU_KEEP_ASPECT, false);
1555 #endif
1556    SETTING_BOOL("video_threaded",                video_driver_get_threaded(), true, DEFAULT_VIDEO_THREADED, false);
1557    SETTING_BOOL("video_shared_context",          &settings->bools.video_shared_context, true, DEFAULT_VIDEO_SHARED_CONTEXT, false);
1558    SETTING_BOOL("auto_screenshot_filename",      &settings->bools.auto_screenshot_filename, true, DEFAULT_AUTO_SCREENSHOT_FILENAME, false);
1559    SETTING_BOOL("video_force_srgb_disable",      &settings->bools.video_force_srgb_disable, true, false, false);
1560    SETTING_BOOL("video_fullscreen",              &settings->bools.video_fullscreen, true, DEFAULT_FULLSCREEN, false);
1561 #ifdef __WINRT__
1562    SETTING_BOOL("video_force_resolution",         &settings->bools.video_force_resolution, true, DEFAULT_FORCE_RESOLUTION, false);
1563 #endif
1564    SETTING_BOOL("bundle_assets_extract_enable",  &settings->bools.bundle_assets_extract_enable, true, DEFAULT_BUNDLE_ASSETS_EXTRACT_ENABLE, false);
1565    SETTING_BOOL("video_vsync",                   &settings->bools.video_vsync, true, DEFAULT_VSYNC, false);
1566    SETTING_BOOL("video_adaptive_vsync",          &settings->bools.video_adaptive_vsync, true, DEFAULT_ADAPTIVE_VSYNC, false);
1567    SETTING_BOOL("video_hard_sync",               &settings->bools.video_hard_sync, true, DEFAULT_HARD_SYNC, false);
1568    SETTING_BOOL("video_disable_composition",     &settings->bools.video_disable_composition, true, DEFAULT_DISABLE_COMPOSITION, false);
1569    SETTING_BOOL("pause_nonactive",               &settings->bools.pause_nonactive, true, DEFAULT_PAUSE_NONACTIVE, false);
1570    SETTING_BOOL("video_gpu_screenshot",          &settings->bools.video_gpu_screenshot, true, DEFAULT_GPU_SCREENSHOT, false);
1571    SETTING_BOOL("video_post_filter_record",      &settings->bools.video_post_filter_record, true, DEFAULT_POST_FILTER_RECORD, false);
1572    SETTING_BOOL("video_notch_write_over_enable", &settings->bools.video_notch_write_over_enable, true, DEFAULT_NOTCH_WRITE_OVER_ENABLE, false);
1573    SETTING_BOOL("keyboard_gamepad_enable",       &settings->bools.input_keyboard_gamepad_enable, true, true, false);
1574    SETTING_BOOL("core_set_supports_no_game_enable", &settings->bools.set_supports_no_game_enable, true, true, false);
1575    SETTING_BOOL("audio_enable",                  &settings->bools.audio_enable, true, DEFAULT_AUDIO_ENABLE, false);
1576    SETTING_BOOL("menu_enable_widgets",           &settings->bools.menu_enable_widgets, true, DEFAULT_MENU_ENABLE_WIDGETS, false);
1577    SETTING_BOOL("menu_show_load_content_animation", &settings->bools.menu_show_load_content_animation, true, DEFAULT_MENU_SHOW_LOAD_CONTENT_ANIMATION, false);
1578    SETTING_BOOL("notification_show_autoconfig", &settings->bools.notification_show_autoconfig, true, DEFAULT_NOTIFICATION_SHOW_AUTOCONFIG, false);
1579    SETTING_BOOL("notification_show_cheats_applied", &settings->bools.notification_show_cheats_applied, true, DEFAULT_NOTIFICATION_SHOW_CHEATS_APPLIED, false);
1580    SETTING_BOOL("notification_show_patch_applied", &settings->bools.notification_show_patch_applied, true, DEFAULT_NOTIFICATION_SHOW_PATCH_APPLIED, false);
1581    SETTING_BOOL("notification_show_remap_load", &settings->bools.notification_show_remap_load, true, DEFAULT_NOTIFICATION_SHOW_REMAP_LOAD, false);
1582    SETTING_BOOL("notification_show_config_override_load", &settings->bools.notification_show_config_override_load, true, DEFAULT_NOTIFICATION_SHOW_CONFIG_OVERRIDE_LOAD, false);
1583    SETTING_BOOL("notification_show_set_initial_disk", &settings->bools.notification_show_set_initial_disk, true, DEFAULT_NOTIFICATION_SHOW_SET_INITIAL_DISK, false);
1584    SETTING_BOOL("notification_show_fast_forward", &settings->bools.notification_show_fast_forward, true, DEFAULT_NOTIFICATION_SHOW_FAST_FORWARD, false);
1585 #ifdef HAVE_SCREENSHOTS
1586    SETTING_BOOL("notification_show_screenshot", &settings->bools.notification_show_screenshot, true, DEFAULT_NOTIFICATION_SHOW_SCREENSHOT, false);
1587 #endif
1588    SETTING_BOOL("notification_show_refresh_rate", &settings->bools.notification_show_refresh_rate, true, DEFAULT_NOTIFICATION_SHOW_REFRESH_RATE, false);
1589    SETTING_BOOL("menu_widget_scale_auto",        &settings->bools.menu_widget_scale_auto, true, DEFAULT_MENU_WIDGET_SCALE_AUTO, false);
1590    SETTING_BOOL("audio_enable_menu",             &settings->bools.audio_enable_menu, true, audio_enable_menu, false);
1591    SETTING_BOOL("audio_enable_menu_ok",          &settings->bools.audio_enable_menu_ok, true, audio_enable_menu_ok, false);
1592    SETTING_BOOL("audio_enable_menu_cancel",      &settings->bools.audio_enable_menu_cancel, true, audio_enable_menu_cancel, false);
1593    SETTING_BOOL("audio_enable_menu_notice",      &settings->bools.audio_enable_menu_notice, true, audio_enable_menu_notice, false);
1594    SETTING_BOOL("audio_enable_menu_bgm",         &settings->bools.audio_enable_menu_bgm, true, audio_enable_menu_bgm, false);
1595    SETTING_BOOL("audio_mute_enable",             audio_get_bool_ptr(AUDIO_ACTION_MUTE_ENABLE), true, false, false);
1596 #ifdef HAVE_AUDIOMIXER
1597    SETTING_BOOL("audio_mixer_mute_enable",       audio_get_bool_ptr(AUDIO_ACTION_MIXER_MUTE_ENABLE), true, false, false);
1598 #endif
1599    SETTING_BOOL("audio_fastforward_mute",        &settings->bools.audio_fastforward_mute, true, DEFAULT_AUDIO_FASTFORWARD_MUTE, false);
1600    SETTING_BOOL("location_allow",                &settings->bools.location_allow, true, false, false);
1601    SETTING_BOOL("video_font_enable",             &settings->bools.video_font_enable, true, DEFAULT_FONT_ENABLE, false);
1602    SETTING_BOOL("core_updater_auto_extract_archive", &settings->bools.network_buildbot_auto_extract_archive, true, DEFAULT_NETWORK_BUILDBOT_AUTO_EXTRACT_ARCHIVE, false);
1603    SETTING_BOOL("core_updater_show_experimental_cores", &settings->bools.network_buildbot_show_experimental_cores, true, DEFAULT_NETWORK_BUILDBOT_SHOW_EXPERIMENTAL_CORES, false);
1604    SETTING_BOOL("core_updater_auto_backup",      &settings->bools.core_updater_auto_backup, true, DEFAULT_CORE_UPDATER_AUTO_BACKUP, false);
1605    SETTING_BOOL("camera_allow",                  &settings->bools.camera_allow, true, false, false);
1606    SETTING_BOOL("discord_allow",                 &settings->bools.discord_enable, true, false, false);
1607 #if defined(VITA)
1608    SETTING_BOOL("input_backtouch_enable",        &settings->bools.input_backtouch_enable, false, false, false);
1609    SETTING_BOOL("input_backtouch_toggle",        &settings->bools.input_backtouch_toggle, false, false, false);
1610 #endif
1611 #if TARGET_OS_IPHONE
1612    SETTING_BOOL("small_keyboard_enable",         &settings->bools.input_small_keyboard_enable, true, false, false);
1613 #endif
1614 #ifdef GEKKO
1615    SETTING_BOOL("video_vfilter",                 &settings->bools.video_vfilter, true, DEFAULT_VIDEO_VFILTER, false);
1616 #endif
1617 #ifdef HAVE_THREADS
1618    SETTING_BOOL("threaded_data_runloop_enable",  &settings->bools.threaded_data_runloop_enable, true, DEFAULT_THREADED_DATA_RUNLOOP_ENABLE, false);
1619 #endif
1620 #ifdef HAVE_MENU
1621    SETTING_BOOL("menu_unified_controls",         &settings->bools.menu_unified_controls, true, false, false);
1622    SETTING_BOOL("menu_throttle_framerate",       &settings->bools.menu_throttle_framerate, true, true, false);
1623    SETTING_BOOL("menu_linear_filter",            &settings->bools.menu_linear_filter, true, DEFAULT_VIDEO_SMOOTH, false);
1624    SETTING_BOOL("menu_horizontal_animation",     &settings->bools.menu_horizontal_animation, true, DEFAULT_MENU_HORIZONTAL_ANIMATION, false);
1625    SETTING_BOOL("menu_pause_libretro",           &settings->bools.menu_pause_libretro, true, true, false);
1626    SETTING_BOOL("menu_savestate_resume",         &settings->bools.menu_savestate_resume, true, menu_savestate_resume, false);
1627    SETTING_BOOL("menu_insert_disk_resume",       &settings->bools.menu_insert_disk_resume, true, DEFAULT_MENU_INSERT_DISK_RESUME, false);
1628    SETTING_BOOL("menu_mouse_enable",             &settings->bools.menu_mouse_enable, true, DEFAULT_MOUSE_ENABLE, false);
1629    SETTING_BOOL("menu_pointer_enable",           &settings->bools.menu_pointer_enable, true, DEFAULT_POINTER_ENABLE, false);
1630    SETTING_BOOL("menu_timedate_enable",          &settings->bools.menu_timedate_enable, true, DEFAULT_MENU_TIMEDATE_ENABLE, false);
1631    SETTING_BOOL("menu_battery_level_enable",     &settings->bools.menu_battery_level_enable, true, true, false);
1632    SETTING_BOOL("menu_core_enable",              &settings->bools.menu_core_enable, true, true, false);
1633    SETTING_BOOL("menu_show_sublabels",           &settings->bools.menu_show_sublabels, true, menu_show_sublabels, false);
1634    SETTING_BOOL("menu_dynamic_wallpaper_enable", &settings->bools.menu_dynamic_wallpaper_enable, true, menu_dynamic_wallpaper_enable, false);
1635    SETTING_BOOL("menu_ticker_smooth",            &settings->bools.menu_ticker_smooth, true, DEFAULT_MENU_TICKER_SMOOTH, false);
1636    SETTING_BOOL("menu_scroll_fast",              &settings->bools.menu_scroll_fast, true, false, false);
1637 
1638    SETTING_BOOL("settings_show_drivers",          &settings->bools.settings_show_drivers, true, DEFAULT_SETTINGS_SHOW_DRIVERS, false);
1639    SETTING_BOOL("settings_show_video",            &settings->bools.settings_show_video, true, DEFAULT_SETTINGS_SHOW_VIDEO, false);
1640    SETTING_BOOL("settings_show_audio",            &settings->bools.settings_show_audio, true, DEFAULT_SETTINGS_SHOW_AUDIO, false);
1641    SETTING_BOOL("settings_show_input",            &settings->bools.settings_show_input, true, DEFAULT_SETTINGS_SHOW_INPUT, false);
1642    SETTING_BOOL("settings_show_latency",          &settings->bools.settings_show_latency, true, DEFAULT_SETTINGS_SHOW_LATENCY, false);
1643    SETTING_BOOL("settings_show_core",             &settings->bools.settings_show_core, true, DEFAULT_SETTINGS_SHOW_CORE, false);
1644    SETTING_BOOL("settings_show_configuration",    &settings->bools.settings_show_configuration, true, DEFAULT_SETTINGS_SHOW_CONFIGURATION, false);
1645    SETTING_BOOL("settings_show_saving",           &settings->bools.settings_show_saving, true, DEFAULT_SETTINGS_SHOW_SAVING, false);
1646    SETTING_BOOL("settings_show_logging",          &settings->bools.settings_show_logging, true, DEFAULT_SETTINGS_SHOW_LOGGING, false);
1647    SETTING_BOOL("settings_show_file_browser",     &settings->bools.settings_show_file_browser, true, DEFAULT_SETTINGS_SHOW_FILE_BROWSER, false);
1648    SETTING_BOOL("settings_show_frame_throttle",   &settings->bools.settings_show_frame_throttle, true, DEFAULT_SETTINGS_SHOW_FRAME_THROTTLE, false);
1649    SETTING_BOOL("settings_show_recording",        &settings->bools.settings_show_recording, true, DEFAULT_SETTINGS_SHOW_RECORDING, false);
1650    SETTING_BOOL("settings_show_onscreen_display", &settings->bools.settings_show_onscreen_display, true, DEFAULT_SETTINGS_SHOW_ONSCREEN_DISPLAY, false);
1651    SETTING_BOOL("settings_show_user_interface",   &settings->bools.settings_show_user_interface, true, DEFAULT_SETTINGS_SHOW_USER_INTERFACE, false);
1652    SETTING_BOOL("settings_show_ai_service",       &settings->bools.settings_show_ai_service, true, DEFAULT_SETTINGS_SHOW_AI_SERVICE, false);
1653    SETTING_BOOL("settings_show_accessibility",    &settings->bools.settings_show_accessibility, true, DEFAULT_SETTINGS_SHOW_ACCESSIBILITY, false);
1654    SETTING_BOOL("settings_show_power_management", &settings->bools.settings_show_power_management, true, DEFAULT_SETTINGS_SHOW_POWER_MANAGEMENT, false);
1655    SETTING_BOOL("settings_show_achievements",     &settings->bools.settings_show_achievements, true, DEFAULT_SETTINGS_SHOW_ACHIEVEMENTS, false);
1656    SETTING_BOOL("settings_show_network",          &settings->bools.settings_show_network, true, DEFAULT_SETTINGS_SHOW_NETWORK, false);
1657    SETTING_BOOL("settings_show_playlists",        &settings->bools.settings_show_playlists, true, DEFAULT_SETTINGS_SHOW_PLAYLISTS, false);
1658    SETTING_BOOL("settings_show_user",             &settings->bools.settings_show_user, true, DEFAULT_SETTINGS_SHOW_USER, false);
1659    SETTING_BOOL("settings_show_directory",        &settings->bools.settings_show_directory, true, DEFAULT_SETTINGS_SHOW_DIRECTORY, false);
1660 
1661    SETTING_BOOL("quick_menu_show_resume_content",             &settings->bools.quick_menu_show_resume_content, true, DEFAULT_QUICK_MENU_SHOW_RESUME_CONTENT, false);
1662    SETTING_BOOL("quick_menu_show_restart_content",            &settings->bools.quick_menu_show_restart_content, true, DEFAULT_QUICK_MENU_SHOW_RESTART_CONTENT, false);
1663    SETTING_BOOL("quick_menu_show_close_content",              &settings->bools.quick_menu_show_close_content, true, DEFAULT_QUICK_MENU_SHOW_CLOSE_CONTENT, false);
1664    SETTING_BOOL("quick_menu_show_recording",                  &settings->bools.quick_menu_show_recording, true, quick_menu_show_recording, false);
1665    SETTING_BOOL("quick_menu_show_streaming",                  &settings->bools.quick_menu_show_streaming, true, quick_menu_show_streaming, false);
1666    SETTING_BOOL("quick_menu_show_save_load_state",            &settings->bools.quick_menu_show_save_load_state, true, DEFAULT_QUICK_MENU_SHOW_SAVE_LOAD_STATE, false);
1667    SETTING_BOOL("quick_menu_show_take_screenshot",            &settings->bools.quick_menu_show_take_screenshot, true, DEFAULT_QUICK_MENU_SHOW_TAKE_SCREENSHOT, false);
1668    SETTING_BOOL("quick_menu_show_undo_save_load_state",       &settings->bools.quick_menu_show_undo_save_load_state, true, DEFAULT_QUICK_MENU_SHOW_UNDO_SAVE_LOAD_STATE, false);
1669    SETTING_BOOL("quick_menu_show_add_to_favorites",           &settings->bools.quick_menu_show_add_to_favorites, true, quick_menu_show_add_to_favorites, false);
1670    SETTING_BOOL("quick_menu_show_start_recording",            &settings->bools.quick_menu_show_start_recording, true, quick_menu_show_start_recording, false);
1671    SETTING_BOOL("quick_menu_show_start_streaming",            &settings->bools.quick_menu_show_start_streaming, true, quick_menu_show_start_streaming, false);
1672    SETTING_BOOL("quick_menu_show_set_core_association",       &settings->bools.quick_menu_show_set_core_association, true, quick_menu_show_set_core_association, false);
1673    SETTING_BOOL("quick_menu_show_reset_core_association",     &settings->bools.quick_menu_show_reset_core_association, true, quick_menu_show_reset_core_association, false);
1674    SETTING_BOOL("quick_menu_show_options",                    &settings->bools.quick_menu_show_options, true, quick_menu_show_options, false);
1675    SETTING_BOOL("quick_menu_show_controls",                   &settings->bools.quick_menu_show_controls, true, quick_menu_show_controls, false);
1676    SETTING_BOOL("quick_menu_show_cheats",                     &settings->bools.quick_menu_show_cheats, true, quick_menu_show_cheats, false);
1677    SETTING_BOOL("quick_menu_show_shaders",                    &settings->bools.quick_menu_show_shaders, true, quick_menu_show_shaders, false);
1678    SETTING_BOOL("quick_menu_show_save_core_overrides",        &settings->bools.quick_menu_show_save_core_overrides, true, quick_menu_show_save_core_overrides, false);
1679    SETTING_BOOL("quick_menu_show_save_game_overrides",        &settings->bools.quick_menu_show_save_game_overrides, true, quick_menu_show_save_game_overrides, false);
1680    SETTING_BOOL("quick_menu_show_save_content_dir_overrides", &settings->bools.quick_menu_show_save_content_dir_overrides, true, quick_menu_show_save_content_dir_overrides, false);
1681    SETTING_BOOL("quick_menu_show_information",                &settings->bools.quick_menu_show_information, true, quick_menu_show_information, false);
1682 #ifdef HAVE_NETWORKING
1683    SETTING_BOOL("quick_menu_show_download_thumbnails",        &settings->bools.quick_menu_show_download_thumbnails, true, quick_menu_show_download_thumbnails, false);
1684 #endif
1685    SETTING_BOOL("kiosk_mode_enable",             &settings->bools.kiosk_mode_enable, true, DEFAULT_KIOSK_MODE_ENABLE, false);
1686    SETTING_BOOL("menu_use_preferred_system_color_theme", &settings->bools.menu_use_preferred_system_color_theme, true, DEFAULT_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, false);
1687    SETTING_BOOL("content_show_settings",         &settings->bools.menu_content_show_settings, true, content_show_settings, false);
1688    SETTING_BOOL("content_show_favorites",        &settings->bools.menu_content_show_favorites, true, content_show_favorites, false);
1689 #ifdef HAVE_IMAGEVIEWER
1690    SETTING_BOOL("content_show_images",           &settings->bools.menu_content_show_images, true, content_show_images, false);
1691 #endif
1692    SETTING_BOOL("content_show_music",            &settings->bools.menu_content_show_music, true, content_show_music, false);
1693 #if defined(HAVE_FFMPEG) || defined(HAVE_MPV)
1694    SETTING_BOOL("content_show_video",            &settings->bools.menu_content_show_video, true, content_show_video, false);
1695 #endif
1696 #ifdef HAVE_NETWORKING
1697    SETTING_BOOL("content_show_netplay",          &settings->bools.menu_content_show_netplay, true, content_show_netplay, false);
1698 #endif
1699    SETTING_BOOL("content_show_history",          &settings->bools.menu_content_show_history, true, content_show_history, false);
1700    SETTING_BOOL("content_show_add",              &settings->bools.menu_content_show_add, true, DEFAULT_MENU_CONTENT_SHOW_ADD, false);
1701    SETTING_BOOL("content_show_playlists",        &settings->bools.menu_content_show_playlists, true, content_show_playlists, false);
1702 #if defined(HAVE_LIBRETRODB)
1703    SETTING_BOOL("content_show_explore",          &settings->bools.menu_content_show_explore, true, DEFAULT_MENU_CONTENT_SHOW_EXPLORE, false);
1704 #endif
1705    SETTING_BOOL("menu_show_load_core",           &settings->bools.menu_show_load_core, true, menu_show_load_core, false);
1706    SETTING_BOOL("menu_show_load_content",        &settings->bools.menu_show_load_content, true, menu_show_load_content, false);
1707 #ifdef HAVE_CDROM
1708    SETTING_BOOL("menu_show_load_disc",           &settings->bools.menu_show_load_disc, true, menu_show_load_disc, false);
1709    SETTING_BOOL("menu_show_dump_disc",           &settings->bools.menu_show_dump_disc, true, menu_show_dump_disc, false);
1710 #endif
1711    SETTING_BOOL("menu_show_information",         &settings->bools.menu_show_information, true, menu_show_information, false);
1712    SETTING_BOOL("menu_show_configurations",      &settings->bools.menu_show_configurations, true, menu_show_configurations, false);
1713    SETTING_BOOL("menu_show_latency",             &settings->bools.menu_show_latency, true, true, false);
1714    SETTING_BOOL("menu_show_rewind",              &settings->bools.menu_show_rewind, true, true, false);
1715    SETTING_BOOL("menu_show_overlays",            &settings->bools.menu_show_overlays, true, true, false);
1716 #ifdef HAVE_VIDEO_LAYOUT
1717    SETTING_BOOL("menu_show_video_layout",        &settings->bools.menu_show_video_layout, true, true, false);
1718 #endif
1719    SETTING_BOOL("menu_show_help",                &settings->bools.menu_show_help, true, menu_show_help, false);
1720    SETTING_BOOL("menu_show_quit_retroarch",      &settings->bools.menu_show_quit_retroarch, true, menu_show_quit_retroarch, false);
1721    SETTING_BOOL("menu_show_restart_retroarch",   &settings->bools.menu_show_restart_retroarch, true, menu_show_restart_retroarch, false);
1722    SETTING_BOOL("menu_show_reboot",              &settings->bools.menu_show_reboot, true, menu_show_reboot, false);
1723    SETTING_BOOL("menu_show_shutdown",            &settings->bools.menu_show_shutdown, true, menu_show_shutdown, false);
1724    SETTING_BOOL("menu_show_online_updater",      &settings->bools.menu_show_online_updater, true, menu_show_online_updater, false);
1725    SETTING_BOOL("menu_show_core_updater",        &settings->bools.menu_show_core_updater, true, menu_show_core_updater, false);
1726    SETTING_BOOL("menu_show_legacy_thumbnail_updater", &settings->bools.menu_show_legacy_thumbnail_updater, true, menu_show_legacy_thumbnail_updater, false);
1727    SETTING_BOOL("filter_by_current_core",        &settings->bools.filter_by_current_core, true, DEFAULT_FILTER_BY_CURRENT_CORE, false);
1728    SETTING_BOOL("rgui_show_start_screen",        &settings->bools.menu_show_start_screen, false, false /* TODO */, false);
1729    SETTING_BOOL("menu_navigation_wraparound_enable", &settings->bools.menu_navigation_wraparound_enable, true, true, false);
1730    SETTING_BOOL("menu_navigation_browser_filter_supported_extensions_enable",
1731          &settings->bools.menu_navigation_browser_filter_supported_extensions_enable, true, true, false);
1732    SETTING_BOOL("menu_show_advanced_settings",  &settings->bools.menu_show_advanced_settings, true, DEFAULT_SHOW_ADVANCED_SETTINGS, false);
1733 #ifdef HAVE_MATERIALUI
1734    SETTING_BOOL("materialui_icons_enable",       &settings->bools.menu_materialui_icons_enable, true, DEFAULT_MATERIALUI_ICONS_ENABLE, false);
1735    SETTING_BOOL("materialui_playlist_icons_enable", &settings->bools.menu_materialui_playlist_icons_enable, true, DEFAULT_MATERIALUI_PLAYLIST_ICONS_ENABLE, false);
1736    SETTING_BOOL("materialui_show_nav_bar",        &settings->bools.menu_materialui_show_nav_bar, true, DEFAULT_MATERIALUI_SHOW_NAV_BAR, false);
1737    SETTING_BOOL("materialui_auto_rotate_nav_bar", &settings->bools.menu_materialui_auto_rotate_nav_bar, true, DEFAULT_MATERIALUI_AUTO_ROTATE_NAV_BAR, false);
1738    SETTING_BOOL("materialui_dual_thumbnail_list_view_enable", &settings->bools.menu_materialui_dual_thumbnail_list_view_enable, true, DEFAULT_MATERIALUI_DUAL_THUMBNAIL_LIST_VIEW_ENABLE, false);
1739    SETTING_BOOL("materialui_thumbnail_background_enable", &settings->bools.menu_materialui_thumbnail_background_enable, true, DEFAULT_MATERIALUI_THUMBNAIL_BACKGROUND_ENABLE, false);
1740 #endif
1741 #ifdef HAVE_RGUI
1742    SETTING_BOOL("rgui_background_filler_thickness_enable", &settings->bools.menu_rgui_background_filler_thickness_enable, true, true, false);
1743    SETTING_BOOL("rgui_border_filler_thickness_enable",     &settings->bools.menu_rgui_border_filler_thickness_enable, true, true, false);
1744    SETTING_BOOL("rgui_border_filler_enable",               &settings->bools.menu_rgui_border_filler_enable, true, true, false);
1745    SETTING_BOOL("menu_rgui_transparency",                  &settings->bools.menu_rgui_transparency, true, DEFAULT_RGUI_TRANSPARENCY, false);
1746    SETTING_BOOL("menu_rgui_shadows",                       &settings->bools.menu_rgui_shadows, true, rgui_shadows, false);
1747    SETTING_BOOL("menu_rgui_full_width_layout",             &settings->bools.menu_rgui_full_width_layout, true, rgui_full_width_layout, false);
1748    SETTING_BOOL("rgui_inline_thumbnails",                  &settings->bools.menu_rgui_inline_thumbnails, true, rgui_inline_thumbnails, false);
1749    SETTING_BOOL("rgui_swap_thumbnails",                    &settings->bools.menu_rgui_swap_thumbnails, true, rgui_swap_thumbnails, false);
1750    SETTING_BOOL("rgui_extended_ascii",                     &settings->bools.menu_rgui_extended_ascii, true, rgui_extended_ascii, false);
1751    SETTING_BOOL("rgui_switch_icons",                       &settings->bools.menu_rgui_switch_icons, true, DEFAULT_RGUI_SWITCH_ICONS, false);
1752    SETTING_BOOL("rgui_particle_effect_screensaver",        &settings->bools.menu_rgui_particle_effect_screensaver, true, DEFAULT_RGUI_PARTICLE_EFFECT_SCREENSAVER, false);
1753 #endif
1754 #ifdef HAVE_XMB
1755    SETTING_BOOL("xmb_shadows_enable",            &settings->bools.menu_xmb_shadows_enable, true, DEFAULT_XMB_SHADOWS_ENABLE, false);
1756    SETTING_BOOL("xmb_vertical_thumbnails",       &settings->bools.menu_xmb_vertical_thumbnails, true, xmb_vertical_thumbnails, false);
1757 #endif
1758 #endif
1759 #ifdef HAVE_CHEEVOS
1760    SETTING_BOOL("cheevos_enable",               &settings->bools.cheevos_enable, true, DEFAULT_CHEEVOS_ENABLE, false);
1761    SETTING_BOOL("cheevos_test_unofficial",      &settings->bools.cheevos_test_unofficial, true, false, false);
1762    SETTING_BOOL("cheevos_hardcore_mode_enable", &settings->bools.cheevos_hardcore_mode_enable, true, false, false);
1763    SETTING_BOOL("cheevos_challenge_indicators", &settings->bools.cheevos_challenge_indicators, true, true, false);
1764    SETTING_BOOL("cheevos_richpresence_enable",  &settings->bools.cheevos_richpresence_enable, true, true, false);
1765    SETTING_BOOL("cheevos_unlock_sound_enable",  &settings->bools.cheevos_unlock_sound_enable, true, false, false);
1766    SETTING_BOOL("cheevos_verbose_enable",       &settings->bools.cheevos_verbose_enable, true, false, false);
1767    SETTING_BOOL("cheevos_auto_screenshot",      &settings->bools.cheevos_auto_screenshot, true, false, false);
1768    SETTING_BOOL("cheevos_badges_enable",        &settings->bools.cheevos_badges_enable, true, false, false);
1769    SETTING_BOOL("cheevos_start_active",         &settings->bools.cheevos_start_active, true, false, false);
1770 #endif
1771 #ifdef HAVE_OVERLAY
1772    SETTING_BOOL("input_overlay_enable",         &settings->bools.input_overlay_enable, true, config_overlay_enable_default(), false);
1773    SETTING_BOOL("input_overlay_enable_autopreferred", &settings->bools.input_overlay_enable_autopreferred, true, DEFAULT_OVERLAY_ENABLE_AUTOPREFERRED, false);
1774    SETTING_BOOL("input_overlay_hide_in_menu",   &settings->bools.input_overlay_hide_in_menu, true, DEFAULT_OVERLAY_HIDE_IN_MENU, false);
1775    SETTING_BOOL("input_overlay_hide_when_gamepad_connected", &settings->bools.input_overlay_hide_when_gamepad_connected, true, DEFAULT_OVERLAY_HIDE_WHEN_GAMEPAD_CONNECTED, false);
1776    SETTING_BOOL("input_overlay_show_mouse_cursor",   &settings->bools.input_overlay_show_mouse_cursor, true, DEFAULT_OVERLAY_SHOW_MOUSE_CURSOR, false);
1777    SETTING_BOOL("input_overlay_auto_rotate",         &settings->bools.input_overlay_auto_rotate, true, DEFAULT_OVERLAY_AUTO_ROTATE, false);
1778    SETTING_BOOL("input_overlay_auto_scale",          &settings->bools.input_overlay_auto_scale, true, DEFAULT_INPUT_OVERLAY_AUTO_SCALE, false);
1779 #endif
1780 #ifdef HAVE_VIDEO_LAYOUT
1781    SETTING_BOOL("video_layout_enable",          &settings->bools.video_layout_enable, true, true, false);
1782 #endif
1783 #ifdef HAVE_COMMAND
1784    SETTING_BOOL("network_cmd_enable",           &settings->bools.network_cmd_enable, true, network_cmd_enable, false);
1785    SETTING_BOOL("stdin_cmd_enable",             &settings->bools.stdin_cmd_enable, true, stdin_cmd_enable, false);
1786 #endif
1787 #ifdef HAVE_NETWORKGAMEPAD
1788    SETTING_BOOL("network_remote_enable",        &settings->bools.network_remote_enable, false, false /* TODO */, false);
1789 #endif
1790 #ifdef HAVE_NETWORKING
1791    SETTING_BOOL("netplay_nat_traversal",        &settings->bools.netplay_nat_traversal, true, true, false);
1792 #endif
1793    SETTING_BOOL("block_sram_overwrite",         &settings->bools.block_sram_overwrite, true, DEFAULT_BLOCK_SRAM_OVERWRITE, false);
1794    SETTING_BOOL("savestate_auto_index",         &settings->bools.savestate_auto_index, true, savestate_auto_index, false);
1795    SETTING_BOOL("savestate_auto_save",          &settings->bools.savestate_auto_save, true, savestate_auto_save, false);
1796    SETTING_BOOL("savestate_auto_load",          &settings->bools.savestate_auto_load, true, savestate_auto_load, false);
1797    SETTING_BOOL("savestate_thumbnail_enable",   &settings->bools.savestate_thumbnail_enable, true, savestate_thumbnail_enable, false);
1798    SETTING_BOOL("save_file_compression",        &settings->bools.save_file_compression, true, DEFAULT_SAVE_FILE_COMPRESSION, false);
1799    SETTING_BOOL("savestate_file_compression",   &settings->bools.savestate_file_compression, true, DEFAULT_SAVESTATE_FILE_COMPRESSION, false);
1800    SETTING_BOOL("history_list_enable",          &settings->bools.history_list_enable, true, DEFAULT_HISTORY_LIST_ENABLE, false);
1801    SETTING_BOOL("playlist_entry_rename",        &settings->bools.playlist_entry_rename, true, DEFAULT_PLAYLIST_ENTRY_RENAME, false);
1802    SETTING_BOOL("game_specific_options",        &settings->bools.game_specific_options, true, default_game_specific_options, false);
1803    SETTING_BOOL("auto_overrides_enable",        &settings->bools.auto_overrides_enable, true, default_auto_overrides_enable, false);
1804    SETTING_BOOL("auto_remaps_enable",           &settings->bools.auto_remaps_enable, true, default_auto_remaps_enable, false);
1805    SETTING_BOOL("global_core_options",          &settings->bools.global_core_options, true, default_global_core_options, false);
1806    SETTING_BOOL("auto_shaders_enable",          &settings->bools.auto_shaders_enable, true, default_auto_shaders_enable, false);
1807    SETTING_BOOL("scan_without_core_match",   &settings->bools.scan_without_core_match, true, DEFAULT_SCAN_WITHOUT_CORE_MATCH, false);
1808    SETTING_BOOL("sort_savefiles_enable",        &settings->bools.sort_savefiles_enable, true, default_sort_savefiles_enable, false);
1809    SETTING_BOOL("sort_savestates_enable",       &settings->bools.sort_savestates_enable, true, default_sort_savestates_enable, false);
1810    SETTING_BOOL("sort_savefiles_by_content_enable", &settings->bools.sort_savefiles_by_content_enable, true, default_sort_savefiles_by_content_enable, false);
1811    SETTING_BOOL("sort_savestates_by_content_enable", &settings->bools.sort_savestates_by_content_enable, true, default_sort_savestates_by_content_enable, false);
1812    SETTING_BOOL("sort_screenshots_by_content_enable", &settings->bools.sort_screenshots_by_content_enable, true, default_sort_screenshots_by_content_enable, false);
1813    SETTING_BOOL("config_save_on_exit",          &settings->bools.config_save_on_exit, true, DEFAULT_CONFIG_SAVE_ON_EXIT, false);
1814    SETTING_BOOL("show_hidden_files",            &settings->bools.show_hidden_files, true, DEFAULT_SHOW_HIDDEN_FILES, false);
1815    SETTING_BOOL("use_last_start_directory",     &settings->bools.use_last_start_directory, true, DEFAULT_USE_LAST_START_DIRECTORY, false);
1816    SETTING_BOOL("input_autodetect_enable",      &settings->bools.input_autodetect_enable, true, input_autodetect_enable, false);
1817 #if defined(HAVE_DINPUT) || defined(HAVE_WINRAWINPUT)
1818    SETTING_BOOL("input_nowinkey_enable",        &settings->bools.input_nowinkey_enable, true, false, false);
1819 #endif
1820    SETTING_BOOL("input_sensors_enable",         &settings->bools.input_sensors_enable, true, DEFAULT_INPUT_SENSORS_ENABLE, false);
1821    SETTING_BOOL("audio_rate_control",           &settings->bools.audio_rate_control, true, DEFAULT_RATE_CONTROL, false);
1822 #ifdef HAVE_WASAPI
1823    SETTING_BOOL("audio_wasapi_exclusive_mode",  &settings->bools.audio_wasapi_exclusive_mode, true, DEFAULT_WASAPI_EXCLUSIVE_MODE, false);
1824    SETTING_BOOL("audio_wasapi_float_format",    &settings->bools.audio_wasapi_float_format, true, DEFAULT_WASAPI_FLOAT_FORMAT, false);
1825 #endif
1826 
1827    SETTING_BOOL("savestates_in_content_dir",     &settings->bools.savestates_in_content_dir, true, default_savestates_in_content_dir, false);
1828    SETTING_BOOL("savefiles_in_content_dir",      &settings->bools.savefiles_in_content_dir, true, default_savefiles_in_content_dir, false);
1829    SETTING_BOOL("systemfiles_in_content_dir",    &settings->bools.systemfiles_in_content_dir, true, default_systemfiles_in_content_dir, false);
1830    SETTING_BOOL("screenshots_in_content_dir",    &settings->bools.screenshots_in_content_dir, true, default_screenshots_in_content_dir, false);
1831 
1832    SETTING_BOOL("video_msg_bgcolor_enable",      &settings->bools.video_msg_bgcolor_enable, true, message_bgcolor_enable, false);
1833    SETTING_BOOL("video_window_show_decorations", &settings->bools.video_window_show_decorations, true, DEFAULT_WINDOW_DECORATIONS, false);
1834    SETTING_BOOL("video_window_save_positions", &settings->bools.video_window_save_positions, true, false, false);
1835 
1836    SETTING_BOOL("sustained_performance_mode",    &settings->bools.sustained_performance_mode, true, sustained_performance_mode, false);
1837 
1838 #ifdef _3DS
1839    SETTING_BOOL("video_3ds_lcd_bottom",          &settings->bools.video_3ds_lcd_bottom, true, video_3ds_lcd_bottom, false);
1840 #endif
1841 
1842    SETTING_BOOL("playlist_use_old_format",       &settings->bools.playlist_use_old_format, true, DEFAULT_PLAYLIST_USE_OLD_FORMAT, false);
1843    SETTING_BOOL("playlist_compression",          &settings->bools.playlist_compression, true, DEFAULT_PLAYLIST_COMPRESSION, false);
1844    SETTING_BOOL("content_runtime_log",           &settings->bools.content_runtime_log, true, DEFAULT_CONTENT_RUNTIME_LOG, false);
1845    SETTING_BOOL("content_runtime_log_aggregate", &settings->bools.content_runtime_log_aggregate, true, DEFAULT_CONTENT_RUNTIME_LOG_AGGREGATE, false);
1846    SETTING_BOOL("playlist_show_sublabels",       &settings->bools.playlist_show_sublabels, true, DEFAULT_PLAYLIST_SHOW_SUBLABELS, false);
1847    SETTING_BOOL("playlist_show_entry_idx",       &settings->bools.playlist_show_entry_idx, true, DEFAULT_PLAYLIST_SHOW_ENTRY_IDX, false);
1848    SETTING_BOOL("playlist_sort_alphabetical",    &settings->bools.playlist_sort_alphabetical, true, DEFAULT_PLAYLIST_SORT_ALPHABETICAL, false);
1849    SETTING_BOOL("playlist_fuzzy_archive_match",  &settings->bools.playlist_fuzzy_archive_match, true, DEFAULT_PLAYLIST_FUZZY_ARCHIVE_MATCH, false);
1850    SETTING_BOOL("playlist_portable_paths",       &settings->bools.playlist_portable_paths, true, DEFAULT_PLAYLIST_PORTABLE_PATHS, false);
1851 
1852    SETTING_BOOL("quit_press_twice", &settings->bools.quit_press_twice, true, DEFAULT_QUIT_PRESS_TWICE, false);
1853    SETTING_BOOL("vibrate_on_keypress", &settings->bools.vibrate_on_keypress, true, vibrate_on_keypress, false);
1854    SETTING_BOOL("enable_device_vibration", &settings->bools.enable_device_vibration, true, enable_device_vibration, false);
1855 
1856 #ifdef HAVE_OZONE
1857    SETTING_BOOL("ozone_collapse_sidebar",       &settings->bools.ozone_collapse_sidebar, true, DEFAULT_OZONE_COLLAPSE_SIDEBAR, false);
1858    SETTING_BOOL("ozone_truncate_playlist_name", &settings->bools.ozone_truncate_playlist_name, true, DEFAULT_OZONE_TRUNCATE_PLAYLIST_NAME, false);
1859    SETTING_BOOL("ozone_sort_after_truncate_playlist_name", &settings->bools.ozone_sort_after_truncate_playlist_name, true, DEFAULT_OZONE_SORT_AFTER_TRUNCATE_PLAYLIST_NAME, false);
1860    SETTING_BOOL("ozone_scroll_content_metadata",&settings->bools.ozone_scroll_content_metadata, true, DEFAULT_OZONE_SCROLL_CONTENT_METADATA, false);
1861 #endif
1862    SETTING_BOOL("log_to_file", &settings->bools.log_to_file, true, DEFAULT_LOG_TO_FILE, false);
1863    SETTING_OVERRIDE(RARCH_OVERRIDE_SETTING_LOG_TO_FILE);
1864    SETTING_BOOL("log_to_file_timestamp", &settings->bools.log_to_file_timestamp, true, DEFAULT_LOG_TO_FILE_TIMESTAMP, false);
1865    SETTING_BOOL("ai_service_enable",     &settings->bools.ai_service_enable, true, DEFAULT_AI_SERVICE_ENABLE, false);
1866    SETTING_BOOL("ai_service_pause",      &settings->bools.ai_service_pause, true, DEFAULT_AI_SERVICE_PAUSE, false);
1867    SETTING_BOOL("wifi_enabled",          &settings->bools.wifi_enabled, true, DEFAULT_WIFI_ENABLE, false);
1868 
1869    *size = count;
1870 
1871    return tmp;
1872 }
1873 
populate_settings_float(settings_t * settings,int * size)1874 static struct config_float_setting *populate_settings_float(
1875       settings_t *settings, int *size)
1876 {
1877    unsigned count = 0;
1878    struct config_float_setting  *tmp      = (struct config_float_setting*)calloc(1, (*size + 1) * sizeof(struct config_float_setting));
1879 
1880    if (!tmp)
1881       return NULL;
1882 
1883    SETTING_FLOAT("video_aspect_ratio",       &settings->floats.video_aspect_ratio, true, DEFAULT_ASPECT_RATIO, false);
1884    SETTING_FLOAT("video_scale",              &settings->floats.video_scale, false, 0.0f, false);
1885    SETTING_FLOAT("crt_video_refresh_rate",   &settings->floats.crt_video_refresh_rate, true, DEFAULT_CRT_REFRESH_RATE, false);
1886    SETTING_FLOAT("video_refresh_rate",       &settings->floats.video_refresh_rate, true, DEFAULT_REFRESH_RATE, false);
1887    SETTING_FLOAT("audio_rate_control_delta", audio_get_float_ptr(AUDIO_ACTION_RATE_CONTROL_DELTA), true, DEFAULT_RATE_CONTROL_DELTA, false);
1888    SETTING_FLOAT("audio_max_timing_skew",    &settings->floats.audio_max_timing_skew, true, DEFAULT_MAX_TIMING_SKEW, false);
1889    SETTING_FLOAT("audio_volume",             &settings->floats.audio_volume, true, DEFAULT_AUDIO_VOLUME, false);
1890 #ifdef HAVE_AUDIOMIXER
1891    SETTING_FLOAT("audio_mixer_volume",       &settings->floats.audio_mixer_volume, true, DEFAULT_AUDIO_MIXER_VOLUME, false);
1892 #endif
1893 #ifdef HAVE_OVERLAY
1894    SETTING_FLOAT("input_overlay_opacity",                 &settings->floats.input_overlay_opacity, true, DEFAULT_INPUT_OVERLAY_OPACITY, false);
1895    SETTING_FLOAT("input_overlay_scale_landscape",         &settings->floats.input_overlay_scale_landscape, true, DEFAULT_INPUT_OVERLAY_SCALE_LANDSCAPE, false);
1896    SETTING_FLOAT("input_overlay_aspect_adjust_landscape", &settings->floats.input_overlay_aspect_adjust_landscape, true, DEFAULT_INPUT_OVERLAY_ASPECT_ADJUST_LANDSCAPE, false);
1897    SETTING_FLOAT("input_overlay_x_separation_landscape",  &settings->floats.input_overlay_x_separation_landscape, true, DEFAULT_INPUT_OVERLAY_X_SEPARATION_LANDSCAPE, false);
1898    SETTING_FLOAT("input_overlay_y_separation_landscape",  &settings->floats.input_overlay_y_separation_landscape, true, DEFAULT_INPUT_OVERLAY_Y_SEPARATION_LANDSCAPE, false);
1899    SETTING_FLOAT("input_overlay_x_offset_landscape",      &settings->floats.input_overlay_x_offset_landscape, true, DEFAULT_INPUT_OVERLAY_X_OFFSET_LANDSCAPE, false);
1900    SETTING_FLOAT("input_overlay_y_offset_landscape",      &settings->floats.input_overlay_y_offset_landscape, true, DEFAULT_INPUT_OVERLAY_Y_OFFSET_LANDSCAPE, false);
1901    SETTING_FLOAT("input_overlay_scale_portrait",          &settings->floats.input_overlay_scale_portrait, true, DEFAULT_INPUT_OVERLAY_SCALE_PORTRAIT, false);
1902    SETTING_FLOAT("input_overlay_aspect_adjust_portrait",  &settings->floats.input_overlay_aspect_adjust_portrait, true, DEFAULT_INPUT_OVERLAY_ASPECT_ADJUST_PORTRAIT, false);
1903    SETTING_FLOAT("input_overlay_x_separation_portrait",   &settings->floats.input_overlay_x_separation_portrait, true, DEFAULT_INPUT_OVERLAY_X_SEPARATION_PORTRAIT, false);
1904    SETTING_FLOAT("input_overlay_y_separation_portrait",   &settings->floats.input_overlay_y_separation_portrait, true, DEFAULT_INPUT_OVERLAY_Y_SEPARATION_PORTRAIT, false);
1905    SETTING_FLOAT("input_overlay_x_offset_portrait",       &settings->floats.input_overlay_x_offset_portrait, true, DEFAULT_INPUT_OVERLAY_X_OFFSET_PORTRAIT, false);
1906    SETTING_FLOAT("input_overlay_y_offset_portrait",       &settings->floats.input_overlay_y_offset_portrait, true, DEFAULT_INPUT_OVERLAY_Y_OFFSET_PORTRAIT, false);
1907 #endif
1908 #ifdef HAVE_MENU
1909    SETTING_FLOAT("menu_scale_factor",        &settings->floats.menu_scale_factor, true, DEFAULT_MENU_SCALE_FACTOR, false);
1910    SETTING_FLOAT("menu_widget_scale_factor", &settings->floats.menu_widget_scale_factor, true, DEFAULT_MENU_WIDGET_SCALE_FACTOR, false);
1911 #if !(defined(RARCH_CONSOLE) || defined(RARCH_MOBILE))
1912    SETTING_FLOAT("menu_widget_scale_factor_windowed", &settings->floats.menu_widget_scale_factor_windowed, true, DEFAULT_MENU_WIDGET_SCALE_FACTOR_WINDOWED, false);
1913 #endif
1914    SETTING_FLOAT("menu_wallpaper_opacity",   &settings->floats.menu_wallpaper_opacity, true, menu_wallpaper_opacity, false);
1915    SETTING_FLOAT("menu_framebuffer_opacity", &settings->floats.menu_framebuffer_opacity, true, menu_framebuffer_opacity, false);
1916    SETTING_FLOAT("menu_footer_opacity",      &settings->floats.menu_footer_opacity,    true, menu_footer_opacity, false);
1917    SETTING_FLOAT("menu_header_opacity",      &settings->floats.menu_header_opacity,    true, menu_header_opacity, false);
1918    SETTING_FLOAT("menu_ticker_speed",        &settings->floats.menu_ticker_speed,      true, menu_ticker_speed,   false);
1919    SETTING_FLOAT("rgui_particle_effect_speed", &settings->floats.menu_rgui_particle_effect_speed, true, DEFAULT_RGUI_PARTICLE_EFFECT_SPEED, false);
1920 #if defined(HAVE_MATERIALUI) || defined(HAVE_XMB) || defined(HAVE_OZONE)
1921    SETTING_FLOAT("menu_screensaver_animation_speed", &settings->floats.menu_screensaver_animation_speed, true, DEFAULT_MENU_SCREENSAVER_ANIMATION_SPEED, false);
1922 #endif
1923 #endif
1924    SETTING_FLOAT("video_message_pos_x",      &settings->floats.video_msg_pos_x,      true, message_pos_offset_x, false);
1925    SETTING_FLOAT("video_message_pos_y",      &settings->floats.video_msg_pos_y,      true, message_pos_offset_y, false);
1926    SETTING_FLOAT("video_font_size",          &settings->floats.video_font_size,      true, DEFAULT_FONT_SIZE, false);
1927    SETTING_FLOAT("fastforward_ratio",        &settings->floats.fastforward_ratio,    true, DEFAULT_FASTFORWARD_RATIO, false);
1928    SETTING_FLOAT("slowmotion_ratio",         &settings->floats.slowmotion_ratio,     true, DEFAULT_SLOWMOTION_RATIO, false);
1929    SETTING_FLOAT("input_axis_threshold",     input_driver_get_float(INPUT_ACTION_AXIS_THRESHOLD), true, DEFAULT_AXIS_THRESHOLD, false);
1930    SETTING_FLOAT("input_analog_deadzone",    &settings->floats.input_analog_deadzone, true, DEFAULT_ANALOG_DEADZONE, false);
1931    SETTING_FLOAT("input_analog_sensitivity",    &settings->floats.input_analog_sensitivity, true, DEFAULT_ANALOG_SENSITIVITY, false);
1932    SETTING_FLOAT("video_msg_bgcolor_opacity", &settings->floats.video_msg_bgcolor_opacity, true, message_bgcolor_opacity, false);
1933 
1934    *size = count;
1935 
1936    return tmp;
1937 }
1938 
populate_settings_uint(settings_t * settings,int * size)1939 static struct config_uint_setting *populate_settings_uint(
1940       settings_t *settings, int *size)
1941 {
1942    unsigned count                     = 0;
1943    struct config_uint_setting  *tmp   = (struct config_uint_setting*)calloc(1, (*size + 1) * sizeof(struct config_uint_setting));
1944 
1945    if (!tmp)
1946       return NULL;
1947 
1948    SETTING_UINT("accessibility_narrator_speech_speed",  		         &settings->uints.accessibility_narrator_speech_speed, true, DEFAULT_ACCESSIBILITY_NARRATOR_SPEECH_SPEED, false);
1949 #ifdef HAVE_NETWORKING
1950    SETTING_UINT("streaming_mode",  		         &settings->uints.streaming_mode, true, STREAMING_MODE_TWITCH, false);
1951 #endif
1952    SETTING_UINT("screen_brightness",	  		&settings->uints.screen_brightness, true, DEFAULT_SCREEN_BRIGHTNESS, false);
1953    SETTING_UINT("crt_switch_resolution",  		&settings->uints.crt_switch_resolution, true, DEFAULT_CRT_SWITCH_RESOLUTION, false);
1954    SETTING_UINT("input_bind_timeout",           &settings->uints.input_bind_timeout,     true, input_bind_timeout, false);
1955    SETTING_UINT("input_bind_hold",              &settings->uints.input_bind_hold,        true, input_bind_hold, false);
1956    SETTING_UINT("input_turbo_period",           &settings->uints.input_turbo_period,     true, turbo_period, false);
1957    SETTING_UINT("input_duty_cycle",             &settings->uints.input_turbo_duty_cycle, true, turbo_duty_cycle, false);
1958    SETTING_UINT("input_turbo_mode",             &settings->uints.input_turbo_mode, true, turbo_mode, false);
1959    SETTING_UINT("input_turbo_default_button",   &settings->uints.input_turbo_default_button, true, turbo_default_btn, false);
1960    SETTING_UINT("input_max_users",              input_driver_get_uint(INPUT_ACTION_MAX_USERS),        true, input_max_users, false);
1961    SETTING_UINT("fps_update_interval",          &settings->uints.fps_update_interval, true, DEFAULT_FPS_UPDATE_INTERVAL, false);
1962    SETTING_UINT("memory_update_interval",       &settings->uints.memory_update_interval, true, DEFAULT_MEMORY_UPDATE_INTERVAL, false);
1963    SETTING_UINT("input_menu_toggle_gamepad_combo", &settings->uints.input_menu_toggle_gamepad_combo, true, DEFAULT_MENU_TOGGLE_GAMEPAD_COMBO, false);
1964    SETTING_UINT("input_hotkey_block_delay",     &settings->uints.input_hotkey_block_delay, true, DEFAULT_INPUT_HOTKEY_BLOCK_DELAY, false);
1965 #ifdef GEKKO
1966    SETTING_UINT("input_mouse_scale",            &settings->uints.input_mouse_scale, true, DEFAULT_MOUSE_SCALE, false);
1967 #endif
1968    SETTING_UINT("input_touch_scale",            &settings->uints.input_touch_scale, true, DEFAULT_TOUCH_SCALE, false);
1969 #if defined(DINGUX) && defined(HAVE_LIBSHAKE)
1970    SETTING_UINT("input_dingux_rumble_gain",     &settings->uints.input_dingux_rumble_gain, true, DEFAULT_DINGUX_RUMBLE_GAIN, false);
1971 #endif
1972    SETTING_UINT("input_auto_game_focus",        &settings->uints.input_auto_game_focus, true, DEFAULT_INPUT_AUTO_GAME_FOCUS, false);
1973    SETTING_UINT("audio_latency",                &settings->uints.audio_latency, false, 0 /* TODO */, false);
1974    SETTING_UINT("audio_resampler_quality",      &settings->uints.audio_resampler_quality, true, audio_resampler_quality_level, false);
1975    SETTING_UINT("audio_block_frames",           &settings->uints.audio_block_frames, true, 0, false);
1976 #ifdef ANDROID
1977    SETTING_UINT("input_block_timeout",           &settings->uints.input_block_timeout, true, 1, false);
1978 #endif
1979    SETTING_UINT("rewind_granularity",           &settings->uints.rewind_granularity, true, DEFAULT_REWIND_GRANULARITY, false);
1980    SETTING_UINT("rewind_buffer_size_step",      &settings->uints.rewind_buffer_size_step, true, DEFAULT_REWIND_BUFFER_SIZE_STEP, false);
1981    SETTING_UINT("autosave_interval",            &settings->uints.autosave_interval,  true, DEFAULT_AUTOSAVE_INTERVAL, false);
1982    SETTING_UINT("savestate_max_keep",           &settings->uints.savestate_max_keep, true, DEFAULT_SAVESTATE_MAX_KEEP, false);
1983    SETTING_UINT("frontend_log_level",           &settings->uints.frontend_log_level, true, DEFAULT_FRONTEND_LOG_LEVEL, false);
1984    SETTING_UINT("libretro_log_level",           &settings->uints.libretro_log_level, true, DEFAULT_LIBRETRO_LOG_LEVEL, false);
1985    SETTING_UINT("keyboard_gamepad_mapping_type",&settings->uints.input_keyboard_gamepad_mapping_type, true, 1, false);
1986    SETTING_UINT("input_poll_type_behavior",     &settings->uints.input_poll_type_behavior, true, 2, false);
1987    SETTING_UINT("video_monitor_index",          &settings->uints.video_monitor_index, true, DEFAULT_MONITOR_INDEX, false);
1988    SETTING_UINT("video_fullscreen_x",           &settings->uints.video_fullscreen_x,  true, DEFAULT_FULLSCREEN_X, false);
1989    SETTING_UINT("video_fullscreen_y",           &settings->uints.video_fullscreen_y,  true, DEFAULT_FULLSCREEN_Y, false);
1990    SETTING_UINT("video_window_opacity",         &settings->uints.video_window_opacity, true, DEFAULT_WINDOW_OPACITY, false);
1991 #ifdef HAVE_VIDEO_LAYOUT
1992    SETTING_UINT("video_layout_selected_view",   &settings->uints.video_layout_selected_view, true, 0, false);
1993 #endif
1994    SETTING_UINT("video_shader_delay",           &settings->uints.video_shader_delay, true, DEFAULT_SHADER_DELAY, false);
1995 #ifdef HAVE_COMMAND
1996    SETTING_UINT("network_cmd_port",             &settings->uints.network_cmd_port,    true, network_cmd_port, false);
1997 #endif
1998 #ifdef HAVE_NETWORKGAMEPAD
1999    SETTING_UINT("network_remote_base_port",     &settings->uints.network_remote_base_port, true, network_remote_base_port, false);
2000 #endif
2001 #ifdef GEKKO
2002    SETTING_UINT("video_viwidth",                    &settings->uints.video_viwidth, true, DEFAULT_VIDEO_VI_WIDTH, false);
2003    SETTING_UINT("video_overscan_correction_top",    &settings->uints.video_overscan_correction_top, true, DEFAULT_VIDEO_OVERSCAN_CORRECTION_TOP, false);
2004    SETTING_UINT("video_overscan_correction_bottom", &settings->uints.video_overscan_correction_bottom, true, DEFAULT_VIDEO_OVERSCAN_CORRECTION_BOTTOM, false);
2005 #endif
2006 #ifdef HAVE_MENU
2007    SETTING_UINT("menu_thumbnails",              &settings->uints.gfx_thumbnails, true, gfx_thumbnails_default, false);
2008    SETTING_UINT("menu_left_thumbnails",         &settings->uints.menu_left_thumbnails, true, menu_left_thumbnails_default, false);
2009    SETTING_UINT("menu_thumbnail_upscale_threshold", &settings->uints.gfx_thumbnail_upscale_threshold, true, gfx_thumbnail_upscale_threshold, false);
2010    SETTING_UINT("menu_timedate_style",          &settings->uints.menu_timedate_style, true, DEFAULT_MENU_TIMEDATE_STYLE, false);
2011    SETTING_UINT("menu_timedate_date_separator", &settings->uints.menu_timedate_date_separator, true, DEFAULT_MENU_TIMEDATE_DATE_SEPARATOR, false);
2012    SETTING_UINT("menu_ticker_type",             &settings->uints.menu_ticker_type, true, DEFAULT_MENU_TICKER_TYPE, false);
2013    SETTING_UINT("menu_scroll_delay",            &settings->uints.menu_scroll_delay, true, DEFAULT_MENU_SCROLL_DELAY, false);
2014    SETTING_UINT("content_show_add_entry",       &settings->uints.menu_content_show_add_entry, true, DEFAULT_MENU_CONTENT_SHOW_ADD_ENTRY, false);
2015    SETTING_UINT("menu_screensaver_timeout",     &settings->uints.menu_screensaver_timeout, true, DEFAULT_MENU_SCREENSAVER_TIMEOUT, false);
2016 #if defined(HAVE_MATERIALUI) || defined(HAVE_XMB) || defined(HAVE_OZONE)
2017    SETTING_UINT("menu_screensaver_animation",   &settings->uints.menu_screensaver_animation, true, DEFAULT_MENU_SCREENSAVER_ANIMATION, false);
2018 #endif
2019 #ifdef HAVE_RGUI
2020    SETTING_UINT("rgui_menu_color_theme",        &settings->uints.menu_rgui_color_theme, true, DEFAULT_RGUI_COLOR_THEME, false);
2021    SETTING_UINT("rgui_thumbnail_downscaler",    &settings->uints.menu_rgui_thumbnail_downscaler, true, rgui_thumbnail_downscaler, false);
2022    SETTING_UINT("rgui_thumbnail_delay",         &settings->uints.menu_rgui_thumbnail_delay, true, rgui_thumbnail_delay, false);
2023    SETTING_UINT("rgui_internal_upscale_level",  &settings->uints.menu_rgui_internal_upscale_level, true, rgui_internal_upscale_level, false);
2024    SETTING_UINT("rgui_aspect_ratio",            &settings->uints.menu_rgui_aspect_ratio, true, rgui_aspect, false);
2025    SETTING_UINT("rgui_aspect_ratio_lock",       &settings->uints.menu_rgui_aspect_ratio_lock, true, rgui_aspect_lock, false);
2026    SETTING_UINT("rgui_particle_effect",         &settings->uints.menu_rgui_particle_effect, true, rgui_particle_effect, false);
2027 #endif
2028 #ifdef HAVE_LIBNX
2029    SETTING_UINT("split_joycon_p1", &settings->uints.input_split_joycon[0], true, 0, false);
2030    SETTING_UINT("split_joycon_p2", &settings->uints.input_split_joycon[1], true, 0, false);
2031    SETTING_UINT("split_joycon_p3", &settings->uints.input_split_joycon[2], true, 0, false);
2032    SETTING_UINT("split_joycon_p4", &settings->uints.input_split_joycon[3], true, 0, false);
2033    SETTING_UINT("split_joycon_p5", &settings->uints.input_split_joycon[4], true, 0, false);
2034    SETTING_UINT("split_joycon_p6", &settings->uints.input_split_joycon[5], true, 0, false);
2035    SETTING_UINT("split_joycon_p7", &settings->uints.input_split_joycon[6], true, 0, false);
2036    SETTING_UINT("split_joycon_p8", &settings->uints.input_split_joycon[7], true, 0, false);
2037 #endif
2038 #ifdef HAVE_XMB
2039    SETTING_UINT("menu_xmb_animation_opening_main_menu",    &settings->uints.menu_xmb_animation_opening_main_menu, true, DEFAULT_XMB_ANIMATION, false);
2040    SETTING_UINT("menu_xmb_animation_horizontal_highlight", &settings->uints.menu_xmb_animation_horizontal_highlight, true, DEFAULT_XMB_ANIMATION, false);
2041    SETTING_UINT("menu_xmb_animation_move_up_down",         &settings->uints.menu_xmb_animation_move_up_down, true, DEFAULT_XMB_ANIMATION, false);
2042    SETTING_UINT("xmb_alpha_factor",             &settings->uints.menu_xmb_alpha_factor, true, xmb_alpha_factor, false);
2043    SETTING_UINT("xmb_layout",                   &settings->uints.menu_xmb_layout, true, xmb_menu_layout, false);
2044    SETTING_UINT("xmb_theme",                    &settings->uints.menu_xmb_theme, true, xmb_icon_theme, false);
2045    SETTING_UINT("xmb_menu_color_theme",         &settings->uints.menu_xmb_color_theme, true, xmb_theme, false);
2046    SETTING_UINT("menu_font_color_red",          &settings->uints.menu_font_color_red, true, menu_font_color_red, false);
2047    SETTING_UINT("menu_font_color_green",        &settings->uints.menu_font_color_green, true, menu_font_color_green, false);
2048    SETTING_UINT("menu_font_color_blue",         &settings->uints.menu_font_color_blue, true, menu_font_color_blue, false);
2049    SETTING_UINT("menu_xmb_thumbnail_scale_factor", &settings->uints.menu_xmb_thumbnail_scale_factor, true, xmb_thumbnail_scale_factor, false);
2050 #endif
2051    SETTING_UINT("materialui_menu_color_theme",  &settings->uints.menu_materialui_color_theme, true, DEFAULT_MATERIALUI_THEME, false);
2052    SETTING_UINT("materialui_menu_transition_animation", &settings->uints.menu_materialui_transition_animation, true, DEFAULT_MATERIALUI_TRANSITION_ANIM, false);
2053    SETTING_UINT("materialui_thumbnail_view_portrait", &settings->uints.menu_materialui_thumbnail_view_portrait, true, DEFAULT_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT, false);
2054    SETTING_UINT("materialui_thumbnail_view_landscape", &settings->uints.menu_materialui_thumbnail_view_landscape, true, DEFAULT_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE, false);
2055    SETTING_UINT("materialui_landscape_layout_optimization", &settings->uints.menu_materialui_landscape_layout_optimization, true, DEFAULT_MATERIALUI_LANDSCAPE_LAYOUT_OPTIMIZATION, false);
2056    SETTING_UINT("menu_shader_pipeline",         &settings->uints.menu_xmb_shader_pipeline, true, DEFAULT_MENU_SHADER_PIPELINE, false);
2057 #ifdef HAVE_OZONE
2058    SETTING_UINT("ozone_menu_color_theme",       &settings->uints.menu_ozone_color_theme, true, DEFAULT_OZONE_COLOR_THEME, false);
2059 #endif
2060 #endif
2061    SETTING_UINT("audio_out_rate",               &settings->uints.audio_output_sample_rate, true, DEFAULT_OUTPUT_RATE, false);
2062    SETTING_UINT("custom_viewport_width",        &settings->video_viewport_custom.width, false, 0 /* TODO */, false);
2063    SETTING_UINT("crt_switch_resolution_super",  &settings->uints.crt_switch_resolution_super,      true, DEFAULT_CRT_SWITCH_RESOLUTION_SUPER, false);
2064    SETTING_UINT("custom_viewport_height",       &settings->video_viewport_custom.height, false, 0 /* TODO */, false);
2065    SETTING_UINT("custom_viewport_x",            (unsigned*)&settings->video_viewport_custom.x, false, 0 /* TODO */, false);
2066    SETTING_UINT("custom_viewport_y",            (unsigned*)&settings->video_viewport_custom.y, false, 0 /* TODO */, false);
2067    SETTING_UINT("content_history_size",         &settings->uints.content_history_size,   true, default_content_history_size, false);
2068    SETTING_UINT("video_hard_sync_frames",       &settings->uints.video_hard_sync_frames, true, DEFAULT_HARD_SYNC_FRAMES, false);
2069    SETTING_UINT("video_frame_delay",            &settings->uints.video_frame_delay,      true, DEFAULT_FRAME_DELAY, false);
2070    SETTING_UINT("video_max_swapchain_images",   &settings->uints.video_max_swapchain_images, true, DEFAULT_MAX_SWAPCHAIN_IMAGES, false);
2071    SETTING_UINT("video_swap_interval",          &settings->uints.video_swap_interval, true, DEFAULT_SWAP_INTERVAL, false);
2072    SETTING_UINT("video_rotation",               &settings->uints.video_rotation, true, ORIENTATION_NORMAL, false);
2073    SETTING_UINT("screen_orientation",           &settings->uints.screen_orientation, true, ORIENTATION_NORMAL, false);
2074    SETTING_UINT("aspect_ratio_index",           &settings->uints.video_aspect_ratio_idx, true, DEFAULT_ASPECT_RATIO_IDX, false);
2075 #ifdef HAVE_SCREENSHOTS
2076    SETTING_UINT("notification_show_screenshot_duration",    &settings->uints.notification_show_screenshot_duration, true, DEFAULT_NOTIFICATION_SHOW_SCREENSHOT_DURATION, false);
2077    SETTING_UINT("notification_show_screenshot_flash",       &settings->uints.notification_show_screenshot_flash, true, DEFAULT_NOTIFICATION_SHOW_SCREENSHOT_FLASH, false);
2078 #endif
2079 #ifdef HAVE_NETWORKING
2080    SETTING_UINT("netplay_ip_port",              &settings->uints.netplay_port,         true, RARCH_DEFAULT_PORT, false);
2081    SETTING_OVERRIDE(RARCH_OVERRIDE_SETTING_NETPLAY_IP_PORT);
2082    SETTING_UINT("netplay_input_latency_frames_min",&settings->uints.netplay_input_latency_frames_min, true, 0, false);
2083    SETTING_UINT("netplay_input_latency_frames_range",&settings->uints.netplay_input_latency_frames_range, true, 0, false);
2084    SETTING_UINT("netplay_share_digital",        &settings->uints.netplay_share_digital, true, netplay_share_digital, false);
2085    SETTING_UINT("netplay_share_analog",         &settings->uints.netplay_share_analog,  true, netplay_share_analog, false);
2086 #endif
2087 #ifdef HAVE_LANGEXTRA
2088 #ifdef VITA
2089    SETTING_UINT("user_language",                msg_hash_get_uint(MSG_HASH_USER_LANGUAGE), true, frontend_driver_get_user_language(), false);
2090 #else
2091    SETTING_UINT("user_language",                msg_hash_get_uint(MSG_HASH_USER_LANGUAGE), true, DEFAULT_USER_LANGUAGE, false);
2092 #endif
2093 #endif
2094 #ifndef __APPLE__
2095    SETTING_UINT("bundle_assets_extract_version_current", &settings->uints.bundle_assets_extract_version_current, true, 0, false);
2096 #endif
2097    SETTING_UINT("bundle_assets_extract_last_version",    &settings->uints.bundle_assets_extract_last_version, true, 0, false);
2098 
2099 #if defined(HAVE_OVERLAY)
2100    SETTING_UINT("input_overlay_show_inputs",      &settings->uints.input_overlay_show_inputs, true, DEFAULT_OVERLAY_SHOW_INPUTS, false);
2101    SETTING_UINT("input_overlay_show_inputs_port", &settings->uints.input_overlay_show_inputs_port, true, DEFAULT_OVERLAY_SHOW_INPUTS_PORT, false);
2102 #endif
2103 
2104    SETTING_UINT("video_msg_bgcolor_red",        &settings->uints.video_msg_bgcolor_red, true, message_bgcolor_red, false);
2105    SETTING_UINT("video_msg_bgcolor_green",        &settings->uints.video_msg_bgcolor_green, true, message_bgcolor_green, false);
2106    SETTING_UINT("video_msg_bgcolor_blue",        &settings->uints.video_msg_bgcolor_blue, true, message_bgcolor_blue, false);
2107 
2108    SETTING_UINT("run_ahead_frames",           &settings->uints.run_ahead_frames, true, 1,  false);
2109 
2110    SETTING_UINT("midi_volume",                  &settings->uints.midi_volume, true, midi_volume, false);
2111 
2112    SETTING_UINT("video_stream_port",            &settings->uints.video_stream_port,    true, RARCH_STREAM_DEFAULT_PORT, false);
2113    SETTING_UINT("video_record_quality",            &settings->uints.video_record_quality,    true, RECORD_CONFIG_TYPE_RECORDING_MED_QUALITY, false);
2114    SETTING_UINT("video_stream_quality",            &settings->uints.video_stream_quality,    true, RECORD_CONFIG_TYPE_STREAMING_MED_QUALITY, false);
2115    SETTING_UINT("video_record_scale_factor",            &settings->uints.video_record_scale_factor,    true, 1, false);
2116    SETTING_UINT("video_stream_scale_factor",            &settings->uints.video_stream_scale_factor,    true, 1, false);
2117    SETTING_UINT("video_windowed_position_x",            &settings->uints.window_position_x,    true, 0, false);
2118    SETTING_UINT("video_windowed_position_y",            &settings->uints.window_position_y,    true, 0, false);
2119    SETTING_UINT("video_windowed_position_width",            &settings->uints.window_position_width,    true, DEFAULT_WINDOW_WIDTH, false);
2120    SETTING_UINT("video_windowed_position_height",            &settings->uints.window_position_height,    true, DEFAULT_WINDOW_HEIGHT, false);
2121    SETTING_UINT("ai_service_mode",            &settings->uints.ai_service_mode,    true, DEFAULT_AI_SERVICE_MODE, false);
2122    SETTING_UINT("ai_service_target_lang",            &settings->uints.ai_service_target_lang,    true, 0, false);
2123    SETTING_UINT("ai_service_source_lang",            &settings->uints.ai_service_source_lang,    true, 0, false);
2124 
2125    SETTING_UINT("video_record_threads",            &settings->uints.video_record_threads,    true, DEFAULT_VIDEO_RECORD_THREADS, false);
2126 
2127 #ifdef HAVE_LIBNX
2128    SETTING_UINT("libnx_overclock",  &settings->uints.libnx_overclock, true, SWITCH_DEFAULT_CPU_PROFILE, false);
2129 #endif
2130 
2131 #ifdef _3DS
2132    SETTING_UINT("video_3ds_display_mode",  &settings->uints.video_3ds_display_mode, true, video_3ds_display_mode, false);
2133 #endif
2134 
2135 #if defined(DINGUX)
2136    SETTING_UINT("video_dingux_ipu_filter_type", &settings->uints.video_dingux_ipu_filter_type, true, DEFAULT_DINGUX_IPU_FILTER_TYPE, false);
2137 #if defined(DINGUX_BETA)
2138    SETTING_UINT("video_dingux_refresh_rate",    &settings->uints.video_dingux_refresh_rate, true, DEFAULT_DINGUX_REFRESH_RATE, false);
2139 #endif
2140 #if defined(RS90)
2141    SETTING_UINT("video_dingux_rs90_softfilter_type", &settings->uints.video_dingux_rs90_softfilter_type, true, DEFAULT_DINGUX_RS90_SOFTFILTER_TYPE, false);
2142 #endif
2143 #endif
2144 
2145 #ifdef HAVE_MENU
2146    SETTING_UINT("playlist_entry_remove_enable",    &settings->uints.playlist_entry_remove_enable, true, DEFAULT_PLAYLIST_ENTRY_REMOVE_ENABLE, false);
2147    SETTING_UINT("playlist_show_inline_core_name",  &settings->uints.playlist_show_inline_core_name, true, DEFAULT_PLAYLIST_SHOW_INLINE_CORE_NAME, false);
2148    SETTING_UINT("playlist_sublabel_runtime_type",  &settings->uints.playlist_sublabel_runtime_type, true, DEFAULT_PLAYLIST_SUBLABEL_RUNTIME_TYPE, false);
2149    SETTING_UINT("playlist_sublabel_last_played_style", &settings->uints.playlist_sublabel_last_played_style, true, DEFAULT_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE, false);
2150 
2151    SETTING_UINT("quit_on_close_content",           &settings->uints.quit_on_close_content, true, DEFAULT_QUIT_ON_CLOSE_CONTENT, false);
2152 #endif
2153 
2154    SETTING_UINT("core_updater_auto_backup_history_size", &settings->uints.core_updater_auto_backup_history_size, true, DEFAULT_CORE_UPDATER_AUTO_BACKUP_HISTORY_SIZE, false);
2155 
2156    SETTING_UINT("video_black_frame_insertion",   &settings->uints.video_black_frame_insertion, true, DEFAULT_BLACK_FRAME_INSERTION, false);
2157 
2158 #ifdef HAVE_LAKKA
2159    SETTING_UINT("cpu_scaling_mode",            &settings->uints.cpu_scaling_mode,    true,   0, false);
2160    SETTING_UINT("cpu_min_freq",                &settings->uints.cpu_min_freq,        true,   1, false);
2161    SETTING_UINT("cpu_max_freq",                &settings->uints.cpu_max_freq,        true, ~0U, false);
2162 #endif
2163 
2164    *size = count;
2165 
2166    return tmp;
2167 }
2168 
populate_settings_size(settings_t * settings,int * size)2169 static struct config_size_setting *populate_settings_size(
2170       settings_t *settings, int *size)
2171 {
2172    unsigned count                     = 0;
2173    struct config_size_setting  *tmp   = (struct config_size_setting*)calloc((*size + 1), sizeof(struct config_size_setting));
2174 
2175    if (!tmp)
2176       return NULL;
2177 
2178    SETTING_SIZE("rewind_buffer_size",           &settings->sizes.rewind_buffer_size, true, DEFAULT_REWIND_BUFFER_SIZE, false);
2179 
2180    *size = count;
2181 
2182    return tmp;
2183 }
2184 
populate_settings_int(settings_t * settings,int * size)2185 static struct config_int_setting *populate_settings_int(
2186       settings_t *settings, int *size)
2187 {
2188    unsigned count                     = 0;
2189    struct config_int_setting  *tmp    = (struct config_int_setting*)calloc((*size + 1), sizeof(struct config_int_setting));
2190 
2191    if (!tmp)
2192       return NULL;
2193 
2194    SETTING_INT("state_slot",                   &settings->ints.state_slot, false, 0 /* TODO */, false);
2195 #ifdef HAVE_NETWORKING
2196    SETTING_INT("netplay_check_frames",         &settings->ints.netplay_check_frames, true, netplay_check_frames, false);
2197    SETTING_OVERRIDE(RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES);
2198 #endif
2199 #ifdef HAVE_WASAPI
2200    SETTING_INT("audio_wasapi_sh_buffer_length", &settings->ints.audio_wasapi_sh_buffer_length, true, DEFAULT_WASAPI_SH_BUFFER_LENGTH, false);
2201 #endif
2202    SETTING_INT("crt_switch_center_adjust",      &settings->ints.crt_switch_center_adjust, false, DEFAULT_CRT_SWITCH_CENTER_ADJUST, false);
2203    SETTING_INT("crt_switch_porch_adjust",      &settings->ints.crt_switch_porch_adjust, false, DEFAULT_CRT_SWITCH_PORCH_ADJUST, false);
2204 #ifdef HAVE_VULKAN
2205    SETTING_INT("vulkan_gpu_index",              &settings->ints.vulkan_gpu_index, true, DEFAULT_VULKAN_GPU_INDEX, false);
2206 #endif
2207 #ifdef HAVE_D3D10
2208    SETTING_INT("d3d10_gpu_index",              &settings->ints.d3d10_gpu_index, true, DEFAULT_D3D10_GPU_INDEX, false);
2209 #endif
2210 #ifdef HAVE_D3D11
2211    SETTING_INT("d3d11_gpu_index",              &settings->ints.d3d11_gpu_index, true, DEFAULT_D3D11_GPU_INDEX, false);
2212 #endif
2213 #ifdef HAVE_D3D12
2214    SETTING_INT("d3d12_gpu_index",              &settings->ints.d3d12_gpu_index, true, DEFAULT_D3D12_GPU_INDEX, false);
2215 #endif
2216    SETTING_INT("content_favorites_size",       &settings->ints.content_favorites_size, true, default_content_favorites_size, false);
2217 
2218    *size = count;
2219 
2220    return tmp;
2221 }
2222 
video_driver_default_settings(global_t * global)2223 static void video_driver_default_settings(global_t *global)
2224 {
2225    if (!global)
2226       return;
2227 
2228    global->console.screen.gamma_correction       = DEFAULT_GAMMA;
2229    global->console.flickerfilter_enable          = false;
2230    global->console.softfilter_enable             = false;
2231 
2232    global->console.screen.resolutions.current.id = 0;
2233 }
2234 
2235 /**
2236  * config_set_defaults:
2237  *
2238  * Set 'default' configuration values.
2239  **/
config_set_defaults(void * data)2240 void config_set_defaults(void *data)
2241 {
2242    unsigned i, j;
2243 #ifdef HAVE_MENU
2244    static bool first_initialized   = true;
2245 #endif
2246    global_t *global                = (global_t*)data;
2247    settings_t *settings            = config_get_ptr();
2248    int bool_settings_size          = sizeof(settings->bools)   / sizeof(settings->bools.placeholder);
2249    int float_settings_size         = sizeof(settings->floats)  / sizeof(settings->floats.placeholder);
2250    int int_settings_size           = sizeof(settings->ints)    / sizeof(settings->ints.placeholder);
2251    int uint_settings_size          = sizeof(settings->uints)   / sizeof(settings->uints.placeholder);
2252    int size_settings_size          = sizeof(settings->sizes)   / sizeof(settings->sizes.placeholder);
2253    const char *def_video           = config_get_default_video();
2254    const char *def_audio           = config_get_default_audio();
2255    const char *def_audio_resampler = config_get_default_audio_resampler();
2256    const char *def_input           = config_get_default_input();
2257    const char *def_joypad          = config_get_default_joypad();
2258 #ifdef HAVE_MENU
2259    const char *def_menu            = config_get_default_menu();
2260 #endif
2261    const char *def_camera          = config_get_default_camera();
2262    const char *def_bluetooth       = config_get_default_bluetooth();
2263    const char *def_wifi            = config_get_default_wifi();
2264    const char *def_led             = config_get_default_led();
2265    const char *def_location        = config_get_default_location();
2266    const char *def_record          = config_get_default_record();
2267    const char *def_midi            = config_get_default_midi();
2268    const char *def_mitm            = DEFAULT_NETPLAY_MITM_SERVER;
2269    struct config_float_setting      *float_settings = populate_settings_float  (settings, &float_settings_size);
2270    struct config_bool_setting       *bool_settings  = populate_settings_bool  (settings, &bool_settings_size);
2271    struct config_int_setting        *int_settings   = populate_settings_int   (settings, &int_settings_size);
2272    struct config_uint_setting       *uint_settings  = populate_settings_uint   (settings, &uint_settings_size);
2273    struct config_size_setting       *size_settings  = populate_settings_size   (settings, &size_settings_size);
2274 
2275    if (bool_settings && (bool_settings_size > 0))
2276    {
2277       for (i = 0; i < (unsigned)bool_settings_size; i++)
2278       {
2279          if (bool_settings[i].def_enable)
2280             *bool_settings[i].ptr = bool_settings[i].def;
2281       }
2282 
2283       free(bool_settings);
2284    }
2285 
2286    if (int_settings && (int_settings_size > 0))
2287    {
2288       for (i = 0; i < (unsigned)int_settings_size; i++)
2289       {
2290          if (int_settings[i].def_enable)
2291             *int_settings[i].ptr = int_settings[i].def;
2292       }
2293 
2294       free(int_settings);
2295    }
2296 
2297    if (uint_settings && (uint_settings_size > 0))
2298    {
2299       for (i = 0; i < (unsigned)uint_settings_size; i++)
2300       {
2301          if (uint_settings[i].def_enable)
2302             *uint_settings[i].ptr = uint_settings[i].def;
2303       }
2304 
2305       free(uint_settings);
2306    }
2307 
2308    if (size_settings && (size_settings_size > 0))
2309    {
2310       for (i = 0; i < (unsigned)size_settings_size; i++)
2311       {
2312          if (size_settings[i].def_enable)
2313             *size_settings[i].ptr = size_settings[i].def;
2314       }
2315 
2316       free(size_settings);
2317    }
2318 
2319    if (float_settings && (float_settings_size > 0))
2320    {
2321       for (i = 0; i < (unsigned)float_settings_size; i++)
2322       {
2323          if (float_settings[i].def_enable)
2324             *float_settings[i].ptr = float_settings[i].def;
2325       }
2326 
2327       free(float_settings);
2328    }
2329 
2330    if (def_camera)
2331       configuration_set_string(settings,
2332             settings->arrays.camera_driver,
2333             def_camera);
2334    if (def_bluetooth)
2335       configuration_set_string(settings,
2336             settings->arrays.bluetooth_driver,
2337             def_bluetooth);
2338    if (def_wifi)
2339       configuration_set_string(settings,
2340             settings->arrays.wifi_driver,
2341             def_wifi);
2342    if (def_led)
2343       configuration_set_string(settings,
2344             settings->arrays.led_driver,
2345             def_led);
2346    if (def_location)
2347       configuration_set_string(settings,
2348             settings->arrays.location_driver,
2349             def_location);
2350    if (def_video)
2351       configuration_set_string(settings,
2352             settings->arrays.video_driver,
2353             def_video);
2354    if (def_audio)
2355       configuration_set_string(settings,
2356             settings->arrays.audio_driver,
2357             def_audio);
2358    if (def_audio_resampler)
2359       configuration_set_string(settings,
2360             settings->arrays.audio_resampler,
2361             def_audio_resampler);
2362    if (def_input)
2363       configuration_set_string(settings,
2364             settings->arrays.input_driver,
2365             def_input);
2366    if (def_joypad)
2367       configuration_set_string(settings,
2368             settings->arrays.input_joypad_driver,
2369             def_joypad);
2370    if (def_record)
2371       configuration_set_string(settings,
2372             settings->arrays.record_driver,
2373             def_record);
2374    if (def_midi)
2375       configuration_set_string(settings,
2376             settings->arrays.midi_driver,
2377             def_midi);
2378    if (def_mitm)
2379       configuration_set_string(settings,
2380             settings->arrays.netplay_mitm_server,
2381             def_mitm);
2382 #ifdef HAVE_MENU
2383    if (def_menu)
2384       configuration_set_string(settings,
2385             settings->arrays.menu_driver,
2386             def_menu);
2387 #ifdef HAVE_XMB
2388    *settings->paths.path_menu_xmb_font            = '\0';
2389 #endif
2390 
2391    configuration_set_string(settings,
2392          settings->arrays.discord_app_id,
2393          DEFAULT_DISCORD_APP_ID);
2394 
2395    configuration_set_string(settings,
2396          settings->arrays.ai_service_url,
2397          DEFAULT_AI_SERVICE_URL);
2398 
2399 
2400 #ifdef HAVE_MATERIALUI
2401    if (g_defaults.menu_materialui_menu_color_theme_enable)
2402       settings->uints.menu_materialui_color_theme = g_defaults.menu_materialui_menu_color_theme;
2403 #endif
2404 #endif
2405 
2406    settings->floats.video_scale                = DEFAULT_SCALE;
2407 
2408    video_driver_set_threaded(DEFAULT_VIDEO_THREADED);
2409 
2410    settings->floats.video_msg_color_r          = ((message_color >> 16) & 0xff) / 255.0f;
2411    settings->floats.video_msg_color_g          = ((message_color >>  8) & 0xff) / 255.0f;
2412    settings->floats.video_msg_color_b          = ((message_color >>  0) & 0xff) / 255.0f;
2413 
2414    if (g_defaults.settings_video_refresh_rate > 0.0 &&
2415          g_defaults.settings_video_refresh_rate != DEFAULT_REFRESH_RATE)
2416       settings->floats.video_refresh_rate      = g_defaults.settings_video_refresh_rate;
2417 
2418    if (DEFAULT_AUDIO_DEVICE)
2419       configuration_set_string(settings,
2420             settings->arrays.audio_device,
2421             DEFAULT_AUDIO_DEVICE);
2422 
2423    if (!g_defaults.settings_out_latency)
2424       g_defaults.settings_out_latency          = DEFAULT_OUT_LATENCY;
2425 
2426    settings->uints.audio_latency               = g_defaults.settings_out_latency;
2427 
2428    audio_set_float(AUDIO_ACTION_VOLUME_GAIN, settings->floats.audio_volume);
2429 #ifdef HAVE_AUDIOMIXER
2430    audio_set_float(AUDIO_ACTION_MIXER_VOLUME_GAIN, settings->floats.audio_mixer_volume);
2431 #endif
2432 
2433 #ifdef HAVE_LAKKA
2434    configuration_set_bool(settings,
2435          settings->bools.ssh_enable, filestream_exists(LAKKA_SSH_PATH));
2436    configuration_set_bool(settings,
2437          settings->bools.samba_enable, filestream_exists(LAKKA_SAMBA_PATH));
2438    configuration_set_bool(settings,
2439          settings->bools.bluetooth_enable, filestream_exists(LAKKA_BLUETOOTH_PATH));
2440    configuration_set_bool(settings, settings->bools.localap_enable, false);
2441    load_timezone(settings->arrays.timezone);
2442 #endif
2443 
2444 #ifdef HAVE_MENU
2445    if (first_initialized)
2446       configuration_set_bool(settings,
2447             settings->bools.menu_show_start_screen,
2448             DEFAULT_MENU_SHOW_START_SCREEN);
2449 #endif
2450 
2451 #ifdef HAVE_CHEEVOS
2452    *settings->arrays.cheevos_username                 = '\0';
2453    *settings->arrays.cheevos_password                 = '\0';
2454    *settings->arrays.cheevos_token                    = '\0';
2455 #endif
2456 
2457    input_config_reset();
2458    input_remapping_deinit();
2459    input_remapping_set_defaults(false);
2460 
2461    /* Verify that binds are in proper order. */
2462    for (i = 0; i < MAX_USERS; i++)
2463    {
2464       for (j = 0; j < RARCH_BIND_LIST_END; j++)
2465       {
2466          const struct retro_keybind *keyval = &input_config_binds[i][j];
2467          if (keyval->valid)
2468             retro_assert(j == keyval->id);
2469       }
2470    }
2471 
2472    configuration_set_string(settings,
2473          settings->paths.network_buildbot_url, DEFAULT_BUILDBOT_SERVER_URL);
2474    configuration_set_string(settings,
2475          settings->paths.network_buildbot_assets_url,
2476          DEFAULT_BUILDBOT_ASSETS_SERVER_URL);
2477 
2478    *settings->arrays.input_keyboard_layout                = '\0';
2479 
2480    for (i = 0; i < MAX_USERS; i++)
2481    {
2482       settings->uints.input_joypad_index[i] = i;
2483 #ifdef SWITCH /* Switch prefered default dpad mode */
2484       settings->uints.input_analog_dpad_mode[i] = ANALOG_DPAD_LSTICK;
2485 #else
2486       settings->uints.input_analog_dpad_mode[i] = ANALOG_DPAD_NONE;
2487 #endif
2488       input_config_set_device(i, RETRO_DEVICE_JOYPAD);
2489       settings->uints.input_mouse_index[i] = 0;
2490    }
2491 
2492    video_driver_reset_custom_viewport();
2493 
2494    /* Make sure settings from other configs carry over into defaults
2495     * for another config. */
2496    if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL))
2497       dir_clear(RARCH_DIR_SAVEFILE);
2498    if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL))
2499       dir_clear(RARCH_DIR_SAVESTATE);
2500 
2501    *settings->paths.path_libretro_info = '\0';
2502    *settings->paths.directory_libretro = '\0';
2503    *settings->paths.directory_cursor = '\0';
2504    *settings->paths.directory_resampler = '\0';
2505    *settings->paths.directory_screenshot = '\0';
2506    *settings->paths.directory_system = '\0';
2507    *settings->paths.directory_cache = '\0';
2508    *settings->paths.directory_input_remapping = '\0';
2509    *settings->paths.directory_core_assets = '\0';
2510    *settings->paths.directory_assets = '\0';
2511    *settings->paths.directory_dynamic_wallpapers = '\0';
2512    *settings->paths.directory_thumbnails = '\0';
2513    *settings->paths.directory_playlist = '\0';
2514    *settings->paths.directory_content_favorites = '\0';
2515    *settings->paths.directory_content_history = '\0';
2516    *settings->paths.directory_content_image_history = '\0';
2517    *settings->paths.directory_content_music_history = '\0';
2518    *settings->paths.directory_content_video_history = '\0';
2519    *settings->paths.directory_runtime_log = '\0';
2520    *settings->paths.directory_autoconfig = '\0';
2521 #ifdef HAVE_MENU
2522    *settings->paths.directory_menu_content = '\0';
2523    *settings->paths.directory_menu_config = '\0';
2524 #endif
2525    *settings->paths.directory_video_shader = '\0';
2526    *settings->paths.directory_video_filter = '\0';
2527    *settings->paths.directory_audio_filter = '\0';
2528 
2529    rarch_ctl(RARCH_CTL_UNSET_UPS_PREF, NULL);
2530    rarch_ctl(RARCH_CTL_UNSET_BPS_PREF, NULL);
2531    rarch_ctl(RARCH_CTL_UNSET_IPS_PREF, NULL);
2532 
2533    if (global)
2534    {
2535       *global->record.output_dir = '\0';
2536       *global->record.config_dir = '\0';
2537    }
2538 
2539    *settings->paths.path_core_options      = '\0';
2540    *settings->paths.path_content_favorites = '\0';
2541    *settings->paths.path_content_history   = '\0';
2542    *settings->paths.path_content_image_history   = '\0';
2543    *settings->paths.path_content_music_history   = '\0';
2544    *settings->paths.path_content_video_history   = '\0';
2545    *settings->paths.path_cheat_settings    = '\0';
2546 #if !defined(__APPLE__)
2547    *settings->arrays.bundle_assets_src = '\0';
2548    *settings->arrays.bundle_assets_dst = '\0';
2549    *settings->arrays.bundle_assets_dst_subdir = '\0';
2550 #endif
2551    *settings->paths.path_cheat_database    = '\0';
2552    *settings->paths.path_menu_wallpaper    = '\0';
2553    *settings->paths.path_rgui_theme_preset = '\0';
2554    *settings->paths.path_content_database  = '\0';
2555    *settings->paths.path_overlay           = '\0';
2556 #ifdef HAVE_VIDEO_LAYOUT
2557    *settings->paths.path_video_layout      = '\0';
2558 #endif
2559    *settings->paths.path_record_config     = '\0';
2560    *settings->paths.path_stream_config     = '\0';
2561    *settings->paths.path_stream_url        = '\0';
2562    *settings->paths.path_softfilter_plugin = '\0';
2563 
2564    *settings->paths.path_audio_dsp_plugin = '\0';
2565 
2566    *settings->paths.log_dir = '\0';
2567 
2568    video_driver_default_settings(global);
2569 
2570    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS]))
2571       configuration_set_string(settings,
2572             settings->paths.directory_dynamic_wallpapers,
2573             g_defaults.dirs[DEFAULT_DIR_WALLPAPERS]);
2574    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_THUMBNAILS]))
2575       configuration_set_string(settings,
2576             settings->paths.directory_thumbnails,
2577             g_defaults.dirs[DEFAULT_DIR_THUMBNAILS]);
2578    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_REMAP]))
2579       configuration_set_string(settings,
2580             settings->paths.directory_input_remapping,
2581             g_defaults.dirs[DEFAULT_DIR_REMAP]);
2582    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CACHE]))
2583       configuration_set_string(settings,
2584             settings->paths.directory_cache,
2585             g_defaults.dirs[DEFAULT_DIR_CACHE]);
2586    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_ASSETS]))
2587       configuration_set_string(settings,
2588             settings->paths.directory_assets,
2589             g_defaults.dirs[DEFAULT_DIR_ASSETS]);
2590    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS]))
2591       configuration_set_string(settings,
2592             settings->paths.directory_core_assets,
2593             g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS]);
2594    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_PLAYLIST]))
2595       configuration_set_string(settings,
2596             settings->paths.directory_playlist,
2597             g_defaults.dirs[DEFAULT_DIR_PLAYLIST]);
2598    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CONTENT_FAVORITES]))
2599       configuration_set_string(settings,
2600             settings->paths.directory_content_favorites,
2601             g_defaults.dirs[DEFAULT_DIR_CONTENT_FAVORITES]);
2602    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY]))
2603       configuration_set_string(settings,
2604             settings->paths.directory_content_history,
2605             g_defaults.dirs[DEFAULT_DIR_CONTENT_HISTORY]);
2606    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CONTENT_IMAGE_HISTORY]))
2607       configuration_set_string(settings,
2608             settings->paths.directory_content_image_history,
2609             g_defaults.dirs[DEFAULT_DIR_CONTENT_IMAGE_HISTORY]);
2610    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CONTENT_MUSIC_HISTORY]))
2611       configuration_set_string(settings,
2612             settings->paths.directory_content_music_history,
2613             g_defaults.dirs[DEFAULT_DIR_CONTENT_MUSIC_HISTORY]);
2614    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CONTENT_VIDEO_HISTORY]))
2615       configuration_set_string(settings,
2616             settings->paths.directory_content_video_history,
2617             g_defaults.dirs[DEFAULT_DIR_CONTENT_VIDEO_HISTORY]);
2618    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CORE]))
2619       fill_pathname_expand_special(settings->paths.directory_libretro,
2620             g_defaults.dirs[DEFAULT_DIR_CORE],
2621             sizeof(settings->paths.directory_libretro));
2622    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER]))
2623       configuration_set_string(settings,
2624             settings->paths.directory_audio_filter,
2625             g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER]);
2626    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER]))
2627       configuration_set_string(settings,
2628             settings->paths.directory_video_filter,
2629             g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER]);
2630    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_SHADER]))
2631       fill_pathname_expand_special(settings->paths.directory_video_shader,
2632             g_defaults.dirs[DEFAULT_DIR_SHADER],
2633             sizeof(settings->paths.directory_video_shader));
2634 
2635    if (!string_is_empty(g_defaults.path_buildbot_server_url))
2636       configuration_set_string(settings,
2637             settings->paths.network_buildbot_url,
2638             g_defaults.path_buildbot_server_url);
2639    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_DATABASE]))
2640       configuration_set_string(settings,
2641             settings->paths.path_content_database,
2642             g_defaults.dirs[DEFAULT_DIR_DATABASE]);
2643    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CURSOR]))
2644       configuration_set_string(settings,
2645             settings->paths.directory_cursor,
2646             g_defaults.dirs[DEFAULT_DIR_CURSOR]);
2647    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CHEATS]))
2648       configuration_set_string(settings,
2649             settings->paths.path_cheat_database,
2650             g_defaults.dirs[DEFAULT_DIR_CHEATS]);
2651    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]))
2652       fill_pathname_expand_special(settings->paths.path_libretro_info,
2653             g_defaults.dirs[DEFAULT_DIR_CORE_INFO],
2654             sizeof(settings->paths.path_libretro_info));
2655 #ifdef HAVE_OVERLAY
2656    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_OVERLAY]))
2657    {
2658       fill_pathname_expand_special(settings->paths.directory_overlay,
2659             g_defaults.dirs[DEFAULT_DIR_OVERLAY],
2660             sizeof(settings->paths.directory_overlay));
2661 #ifdef RARCH_MOBILE
2662       if (string_is_empty(settings->paths.path_overlay))
2663       {
2664          fill_pathname_join(settings->paths.path_overlay,
2665                settings->paths.directory_overlay,
2666                FILE_PATH_DEFAULT_OVERLAY,
2667                sizeof(settings->paths.path_overlay));
2668       }
2669 #endif
2670    }
2671 #endif
2672 #ifdef HAVE_VIDEO_LAYOUT
2673    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT]))
2674    {
2675       fill_pathname_expand_special(settings->paths.directory_video_layout,
2676             g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT],
2677             sizeof(settings->paths.directory_video_layout));
2678    }
2679 #endif
2680 
2681 #ifdef HAVE_MENU
2682    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG]))
2683    {
2684       configuration_set_string(settings,
2685             settings->paths.directory_menu_config,
2686             g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG]);
2687 #if TARGET_OS_IPHONE
2688       {
2689          char config_file_path[PATH_MAX_LENGTH];
2690 
2691          config_file_path[0]           = '\0';
2692 
2693          fill_pathname_join(config_file_path,
2694                settings->paths.directory_menu_config,
2695                FILE_PATH_MAIN_CONFIG,
2696                sizeof(config_file_path));
2697          path_set(RARCH_PATH_CONFIG,
2698                config_file_path);
2699       }
2700 #endif
2701    }
2702 
2703    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_MENU_CONTENT]))
2704       configuration_set_string(settings,
2705             settings->paths.directory_menu_content,
2706             g_defaults.dirs[DEFAULT_DIR_MENU_CONTENT]);
2707 #endif
2708    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG]))
2709       configuration_set_string(settings,
2710             settings->paths.directory_autoconfig,
2711             g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG]);
2712 
2713    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_SAVESTATE]))
2714       dir_set(RARCH_DIR_SAVESTATE, g_defaults.dirs[DEFAULT_DIR_SAVESTATE]);
2715 
2716    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_SRAM]))
2717       dir_set(RARCH_DIR_SAVEFILE, g_defaults.dirs[DEFAULT_DIR_SRAM]);
2718 
2719    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_SYSTEM]))
2720       configuration_set_string(settings,
2721             settings->paths.directory_system,
2722             g_defaults.dirs[DEFAULT_DIR_SYSTEM]);
2723    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT]))
2724       configuration_set_string(settings,
2725             settings->paths.directory_screenshot,
2726             g_defaults.dirs[DEFAULT_DIR_SCREENSHOT]);
2727    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_RESAMPLER]))
2728       configuration_set_string(settings,
2729             settings->paths.directory_resampler,
2730             g_defaults.dirs[DEFAULT_DIR_RESAMPLER]);
2731    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_LOGS]))
2732       configuration_set_string(settings,
2733             settings->paths.log_dir,
2734             g_defaults.dirs[DEFAULT_DIR_LOGS]);
2735 
2736    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_RECORD_OUTPUT]))
2737       fill_pathname_expand_special(global->record.output_dir,
2738             g_defaults.dirs[DEFAULT_DIR_RECORD_OUTPUT],
2739             sizeof(global->record.output_dir));
2740    if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG]))
2741       fill_pathname_expand_special(global->record.config_dir,
2742             g_defaults.dirs[DEFAULT_DIR_RECORD_CONFIG],
2743             sizeof(global->record.config_dir));
2744 
2745    if (!string_is_empty(g_defaults.path_config))
2746    {
2747       char temp_str[PATH_MAX_LENGTH];
2748 
2749       temp_str[0] = '\0';
2750 
2751       fill_pathname_expand_special(temp_str,
2752             g_defaults.path_config,
2753             sizeof(temp_str));
2754       path_set(RARCH_PATH_CONFIG, temp_str);
2755    }
2756 
2757    configuration_set_string(settings,
2758          settings->arrays.midi_input,
2759          DEFAULT_MIDI_INPUT);
2760    configuration_set_string(settings,
2761          settings->arrays.midi_output,
2762          DEFAULT_MIDI_OUTPUT);
2763 
2764 #ifdef HAVE_CONFIGFILE
2765    /* Avoid reloading config on every content load */
2766    if (DEFAULT_BLOCK_CONFIG_READ)
2767       rarch_ctl(RARCH_CTL_SET_BLOCK_CONFIG_READ, NULL);
2768    else
2769       rarch_ctl(RARCH_CTL_UNSET_BLOCK_CONFIG_READ, NULL);
2770 #endif
2771 
2772 #ifdef HAVE_MENU
2773    first_initialized = false;
2774 #endif
2775 }
2776 
2777 /**
2778  * config_load:
2779  *
2780  * Loads a config file and reads all the values into memory.
2781  *
2782  */
config_load(void * data)2783 void config_load(void *data)
2784 {
2785    global_t *global = (global_t*)data;
2786    config_set_defaults(global);
2787 #ifdef HAVE_CONFIGFILE
2788    config_parse_file(global);
2789 #endif
2790 }
2791 
2792 #ifdef HAVE_CONFIGFILE
2793 #if defined(HAVE_MENU) && defined(HAVE_RGUI)
check_menu_driver_compatibility(settings_t * settings)2794 static bool check_menu_driver_compatibility(settings_t *settings)
2795 {
2796    char *video_driver   = settings->arrays.video_driver;
2797    char *menu_driver    = settings->arrays.menu_driver;
2798 
2799    if (  string_is_equal(menu_driver,  "rgui") ||
2800          string_is_equal(menu_driver,  "null") ||
2801          string_is_equal(video_driver, "null"))
2802       return true;
2803 
2804    /* TODO/FIXME - maintenance hazard */
2805    if (string_starts_with_size(video_driver, "d3d", STRLEN_CONST("d3d")))
2806       if (
2807             string_is_equal(video_driver, "d3d9")   ||
2808             string_is_equal(video_driver, "d3d10")  ||
2809             string_is_equal(video_driver, "d3d11")  ||
2810             string_is_equal(video_driver, "d3d12")
2811          )
2812       return true;
2813    if (string_starts_with_size(video_driver, "gl", STRLEN_CONST("gl")))
2814       if (
2815             string_is_equal(video_driver, "gl")     ||
2816             string_is_equal(video_driver, "gl1")    ||
2817             string_is_equal(video_driver, "glcore")
2818          )
2819          return true;
2820    if (
2821          string_is_equal(video_driver, "caca")   ||
2822          string_is_equal(video_driver, "gdi")    ||
2823          string_is_equal(video_driver, "gx2")    ||
2824          string_is_equal(video_driver, "vulkan") ||
2825          string_is_equal(video_driver, "metal")  ||
2826          string_is_equal(video_driver, "ctr")    ||
2827          string_is_equal(video_driver, "vita2d")
2828       )
2829       return true;
2830 
2831    return false;
2832 }
2833 #endif
2834 
2835 /**
2836  * open_default_config_file
2837  *
2838  * Open a default config file. Platform-specific.
2839  *
2840  * Returns: handle to config file if found, otherwise NULL.
2841  **/
open_default_config_file(void)2842 static config_file_t *open_default_config_file(void)
2843 {
2844    char application_data[PATH_MAX_LENGTH];
2845    char conf_path[PATH_MAX_LENGTH];
2846    char app_path[PATH_MAX_LENGTH];
2847    bool has_application_data              = false;
2848    config_file_t *conf                    = NULL;
2849 
2850    application_data[0] = conf_path[0] = app_path[0] = '\0';
2851 
2852 #if defined(_WIN32) && !defined(_XBOX)
2853 #if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
2854    /* On UWP, the app install directory is not writable so use the writable LocalState dir instead */
2855    fill_pathname_home_dir(app_path, sizeof(app_path));
2856 #else
2857    fill_pathname_application_dir(app_path, sizeof(app_path));
2858 #endif
2859    fill_pathname_resolve_relative(conf_path, app_path,
2860          FILE_PATH_MAIN_CONFIG, sizeof(conf_path));
2861 
2862    conf = config_file_new_from_path_to_string(conf_path);
2863 
2864    if (!conf)
2865    {
2866       if (fill_pathname_application_data(application_data,
2867             sizeof(application_data)))
2868       {
2869          fill_pathname_join(conf_path, application_data,
2870                FILE_PATH_MAIN_CONFIG, sizeof(conf_path));
2871          conf = config_file_new_from_path_to_string(conf_path);
2872       }
2873    }
2874 
2875    if (!conf)
2876    {
2877       bool saved = false;
2878 
2879       /* Try to create a new config file. */
2880       conf = config_file_new_alloc();
2881 
2882       if (conf)
2883       {
2884          /* Since this is a clean config file, we can
2885           * safely use config_save_on_exit. */
2886          fill_pathname_resolve_relative(conf_path, app_path,
2887                FILE_PATH_MAIN_CONFIG, sizeof(conf_path));
2888          config_set_bool(conf, "config_save_on_exit", true);
2889          saved = config_file_write(conf, conf_path, true);
2890       }
2891 
2892       if (!saved)
2893       {
2894          /* WARN here to make sure user has a good chance of seeing it. */
2895          RARCH_ERR("[Config]: Failed to create new config file in: \"%s\".\n",
2896                conf_path);
2897          goto error;
2898       }
2899 
2900       RARCH_WARN("[Config]: Created new config file in: \"%s\".\n", conf_path);
2901    }
2902 #elif defined(OSX)
2903    if (!fill_pathname_application_data(application_data,
2904             sizeof(application_data)))
2905       goto error;
2906 
2907    /* Group config file with menu configs, remaps, etc: */
2908    strlcat(application_data, "/config", sizeof(application_data));
2909 
2910    path_mkdir(application_data);
2911 
2912    fill_pathname_join(conf_path, application_data,
2913          FILE_PATH_MAIN_CONFIG, sizeof(conf_path));
2914    conf = config_file_new_from_path_to_string(conf_path);
2915 
2916    if (!conf)
2917    {
2918       bool saved = false;
2919       conf       = config_file_new_alloc();
2920 
2921       if (conf)
2922       {
2923          config_set_bool(conf, "config_save_on_exit", true);
2924          saved = config_file_write(conf, conf_path, true);
2925       }
2926 
2927       if (!saved)
2928       {
2929          /* WARN here to make sure user has a good chance of seeing it. */
2930          RARCH_ERR("Failed to create new config file in: \"%s\".\n",
2931                conf_path);
2932          goto error;
2933       }
2934 
2935       RARCH_WARN("Created new config file in: \"%s\".\n", conf_path);
2936    }
2937 #elif !defined(RARCH_CONSOLE)
2938    has_application_data =
2939       fill_pathname_application_data(application_data,
2940             sizeof(application_data));
2941 
2942    if (has_application_data)
2943    {
2944       fill_pathname_join(conf_path, application_data,
2945             FILE_PATH_MAIN_CONFIG, sizeof(conf_path));
2946       RARCH_LOG("[Config]: Looking for config in: \"%s\".\n", conf_path);
2947       conf = config_file_new_from_path_to_string(conf_path);
2948    }
2949 
2950    /* Fallback to $HOME/.retroarch.cfg. */
2951    if (!conf && getenv("HOME"))
2952    {
2953       fill_pathname_join(conf_path, getenv("HOME"),
2954             "." FILE_PATH_MAIN_CONFIG, sizeof(conf_path));
2955       RARCH_LOG("[Config]: Looking for config in: \"%s\".\n", conf_path);
2956       conf = config_file_new_from_path_to_string(conf_path);
2957    }
2958 
2959    if (!conf && has_application_data)
2960    {
2961       bool dir_created = false;
2962       char basedir[PATH_MAX_LENGTH];
2963 
2964       basedir[0]       = '\0';
2965 
2966       /* Try to create a new config file. */
2967 
2968       fill_pathname_basedir(basedir, application_data, sizeof(basedir));
2969       fill_pathname_join(conf_path, application_data,
2970             FILE_PATH_MAIN_CONFIG, sizeof(conf_path));
2971 
2972       dir_created = path_mkdir(basedir);
2973 
2974       if (dir_created)
2975       {
2976          char skeleton_conf[PATH_MAX_LENGTH];
2977          bool saved          = false;
2978 
2979          skeleton_conf[0] = '\0';
2980 
2981          /* Build a retroarch.cfg path from the
2982           * global config directory (/etc). */
2983          fill_pathname_join(skeleton_conf, GLOBAL_CONFIG_DIR,
2984             FILE_PATH_MAIN_CONFIG, sizeof(skeleton_conf));
2985 
2986          conf = config_file_new_from_path_to_string(skeleton_conf);
2987          if (conf)
2988             RARCH_WARN("[Config]: Using skeleton config \"%s\" as base for a new config file.\n", skeleton_conf);
2989          else
2990             conf = config_file_new_alloc();
2991 
2992          if (conf)
2993          {
2994             /* Since this is a clean config file, we can
2995              * safely use config_save_on_exit. */
2996             config_set_bool(conf, "config_save_on_exit", true);
2997             saved = config_file_write(conf, conf_path, true);
2998          }
2999 
3000          if (!saved)
3001          {
3002             /* WARN here to make sure user has a good chance of seeing it. */
3003             RARCH_ERR("[Config]: Failed to create new config file in: \"%s\".\n",
3004                   conf_path);
3005             goto error;
3006          }
3007 
3008          RARCH_WARN("[Config]: Created new config file in: \"%s\".\n",
3009                conf_path);
3010       }
3011    }
3012 #endif
3013 
3014    if (!conf)
3015       goto error;
3016 
3017    path_set(RARCH_PATH_CONFIG, conf_path);
3018 
3019    return conf;
3020 
3021 error:
3022    if (conf)
3023       config_file_free(conf);
3024    return NULL;
3025 }
3026 
3027 #ifdef RARCH_CONSOLE
video_driver_load_settings(global_t * global,config_file_t * conf)3028 static void video_driver_load_settings(global_t *global,
3029       config_file_t *conf)
3030 {
3031    bool               tmp_bool = false;
3032 
3033    CONFIG_GET_INT_BASE(conf, global,
3034          console.screen.gamma_correction, "gamma_correction");
3035 
3036    if (config_get_bool(conf, "flicker_filter_enable",
3037          &tmp_bool))
3038       global->console.flickerfilter_enable = tmp_bool;
3039 
3040    if (config_get_bool(conf, "soft_filter_enable",
3041          &tmp_bool))
3042       global->console.softfilter_enable = tmp_bool;
3043 
3044    CONFIG_GET_INT_BASE(conf, global,
3045          console.screen.soft_filter_index,
3046          "soft_filter_index");
3047    CONFIG_GET_INT_BASE(conf, global,
3048          console.screen.resolutions.current.id,
3049          "current_resolution_id");
3050    CONFIG_GET_INT_BASE(conf, global,
3051          console.screen.flicker_filter_index,
3052          "flicker_filter_index");
3053 }
3054 #endif
3055 
3056 /**
3057  * config_load:
3058  * @path                : path to be read from.
3059  * @set_defaults        : set default values first before
3060  *                        reading the values from the config file
3061  *
3062  * Loads a config file and reads all the values into memory.
3063  *
3064  */
config_load_file(global_t * global,const char * path,settings_t * settings)3065 static bool config_load_file(global_t *global,
3066       const char *path, settings_t *settings)
3067 {
3068    unsigned i;
3069    char tmp_str[PATH_MAX_LENGTH];
3070    bool ret                                        = false;
3071    unsigned tmp_uint                               = 0;
3072    bool tmp_bool                                   = false;
3073    unsigned msg_color                              = 0;
3074    char *save                                      = NULL;
3075    char *override_username                         = NULL;
3076    const char *path_config                         = NULL;
3077    int bool_settings_size                          = sizeof(settings->bools)  / sizeof(settings->bools.placeholder);
3078    int float_settings_size                         = sizeof(settings->floats) / sizeof(settings->floats.placeholder);
3079    int int_settings_size                           = sizeof(settings->ints)   / sizeof(settings->ints.placeholder);
3080    int uint_settings_size                          = sizeof(settings->uints)  / sizeof(settings->uints.placeholder);
3081    int size_settings_size                          = sizeof(settings->sizes)  / sizeof(settings->sizes.placeholder);
3082    int array_settings_size                         = sizeof(settings->arrays) / sizeof(settings->arrays.placeholder);
3083    int path_settings_size                          = sizeof(settings->paths)  / sizeof(settings->paths.placeholder);
3084    struct config_bool_setting *bool_settings       = populate_settings_bool  (settings, &bool_settings_size);
3085    struct config_float_setting *float_settings     = populate_settings_float (settings, &float_settings_size);
3086    struct config_int_setting *int_settings         = populate_settings_int   (settings, &int_settings_size);
3087    struct config_uint_setting *uint_settings       = populate_settings_uint  (settings, &uint_settings_size);
3088    struct config_size_setting *size_settings       = populate_settings_size  (settings, &size_settings_size);
3089    struct config_array_setting *array_settings     = populate_settings_array (settings, &array_settings_size);
3090    struct config_path_setting *path_settings       = populate_settings_path  (settings, &path_settings_size);
3091    config_file_t *conf                             = path ? config_file_new_from_path_to_string(path) : open_default_config_file();
3092 
3093    tmp_str[0] = '\0';
3094 
3095    if (!conf)
3096    {
3097       if (!path)
3098          ret = true;
3099       goto end;
3100    }
3101 
3102    if (!path_is_empty(RARCH_PATH_CONFIG_APPEND))
3103    {
3104       /* Don't destroy append_config_path, store in temporary
3105        * variable. */
3106       char tmp_append_path[PATH_MAX_LENGTH];
3107       const char *extra_path = NULL;
3108 
3109       tmp_append_path[0] = '\0';
3110 
3111       strlcpy(tmp_append_path, path_get(RARCH_PATH_CONFIG_APPEND),
3112             sizeof(tmp_append_path));
3113       extra_path = strtok_r(tmp_append_path, "|", &save);
3114 
3115       while (extra_path)
3116       {
3117          bool result = config_append_file(conf, extra_path);
3118 
3119          RARCH_LOG("[Config]: Appending config \"%s\".\n", extra_path);
3120 
3121          if (!result)
3122             RARCH_ERR("[Config]: Failed to append config \"%s\".\n", extra_path);
3123          extra_path = strtok_r(NULL, "|", &save);
3124       }
3125    }
3126 
3127 #if 0
3128    if (verbosity_is_enabled())
3129    {
3130       RARCH_LOG_OUTPUT("=== Config ===\n");
3131       config_file_dump_all(conf);
3132       RARCH_LOG_OUTPUT("=== Config end ===\n");
3133    }
3134 #endif
3135 
3136    /* Overrides */
3137 
3138    if (rarch_ctl(RARCH_CTL_HAS_SET_USERNAME, NULL))
3139       override_username = strdup(settings->paths.username);
3140 
3141    /* Boolean settings */
3142 
3143    for (i = 0; i < (unsigned)bool_settings_size; i++)
3144    {
3145       bool tmp = false;
3146       if (config_get_bool(conf, bool_settings[i].ident, &tmp))
3147          *bool_settings[i].ptr = tmp;
3148    }
3149 
3150 #ifdef HAVE_NETWORKGAMEPAD
3151    for (i = 0; i < MAX_USERS; i++)
3152    {
3153       char tmp[64];
3154 
3155       tmp[0] = '\0';
3156 
3157       snprintf(tmp, sizeof(tmp), "network_remote_enable_user_p%u", i + 1);
3158 
3159       if (config_get_bool(conf, tmp, &tmp_bool))
3160          configuration_set_bool(settings,
3161                settings->bools.network_remote_enable_user[i], tmp_bool);
3162    }
3163 #endif
3164    if (config_get_bool(conf, "log_verbosity", &tmp_bool))
3165    {
3166       if (tmp_bool)
3167          verbosity_enable();
3168       else
3169          verbosity_disable();
3170    }
3171    if (config_get_uint(conf, "frontend_log_level", &tmp_uint))
3172    {
3173       verbosity_set_log_level(tmp_uint);
3174    }
3175 
3176    /* Integer settings */
3177 
3178    for (i = 0; i < (unsigned)int_settings_size; i++)
3179    {
3180       int tmp = 0;
3181       if (config_get_int(conf, int_settings[i].ident, &tmp))
3182          *int_settings[i].ptr = tmp;
3183    }
3184 
3185    for (i = 0; i < (unsigned)uint_settings_size; i++)
3186    {
3187       int tmp = 0;
3188       if (config_get_int(conf, uint_settings[i].ident, &tmp))
3189          *uint_settings[i].ptr = tmp;
3190    }
3191 
3192    for (i = 0; i < (unsigned)size_settings_size; i++)
3193    {
3194       size_t tmp = 0;
3195       if (config_get_size_t(conf, size_settings[i].ident, &tmp))
3196          *size_settings[i].ptr = tmp ;
3197       /* Special case for rewind_buffer_size - need to convert
3198        * low values to what they were
3199        * intended to be based on the default value in config.def.h
3200        * If the value is less than 10000 then multiple by 1MB because if
3201        * the retroarch.cfg
3202        * file contains rewind_buffer_size = "100",
3203        * then that ultimately gets interpreted as
3204        * 100MB, so ensure the internal values represent that.*/
3205       if (string_is_equal(size_settings[i].ident, "rewind_buffer_size"))
3206          if (*size_settings[i].ptr < 10000)
3207             *size_settings[i].ptr  = *size_settings[i].ptr * 1024 * 1024;
3208    }
3209 
3210    for (i = 0; i < MAX_USERS; i++)
3211    {
3212       char buf[64];
3213 
3214       buf[0] = '\0';
3215 
3216       snprintf(buf, sizeof(buf), "input_player%u_joypad_index", i + 1);
3217       CONFIG_GET_INT_BASE(conf, settings, uints.input_joypad_index[i], buf);
3218 
3219       snprintf(buf, sizeof(buf), "input_player%u_analog_dpad_mode", i + 1);
3220       CONFIG_GET_INT_BASE(conf, settings, uints.input_analog_dpad_mode[i], buf);
3221 
3222       snprintf(buf, sizeof(buf), "input_player%u_mouse_index", i + 1);
3223       CONFIG_GET_INT_BASE(conf, settings, uints.input_mouse_index[i], buf);
3224 
3225       snprintf(buf, sizeof(buf), "input_libretro_device_p%u", i + 1);
3226       CONFIG_GET_INT_BASE(conf, settings, uints.input_libretro_device[i], buf);
3227    }
3228 
3229    /* LED map for use by the led driver */
3230    for (i = 0; i < MAX_LEDS; i++)
3231    {
3232       char buf[64];
3233 
3234       buf[0] = '\0';
3235 
3236       snprintf(buf, sizeof(buf), "led%u_map", i + 1);
3237 
3238       /* TODO/FIXME - change of sign - led_map is unsigned */
3239       settings->uints.led_map[i] = -1;
3240 
3241       CONFIG_GET_INT_BASE(conf, settings, uints.led_map[i], buf);
3242    }
3243 
3244    /* Hexadecimal settings  */
3245 
3246    if (config_get_hex(conf, "video_message_color", &msg_color))
3247    {
3248       settings->floats.video_msg_color_r = ((msg_color >> 16) & 0xff) / 255.0f;
3249       settings->floats.video_msg_color_g = ((msg_color >>  8) & 0xff) / 255.0f;
3250       settings->floats.video_msg_color_b = ((msg_color >>  0) & 0xff) / 255.0f;
3251    }
3252 
3253    /* Float settings */
3254    for (i = 0; i < (unsigned)float_settings_size; i++)
3255    {
3256       float tmp = 0.0f;
3257       if (config_get_float(conf, float_settings[i].ident, &tmp))
3258          *float_settings[i].ptr = tmp;
3259    }
3260 
3261    /* Array settings  */
3262    for (i = 0; i < (unsigned)array_settings_size; i++)
3263    {
3264       if (!array_settings[i].handle)
3265          continue;
3266       config_get_array(conf, array_settings[i].ident,
3267             array_settings[i].ptr, PATH_MAX_LENGTH);
3268    }
3269 
3270    /* Path settings  */
3271    for (i = 0; i < (unsigned)path_settings_size; i++)
3272    {
3273       if (!path_settings[i].handle)
3274          continue;
3275       if (config_get_path(conf, path_settings[i].ident, tmp_str, sizeof(tmp_str)))
3276          strlcpy(path_settings[i].ptr, tmp_str, PATH_MAX_LENGTH);
3277    }
3278 
3279    if (config_get_path(conf, "libretro_directory", tmp_str, sizeof(tmp_str)))
3280       configuration_set_string(settings,
3281             settings->paths.directory_libretro, tmp_str);
3282 
3283 #ifdef RARCH_CONSOLE
3284    if (conf)
3285       video_driver_load_settings(global, conf);
3286 #endif
3287 
3288    /* Post-settings load */
3289 
3290    if (rarch_ctl(RARCH_CTL_HAS_SET_USERNAME, NULL) && override_username)
3291    {
3292       configuration_set_string(settings,
3293             settings->paths.username,
3294             override_username);
3295       free(override_username);
3296    }
3297 
3298    if (settings->uints.video_hard_sync_frames > 3)
3299       settings->uints.video_hard_sync_frames = 3;
3300 
3301    if (settings->uints.video_frame_delay > MAXIMUM_FRAME_DELAY)
3302       settings->uints.video_frame_delay = MAXIMUM_FRAME_DELAY;
3303 
3304    settings->uints.video_swap_interval = MAX(settings->uints.video_swap_interval, 1);
3305    settings->uints.video_swap_interval = MIN(settings->uints.video_swap_interval, 4);
3306 
3307    audio_set_float(AUDIO_ACTION_VOLUME_GAIN, settings->floats.audio_volume);
3308 #ifdef HAVE_AUDIOMIXER
3309    audio_set_float(AUDIO_ACTION_MIXER_VOLUME_GAIN, settings->floats.audio_mixer_volume);
3310 #endif
3311 
3312    path_config = path_get(RARCH_PATH_CONFIG);
3313 
3314    if (string_is_empty(settings->paths.path_content_favorites))
3315          strlcpy(settings->paths.directory_content_favorites, "default", sizeof(settings->paths.directory_content_favorites));
3316 
3317    if (string_is_empty(settings->paths.directory_content_favorites) || string_is_equal(settings->paths.directory_content_favorites, "default"))
3318          fill_pathname_resolve_relative(
3319                settings->paths.path_content_favorites,
3320                path_config,
3321                FILE_PATH_CONTENT_FAVORITES,
3322                sizeof(settings->paths.path_content_favorites));
3323    else
3324          fill_pathname_join(
3325                settings->paths.path_content_favorites,
3326                settings->paths.directory_content_favorites,
3327                FILE_PATH_CONTENT_FAVORITES,
3328                sizeof(settings->paths.path_content_favorites));
3329 
3330    if (string_is_empty(settings->paths.path_content_history))
3331          strlcpy(settings->paths.directory_content_history, "default", sizeof(settings->paths.directory_content_history));
3332 
3333    if (string_is_empty(settings->paths.directory_content_history) || string_is_equal(settings->paths.directory_content_history, "default"))
3334          fill_pathname_resolve_relative(
3335                settings->paths.path_content_history,
3336                path_config,
3337                FILE_PATH_CONTENT_HISTORY,
3338                sizeof(settings->paths.path_content_history));
3339    else
3340          fill_pathname_join(
3341                settings->paths.path_content_history,
3342                settings->paths.directory_content_history,
3343                FILE_PATH_CONTENT_HISTORY,
3344                sizeof(settings->paths.path_content_history));
3345 
3346    if (string_is_empty(settings->paths.path_content_image_history))
3347          strlcpy(settings->paths.directory_content_image_history, "default", sizeof(settings->paths.directory_content_image_history));
3348 
3349    if (string_is_empty(settings->paths.directory_content_image_history) || string_is_equal(settings->paths.directory_content_image_history, "default"))
3350          fill_pathname_resolve_relative(
3351                settings->paths.path_content_image_history,
3352                path_config,
3353                FILE_PATH_CONTENT_IMAGE_HISTORY,
3354                sizeof(settings->paths.path_content_image_history));
3355    else
3356          fill_pathname_join(
3357                settings->paths.path_content_image_history,
3358                settings->paths.directory_content_image_history,
3359                FILE_PATH_CONTENT_IMAGE_HISTORY,
3360                sizeof(settings->paths.path_content_image_history));
3361 
3362    if (string_is_empty(settings->paths.path_content_music_history))
3363          strlcpy(settings->paths.directory_content_music_history, "default", sizeof(settings->paths.directory_content_music_history));
3364 
3365    if (string_is_empty(settings->paths.directory_content_music_history) || string_is_equal(settings->paths.directory_content_music_history, "default"))
3366          fill_pathname_resolve_relative(
3367                settings->paths.path_content_music_history,
3368                path_config,
3369                FILE_PATH_CONTENT_MUSIC_HISTORY,
3370                sizeof(settings->paths.path_content_music_history));
3371    else
3372          fill_pathname_join(
3373                settings->paths.path_content_music_history,
3374                settings->paths.directory_content_music_history,
3375                FILE_PATH_CONTENT_MUSIC_HISTORY,
3376                sizeof(settings->paths.path_content_music_history));
3377 
3378    if (string_is_empty(settings->paths.path_content_video_history))
3379          strlcpy(settings->paths.directory_content_video_history, "default", sizeof(settings->paths.directory_content_video_history));
3380 
3381    if (string_is_empty(settings->paths.directory_content_video_history) || string_is_equal(settings->paths.directory_content_video_history, "default"))
3382          fill_pathname_resolve_relative(
3383                settings->paths.path_content_video_history,
3384                path_config,
3385                FILE_PATH_CONTENT_VIDEO_HISTORY,
3386                sizeof(settings->paths.path_content_video_history));
3387    else
3388          fill_pathname_join(
3389                settings->paths.path_content_video_history,
3390                settings->paths.directory_content_video_history,
3391                FILE_PATH_CONTENT_VIDEO_HISTORY,
3392                sizeof(settings->paths.path_content_video_history));
3393 
3394    if (!string_is_empty(settings->paths.directory_screenshot))
3395    {
3396       if (string_is_equal(settings->paths.directory_screenshot, "default"))
3397          *settings->paths.directory_screenshot = '\0';
3398       else if (!path_is_directory(settings->paths.directory_screenshot))
3399       {
3400          RARCH_WARN("[Config]: 'screenshot_directory' is not an existing directory, ignoring ...\n");
3401          *settings->paths.directory_screenshot = '\0';
3402       }
3403    }
3404 
3405 #if defined(__APPLE__) && defined(OSX)
3406 #if defined(__aarch64__)
3407    /* Wrong architecture, set it back to arm64 */
3408    if (string_is_equal(settings->paths.network_buildbot_url, "http://buildbot.libretro.com/nightly/apple/osx/x86_64/latest/"))
3409        configuration_set_string(settings,
3410              settings->paths.network_buildbot_url, DEFAULT_BUILDBOT_SERVER_URL);
3411 #elif defined(__x86_64__)
3412    /* Wrong architecture, set it back to x86_64 */
3413    if (string_is_equal(settings->paths.network_buildbot_url, "http://buildbot.libretro.com/nightly/apple/osx/arm64/latest/"))
3414        configuration_set_string(settings,
3415              settings->paths.network_buildbot_url, DEFAULT_BUILDBOT_SERVER_URL);
3416 #endif
3417 #endif
3418 
3419    if (string_is_equal(settings->paths.path_menu_wallpaper, "default"))
3420       *settings->paths.path_menu_wallpaper = '\0';
3421    if (string_is_equal(settings->paths.path_rgui_theme_preset, "default"))
3422       *settings->paths.path_rgui_theme_preset = '\0';
3423    if (string_is_equal(settings->paths.directory_video_shader, "default"))
3424       *settings->paths.directory_video_shader = '\0';
3425    if (string_is_equal(settings->paths.directory_video_filter, "default"))
3426       *settings->paths.directory_video_filter = '\0';
3427    if (string_is_equal(settings->paths.directory_audio_filter, "default"))
3428       *settings->paths.directory_audio_filter = '\0';
3429    if (string_is_equal(settings->paths.directory_core_assets, "default"))
3430       *settings->paths.directory_core_assets = '\0';
3431    if (string_is_equal(settings->paths.directory_assets, "default"))
3432       *settings->paths.directory_assets = '\0';
3433    if (string_is_equal(settings->paths.directory_dynamic_wallpapers, "default"))
3434       *settings->paths.directory_dynamic_wallpapers = '\0';
3435    if (string_is_equal(settings->paths.directory_thumbnails, "default"))
3436       *settings->paths.directory_thumbnails = '\0';
3437    if (string_is_equal(settings->paths.directory_playlist, "default"))
3438       *settings->paths.directory_playlist = '\0';
3439    if (string_is_equal(settings->paths.directory_content_favorites, "default"))
3440       *settings->paths.directory_content_favorites = '\0';
3441    if (string_is_equal(settings->paths.directory_content_history, "default"))
3442       *settings->paths.directory_content_history = '\0';
3443    if (string_is_equal(settings->paths.directory_content_image_history, "default"))
3444       *settings->paths.directory_content_image_history = '\0';
3445    if (string_is_equal(settings->paths.directory_content_music_history, "default"))
3446       *settings->paths.directory_content_music_history = '\0';
3447    if (string_is_equal(settings->paths.directory_content_video_history, "default"))
3448       *settings->paths.directory_content_video_history = '\0';
3449    if (string_is_equal(settings->paths.directory_runtime_log, "default"))
3450       *settings->paths.directory_runtime_log = '\0';
3451 #ifdef HAVE_MENU
3452    if (string_is_equal(settings->paths.directory_menu_content, "default"))
3453       *settings->paths.directory_menu_content = '\0';
3454    if (string_is_equal(settings->paths.directory_menu_config, "default"))
3455       *settings->paths.directory_menu_config = '\0';
3456 #endif
3457 #ifdef HAVE_OVERLAY
3458    if (string_is_equal(settings->paths.directory_overlay, "default"))
3459       *settings->paths.directory_overlay = '\0';
3460 #endif
3461 #ifdef HAVE_VIDEO_LAYOUT
3462    if (string_is_equal(settings->paths.directory_video_layout, "default"))
3463       *settings->paths.directory_video_layout = '\0';
3464 #endif
3465    if (string_is_equal(settings->paths.directory_system, "default"))
3466       *settings->paths.directory_system = '\0';
3467 
3468    /* Log directory is a special case, since it must contain
3469     * a valid path as soon as possible - if config file
3470     * value is 'default' must copy g_defaults.dirs[DEFAULT_DIR_LOGS]
3471     * directly... */
3472    if (string_is_equal(settings->paths.log_dir, "default"))
3473    {
3474       if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_LOGS]))
3475       {
3476          configuration_set_string(settings,
3477                settings->paths.log_dir,
3478                g_defaults.dirs[DEFAULT_DIR_LOGS]);
3479       }
3480       else
3481          *settings->paths.log_dir = '\0';
3482    }
3483 
3484    if (settings->floats.slowmotion_ratio < 1.0f)
3485       configuration_set_float(settings, settings->floats.slowmotion_ratio, 1.0f);
3486 
3487    /* Sanitize fastforward_ratio value - previously range was -1
3488     * and up (with 0 being skipped) */
3489    if (settings->floats.fastforward_ratio < 0.0f)
3490       configuration_set_float(settings, settings->floats.fastforward_ratio, 0.0f);
3491 
3492 #ifdef HAVE_LAKKA
3493    configuration_set_bool(settings,
3494          settings->bools.ssh_enable, filestream_exists(LAKKA_SSH_PATH));
3495    configuration_set_bool(settings,
3496          settings->bools.samba_enable, filestream_exists(LAKKA_SAMBA_PATH));
3497    configuration_set_bool(settings,
3498          settings->bools.bluetooth_enable, filestream_exists(LAKKA_BLUETOOTH_PATH));
3499 #endif
3500 
3501    if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL) &&
3502          config_get_path(conf, "savefile_directory", tmp_str, sizeof(tmp_str)))
3503    {
3504       if (string_is_equal(tmp_str, "default"))
3505          dir_set(RARCH_DIR_SAVEFILE, g_defaults.dirs[DEFAULT_DIR_SRAM]);
3506 
3507       else if (path_is_directory(tmp_str))
3508       {
3509          dir_set(RARCH_DIR_SAVEFILE, tmp_str);
3510 
3511          if (global)
3512          {
3513             strlcpy(global->name.savefile, tmp_str,
3514                   sizeof(global->name.savefile));
3515             fill_pathname_dir(global->name.savefile,
3516                   path_get(RARCH_PATH_BASENAME),
3517                   FILE_PATH_SRM_EXTENSION,
3518                   sizeof(global->name.savefile));
3519          }
3520       }
3521       else
3522          RARCH_WARN("[Config]: 'savefile_directory' is not a directory, ignoring ...\n");
3523    }
3524 
3525    if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL) &&
3526          config_get_path(conf, "savestate_directory", tmp_str, sizeof(tmp_str)))
3527    {
3528       if (string_is_equal(tmp_str, "default"))
3529          dir_set(RARCH_DIR_SAVESTATE, g_defaults.dirs[DEFAULT_DIR_SAVESTATE]);
3530       else if (path_is_directory(tmp_str))
3531       {
3532          dir_set(RARCH_DIR_SAVESTATE, tmp_str);
3533 
3534          if (global)
3535          {
3536             strlcpy(global->name.savestate, tmp_str,
3537                   sizeof(global->name.savestate));
3538             fill_pathname_dir(global->name.savestate,
3539                   path_get(RARCH_PATH_BASENAME),
3540                   ".state",
3541                   sizeof(global->name.savestate));
3542          }
3543       }
3544       else
3545          RARCH_WARN("[Config]: 'savestate_directory' is not a directory, ignoring ...\n");
3546    }
3547 
3548    config_read_keybinds_conf(conf);
3549 
3550 #if defined(HAVE_MENU) && defined(HAVE_RGUI)
3551    if (!check_menu_driver_compatibility(settings))
3552       configuration_set_string(settings,
3553             settings->arrays.menu_driver, "rgui");
3554 #endif
3555 
3556 #ifdef HAVE_LIBNX
3557    /* Apply initial clocks */
3558    extern void libnx_apply_overclock();
3559    libnx_apply_overclock();
3560 #endif
3561 
3562    frontend_driver_set_sustained_performance_mode(settings->bools.sustained_performance_mode);
3563    recording_driver_update_streaming_url();
3564 
3565    if (!config_entry_exists(conf, "user_language"))
3566       msg_hash_set_uint(MSG_HASH_USER_LANGUAGE, frontend_driver_get_user_language());
3567 
3568    /* If this is the first run of an existing installation
3569     * after the independent favourites playlist size limit was
3570     * added, set the favourites limit according to the current
3571     * history playlist size limit. (Have to do this, otherwise
3572     * users with large custom history size limits may lose
3573     * favourites entries when updating RetroArch...) */
3574    if ( config_entry_exists(conf, "content_history_size") &&
3575        !config_entry_exists(conf, "content_favorites_size"))
3576    {
3577       if (settings->uints.content_history_size > 999)
3578          settings->ints.content_favorites_size = -1;
3579       else
3580          settings->ints.content_favorites_size = (int)settings->uints.content_history_size;
3581    }
3582 
3583    ret = true;
3584 end:
3585    if (conf)
3586       config_file_free(conf);
3587    if (bool_settings)
3588       free(bool_settings);
3589    if (int_settings)
3590       free(int_settings);
3591    if (uint_settings)
3592       free(uint_settings);
3593    if (float_settings)
3594       free(float_settings);
3595    if (array_settings)
3596       free(array_settings);
3597    if (path_settings)
3598       free(path_settings);
3599    if (size_settings)
3600       free(size_settings);
3601    return ret;
3602 }
3603 
3604 /**
3605  * config_load_override:
3606  *
3607  * Tries to append game-specific and core-specific configuration.
3608  * These settings will always have precedence, thus this feature
3609  * can be used to enforce overrides.
3610  *
3611  * This function only has an effect if a game-specific or core-specific
3612  * configuration file exists at respective locations.
3613  *
3614  * core-specific: $CONFIG_DIR/$CORE_NAME/$CORE_NAME.cfg
3615  * fallback:      $CURRENT_CFG_LOCATION/$CORE_NAME/$CORE_NAME.cfg
3616  *
3617  * game-specific: $CONFIG_DIR/$CORE_NAME/$ROM_NAME.cfg
3618  * fallback:      $CURRENT_CFG_LOCATION/$CORE_NAME/$GAME_NAME.cfg
3619  *
3620  * Returns: false if there was an error or no action was performed.
3621  *
3622  */
config_load_override(void * data)3623 bool config_load_override(void *data)
3624 {
3625    char core_path[PATH_MAX_LENGTH];
3626    char game_path[PATH_MAX_LENGTH];
3627    char content_path[PATH_MAX_LENGTH];
3628    char content_dir_name[PATH_MAX_LENGTH];
3629    char config_directory[PATH_MAX_LENGTH];
3630    bool should_append                     = false;
3631    rarch_system_info_t *system            = (rarch_system_info_t*)data;
3632    const char *core_name                  = system ?
3633       system->info.library_name : NULL;
3634    const char *rarch_path_basename        = path_get(RARCH_PATH_BASENAME);
3635    const char *game_name                  = path_basename(rarch_path_basename);
3636    settings_t *settings                   = config_get_ptr();
3637 
3638    if (!string_is_empty(rarch_path_basename))
3639       fill_pathname_parent_dir_name(content_dir_name,
3640             rarch_path_basename, sizeof(content_dir_name));
3641 
3642    if (string_is_empty(core_name) || string_is_empty(game_name))
3643       return false;
3644 
3645    config_directory[0] = core_path[0] = game_path[0] = '\0';
3646 
3647    fill_pathname_application_special(config_directory, sizeof(config_directory),
3648          APPLICATION_SPECIAL_DIRECTORY_CONFIG);
3649 
3650    /* Concatenate strings into full paths for core_path, game_path,
3651     * content_path */
3652    fill_pathname_join_special_ext(game_path,
3653          config_directory, core_name,
3654          game_name,
3655          ".cfg",
3656          sizeof(game_path));
3657 
3658    fill_pathname_join_special_ext(content_path,
3659       config_directory, core_name,
3660       content_dir_name,
3661       ".cfg",
3662       sizeof(content_path));
3663 
3664    fill_pathname_join_special_ext(core_path,
3665          config_directory, core_name,
3666          core_name,
3667          ".cfg",
3668          sizeof(core_path));
3669 
3670    /* per-core overrides */
3671    /* Create a new config file from core_path */
3672    if (config_file_exists(core_path))
3673    {
3674       RARCH_LOG("[Overrides]: Core-specific overrides found at \"%s\".\n",
3675             core_path);
3676 
3677       path_set(RARCH_PATH_CONFIG_APPEND, core_path);
3678 
3679       should_append = true;
3680    }
3681    else
3682       RARCH_LOG("[Overrides]: No core-specific overrides found at \"%s\".\n",
3683             core_path);
3684 
3685    /* per-content-dir overrides */
3686    /* Create a new config file from content_path */
3687    if (config_file_exists(content_path))
3688    {
3689       char temp_path[PATH_MAX_LENGTH];
3690 
3691       RARCH_LOG("[Overrides]: Content dir-specific overrides found at \"%s\".\n",
3692             content_path);
3693 
3694       if (should_append)
3695       {
3696          RARCH_LOG("[Overrides]: Content dir-specific overrides stacking on top of previous overrides.\n");
3697          snprintf(temp_path, sizeof(temp_path),
3698                "%s|%s",
3699                path_get(RARCH_PATH_CONFIG_APPEND),
3700                content_path
3701                );
3702       }
3703       else
3704       {
3705          temp_path[0]    = '\0';
3706          strlcpy(temp_path, content_path, sizeof(temp_path));
3707       }
3708 
3709       path_set(RARCH_PATH_CONFIG_APPEND, temp_path);
3710 
3711       should_append = true;
3712    }
3713    else
3714       RARCH_LOG("[Overrides]: No content-dir-specific overrides found at \"%s\".\n",
3715          content_path);
3716 
3717    /* per-game overrides */
3718    /* Create a new config file from game_path */
3719    if (config_file_exists(game_path))
3720    {
3721       char temp_path[PATH_MAX_LENGTH];
3722 
3723       RARCH_LOG("[Overrides]: Game-specific overrides found at \"%s\".\n",
3724             game_path);
3725 
3726       if (should_append)
3727       {
3728          RARCH_LOG("[Overrides]: Game-specific overrides stacking on top of previous overrides.\n");
3729          snprintf(temp_path, sizeof(temp_path),
3730                "%s|%s",
3731                path_get(RARCH_PATH_CONFIG_APPEND),
3732                game_path
3733                );
3734       }
3735       else
3736       {
3737          temp_path[0]    = '\0';
3738          strlcpy(temp_path, game_path, sizeof(temp_path));
3739       }
3740 
3741       path_set(RARCH_PATH_CONFIG_APPEND, temp_path);
3742 
3743       should_append = true;
3744    }
3745    else
3746       RARCH_LOG("[Overrides]: No game-specific overrides found at \"%s\".\n",
3747             game_path);
3748 
3749    if (!should_append)
3750       return false;
3751 
3752    /* Re-load the configuration with any overrides
3753     * that might have been found */
3754 
3755    /* Toggle has_save_path to false so it resets */
3756    retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL);
3757    retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_SAVE_PATH,  NULL);
3758 
3759    if (!config_load_file(global_get_ptr(),
3760             path_get(RARCH_PATH_CONFIG), settings))
3761       return false;
3762 
3763    if (settings->bools.notification_show_config_override_load)
3764       runloop_msg_queue_push(msg_hash_to_str(MSG_CONFIG_OVERRIDE_LOADED),
3765             1, 100, false,
3766             NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3767 
3768    /* Reset save paths. */
3769    retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL);
3770    retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL);
3771 
3772    path_clear(RARCH_PATH_CONFIG_APPEND);
3773 
3774    return true;
3775 }
3776 
3777 /**
3778  * config_unload_override:
3779  *
3780  * Unloads configuration overrides if overrides are active.
3781  *
3782  *
3783  * Returns: false if there was an error.
3784  */
config_unload_override(void)3785 bool config_unload_override(void)
3786 {
3787    path_clear(RARCH_PATH_CONFIG_APPEND);
3788 
3789    /* Toggle has_save_path to false so it resets */
3790    retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL);
3791    retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_SAVE_PATH,  NULL);
3792 
3793    if (!config_load_file(global_get_ptr(),
3794             path_get(RARCH_PATH_CONFIG), config_get_ptr()))
3795       return false;
3796 
3797    RARCH_LOG("[Overrides]: Configuration overrides unloaded, original configuration restored.\n");
3798 
3799    /* Reset save paths */
3800    retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL);
3801    retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL);
3802 
3803    return true;
3804 }
3805 
3806 /**
3807  * config_load_remap:
3808  *
3809  * Tries to append game-specific and core-specific remap files.
3810  *
3811  * This function only has an effect if a game-specific or core-specific
3812  * configuration file exists at respective locations.
3813  *
3814  * core-specific: $REMAP_DIR/$CORE_NAME/$CORE_NAME.cfg
3815  * game-specific: $REMAP_DIR/$CORE_NAME/$GAME_NAME.cfg
3816  *
3817  * Returns: false if there was an error or no action was performed.
3818  */
config_load_remap(const char * directory_input_remapping,void * data)3819 bool config_load_remap(const char *directory_input_remapping,
3820       void *data)
3821 {
3822    char content_dir_name[PATH_MAX_LENGTH] = { 0 };
3823    /* path to the directory containing retroarch.cfg (prefix)    */
3824    char remap_directory[PATH_MAX_LENGTH];
3825    /* final path for core-specific configuration (prefix+suffix) */
3826    char core_path[PATH_MAX_LENGTH];
3827    /* final path for game-specific configuration (prefix+suffix) */
3828    char game_path[PATH_MAX_LENGTH];
3829    /* final path for content-dir-specific configuration (prefix+suffix) */
3830    char content_path[PATH_MAX_LENGTH];
3831    config_file_t *new_conf                = NULL;
3832    rarch_system_info_t *system            = (rarch_system_info_t*)data;
3833    const char *core_name                  = system ? system->info.library_name : NULL;
3834    const char *rarch_path_basename        = path_get(RARCH_PATH_BASENAME);
3835    const char *game_name                  = path_basename(rarch_path_basename);
3836    enum msg_hash_enums msg_remap_loaded   = MSG_GAME_REMAP_FILE_LOADED;
3837    settings_t *settings                   = config_get_ptr();
3838    bool notification_show_remap_load      = settings->bools.notification_show_remap_load;
3839 
3840    if (string_is_empty(core_name))
3841       return false;
3842 
3843    /* Remap directory: remap_directory.
3844     * Try remap directory setting, no fallbacks defined */
3845    if (string_is_empty(directory_input_remapping))
3846       return false;
3847 
3848    if (!string_is_empty(rarch_path_basename))
3849       fill_pathname_parent_dir_name(content_dir_name,
3850             rarch_path_basename, sizeof(content_dir_name));
3851 
3852    remap_directory[0] = core_path[0] = game_path[0] = '\0';
3853 
3854    strlcpy(remap_directory,
3855          directory_input_remapping, sizeof(remap_directory));
3856    RARCH_LOG("[Remaps]: Remap directory: \"%s\".\n", remap_directory);
3857 
3858    /* Concatenate strings into full paths for core_path, game_path */
3859    fill_pathname_join_special_ext(core_path,
3860          remap_directory, core_name,
3861          core_name,
3862          FILE_PATH_REMAP_EXTENSION,
3863          sizeof(core_path));
3864 
3865    fill_pathname_join_special_ext(content_path,
3866          remap_directory, core_name,
3867          content_dir_name,
3868          FILE_PATH_REMAP_EXTENSION,
3869          sizeof(content_path));
3870 
3871    fill_pathname_join_special_ext(game_path,
3872          remap_directory, core_name,
3873          game_name,
3874          FILE_PATH_REMAP_EXTENSION,
3875          sizeof(game_path));
3876 
3877    input_remapping_set_defaults(false);
3878 
3879    /* If a game remap file exists, load it. */
3880    if ((new_conf = config_file_new_from_path_to_string(game_path)))
3881    {
3882       bool ret = input_remapping_load_file(new_conf, game_path);
3883       config_file_free(new_conf);
3884       new_conf = NULL;
3885       RARCH_LOG("[Remaps]: Game-specific remap found at \"%s\".\n", game_path);
3886       if (ret)
3887       {
3888          rarch_ctl(RARCH_CTL_SET_REMAPS_GAME_ACTIVE, NULL);
3889          /* msg_remap_loaded is set to MSG_GAME_REMAP_FILE_LOADED
3890           * by default - no need to change it here */
3891          goto success;
3892       }
3893    }
3894 
3895    /* If a content-dir remap file exists, load it. */
3896    if ((new_conf = config_file_new_from_path_to_string(content_path)))
3897    {
3898       bool ret = input_remapping_load_file(new_conf, content_path);
3899       config_file_free(new_conf);
3900       new_conf = NULL;
3901       RARCH_LOG("[Remaps]: Content-dir-specific remap found at \"%s\".\n", content_path);
3902       if (ret)
3903       {
3904          rarch_ctl(RARCH_CTL_SET_REMAPS_CONTENT_DIR_ACTIVE, NULL);
3905          msg_remap_loaded = MSG_DIRECTORY_REMAP_FILE_LOADED;
3906          goto success;
3907       }
3908    }
3909 
3910    /* If a core remap file exists, load it. */
3911    if ((new_conf = config_file_new_from_path_to_string(core_path)))
3912    {
3913       bool ret = input_remapping_load_file(new_conf, core_path);
3914       config_file_free(new_conf);
3915       new_conf = NULL;
3916       RARCH_LOG("[Remaps]: Core-specific remap found at \"%s\".\n", core_path);
3917       if (ret)
3918       {
3919          rarch_ctl(RARCH_CTL_SET_REMAPS_CORE_ACTIVE, NULL);
3920          msg_remap_loaded = MSG_CORE_REMAP_FILE_LOADED;
3921          goto success;
3922       }
3923    }
3924 
3925    if (new_conf)
3926       config_file_free(new_conf);
3927    new_conf = NULL;
3928 
3929    return false;
3930 
3931 success:
3932    if (notification_show_remap_load)
3933       runloop_msg_queue_push(
3934             msg_hash_to_str(msg_remap_loaded), 1, 100, false,
3935             NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
3936    return true;
3937 }
3938 
3939 /**
3940  * config_parse_file:
3941  *
3942  * Loads a config file and reads all the values into memory.
3943  *
3944  */
config_parse_file(global_t * global)3945 static void config_parse_file(global_t *global)
3946 {
3947    if (path_is_empty(RARCH_PATH_CONFIG))
3948    {
3949       RARCH_LOG("[Config]: Loading default config.\n");
3950    }
3951 
3952    {
3953       const char *config_path = path_get(RARCH_PATH_CONFIG);
3954       RARCH_LOG("[Config]: Loading config from: \"%s\".\n", config_path);
3955 
3956       if (!config_load_file(global, config_path, config_get_ptr()))
3957       {
3958          RARCH_ERR("[Config]: Couldn't find config at path: \"%s\".\n",
3959                config_path);
3960       }
3961    }
3962 }
3963 
video_driver_save_settings(global_t * global,config_file_t * conf)3964 static void video_driver_save_settings(global_t *global, config_file_t *conf)
3965 {
3966    config_set_int(conf, "gamma_correction",
3967          global->console.screen.gamma_correction);
3968    config_set_bool(conf, "flicker_filter_enable",
3969          global->console.flickerfilter_enable);
3970    config_set_bool(conf, "soft_filter_enable",
3971          global->console.softfilter_enable);
3972 
3973    config_set_int(conf, "soft_filter_index",
3974          global->console.screen.soft_filter_index);
3975    config_set_int(conf, "current_resolution_id",
3976          global->console.screen.resolutions.current.id);
3977    config_set_int(conf, "flicker_filter_index",
3978          global->console.screen.flicker_filter_index);
3979 }
3980 
3981 /**
3982  * config_save_autoconf_profile:
3983  * @device_name       : Input device name
3984  * @user              : Controller number to save
3985  * Writes a controller autoconf file to disk.
3986  **/
config_save_autoconf_profile(const char * device_name,unsigned user)3987 bool config_save_autoconf_profile(const
3988       char *device_name, unsigned user)
3989 {
3990    static const char* invalid_filename_chars[] = {
3991       /* https://support.microsoft.com/en-us/help/905231/information-about-the-characters-that-you-cannot-use-in-site-names--fo */
3992       "~", "#", "%", "&", "*", "{", "}", "\\", ":", "[", "]", "?", "/", "|", "\'", "\"",
3993       NULL
3994    };
3995    unsigned i;
3996    char buf[PATH_MAX_LENGTH];
3997    char autoconf_file[PATH_MAX_LENGTH];
3998    config_file_t *conf                  = NULL;
3999    int32_t pid_user                     = 0;
4000    int32_t vid_user                     = 0;
4001    bool ret                             = false;
4002    settings_t *settings                 = config_get_ptr();
4003    const char *autoconf_dir             = settings->paths.directory_autoconfig;
4004    const char *joypad_driver_fallback   = settings->arrays.input_joypad_driver;
4005    const char *joypad_driver            = NULL;
4006    char *sanitised_name                 = NULL;
4007 
4008    buf[0]                               = '\0';
4009    autoconf_file[0]                     = '\0';
4010 
4011    if (string_is_empty(device_name))
4012       goto end;
4013 
4014    /* Get currently set joypad driver */
4015    joypad_driver = input_config_get_device_joypad_driver(user);
4016    if (string_is_empty(joypad_driver))
4017    {
4018       /* This cannot happen, but if we reach this
4019        * point without a driver being set for the
4020        * current input device then use the value
4021        * from the settings struct as a fallback */
4022       joypad_driver = joypad_driver_fallback;
4023 
4024       if (string_is_empty(joypad_driver))
4025          goto end;
4026    }
4027 
4028    sanitised_name = strdup(device_name);
4029 
4030    /* Remove invalid filename characters from
4031     * input device name */
4032    for (i = 0; invalid_filename_chars[i]; i++)
4033    {
4034       for (;;)
4035       {
4036          char *tmp = strstr(sanitised_name,
4037                invalid_filename_chars[i]);
4038 
4039          if (tmp)
4040             *tmp = '_';
4041          else
4042             break;
4043       }
4044    }
4045 
4046    /* Generate autoconfig file path */
4047    fill_pathname_join(buf, autoconf_dir, joypad_driver, sizeof(buf));
4048 
4049    if (path_is_directory(buf))
4050       fill_pathname_join_concat(autoconf_file, buf,
4051             sanitised_name, ".cfg", sizeof(autoconf_file));
4052    else
4053       fill_pathname_join_concat(autoconf_file, autoconf_dir,
4054             sanitised_name, ".cfg", sizeof(autoconf_file));
4055 
4056    /* Open config file */
4057    conf = config_file_new_from_path_to_string(autoconf_file);
4058 
4059    if (!conf)
4060    {
4061       conf = config_file_new_alloc();
4062 
4063       if (!conf)
4064          goto end;
4065    }
4066 
4067    /* Update config file */
4068    config_set_string(conf, "input_driver",
4069          joypad_driver);
4070    config_set_string(conf, "input_device",
4071          input_config_get_device_name(user));
4072 
4073    pid_user = input_config_get_device_pid(user);
4074    vid_user = input_config_get_device_vid(user);
4075 
4076    if (pid_user && vid_user)
4077    {
4078       config_set_int(conf, "input_vendor_id",
4079             vid_user);
4080       config_set_int(conf, "input_product_id",
4081             pid_user);
4082    }
4083 
4084    for (i = 0; i < RARCH_FIRST_META_KEY; i++)
4085    {
4086       const struct retro_keybind *bind = &input_config_binds[user][i];
4087       if (bind->valid)
4088          input_config_save_keybind(
4089                conf, "input", input_config_bind_map_get_base(i),
4090                bind, false);
4091    }
4092 
4093    ret = config_file_write(conf, autoconf_file, false);
4094 
4095 end:
4096    if (sanitised_name)
4097       free(sanitised_name);
4098 
4099    if (conf)
4100       config_file_free(conf);
4101 
4102    return ret;
4103 }
4104 
4105 /**
4106  * config_save_file:
4107  * @path            : Path that shall be written to.
4108  *
4109  * Writes a config file to disk.
4110  *
4111  * Returns: true (1) on success, otherwise returns false (0).
4112  **/
config_save_file(const char * path)4113 bool config_save_file(const char *path)
4114 {
4115    float msg_color;
4116    unsigned i                                        = 0;
4117    bool ret                                          = false;
4118    struct config_bool_setting     *bool_settings     = NULL;
4119    struct config_int_setting     *int_settings       = NULL;
4120    struct config_uint_setting     *uint_settings     = NULL;
4121    struct config_size_setting     *size_settings     = NULL;
4122    struct config_float_setting     *float_settings   = NULL;
4123    struct config_array_setting     *array_settings   = NULL;
4124    struct config_path_setting     *path_settings     = NULL;
4125    config_file_t                              *conf  = config_file_new_from_path_to_string(path);
4126    settings_t                              *settings = config_get_ptr();
4127    global_t *global                                  = global_get_ptr();
4128    int bool_settings_size                            = sizeof(settings->bools) / sizeof(settings->bools.placeholder);
4129    int float_settings_size                           = sizeof(settings->floats)/ sizeof(settings->floats.placeholder);
4130    int int_settings_size                             = sizeof(settings->ints)  / sizeof(settings->ints.placeholder);
4131    int uint_settings_size                            = sizeof(settings->uints) / sizeof(settings->uints.placeholder);
4132    int size_settings_size                            = sizeof(settings->sizes) / sizeof(settings->sizes.placeholder);
4133    int array_settings_size                           = sizeof(settings->arrays)/ sizeof(settings->arrays.placeholder);
4134    int path_settings_size                            = sizeof(settings->paths) / sizeof(settings->paths.placeholder);
4135 
4136    if (!conf)
4137       conf = config_file_new_alloc();
4138 
4139    if (!conf || rarch_ctl(RARCH_CTL_IS_OVERRIDES_ACTIVE, NULL))
4140    {
4141       if (conf)
4142          config_file_free(conf);
4143       return false;
4144    }
4145 
4146    bool_settings   = populate_settings_bool  (settings, &bool_settings_size);
4147    int_settings    = populate_settings_int   (settings, &int_settings_size);
4148    uint_settings   = populate_settings_uint  (settings, &uint_settings_size);
4149    size_settings   = populate_settings_size  (settings, &size_settings_size);
4150    float_settings  = populate_settings_float (settings, &float_settings_size);
4151    array_settings  = populate_settings_array (settings, &array_settings_size);
4152    path_settings   = populate_settings_path  (settings, &path_settings_size);
4153 
4154    /* Path settings */
4155    if (path_settings && (path_settings_size > 0))
4156    {
4157       for (i = 0; i < (unsigned)path_settings_size; i++)
4158       {
4159          const char *value = path_settings[i].ptr;
4160 
4161          if (path_settings[i].def_enable && string_is_empty(path_settings[i].ptr))
4162             value = "default";
4163 
4164          config_set_path(conf, path_settings[i].ident, value);
4165       }
4166 
4167       free(path_settings);
4168    }
4169 
4170 #ifdef HAVE_MENU
4171    config_set_path(conf, "xmb_font",
4172          !string_is_empty(settings->paths.path_menu_xmb_font)
4173          ? settings->paths.path_menu_xmb_font : "");
4174 #endif
4175 
4176    /* String settings  */
4177    if (array_settings && (array_settings_size > 0))
4178    {
4179       for (i = 0; i < (unsigned)array_settings_size; i++)
4180          if (!array_settings[i].override ||
4181              !retroarch_override_setting_is_set(array_settings[i].override, NULL))
4182             config_set_string(conf,
4183                   array_settings[i].ident,
4184                   array_settings[i].ptr);
4185 
4186       free(array_settings);
4187    }
4188 
4189    /* Float settings  */
4190    if (float_settings && (float_settings_size > 0))
4191    {
4192       for (i = 0; i < (unsigned)float_settings_size; i++)
4193          if (!float_settings[i].override ||
4194              !retroarch_override_setting_is_set(float_settings[i].override, NULL))
4195             config_set_float(conf,
4196                   float_settings[i].ident,
4197                   *float_settings[i].ptr);
4198 
4199       free(float_settings);
4200    }
4201 
4202    /* Integer settings */
4203    if (int_settings && (int_settings_size > 0))
4204    {
4205       for (i = 0; i < (unsigned)int_settings_size; i++)
4206          if (!int_settings[i].override ||
4207              !retroarch_override_setting_is_set(int_settings[i].override, NULL))
4208             config_set_int(conf,
4209                   int_settings[i].ident,
4210                   *int_settings[i].ptr);
4211 
4212       free(int_settings);
4213    }
4214 
4215    if (uint_settings && (uint_settings_size > 0))
4216    {
4217       for (i = 0; i < (unsigned)uint_settings_size; i++)
4218          if (!uint_settings[i].override ||
4219              !retroarch_override_setting_is_set(uint_settings[i].override, NULL))
4220             config_set_int(conf,
4221                   uint_settings[i].ident,
4222                   *uint_settings[i].ptr);
4223 
4224       free(uint_settings);
4225    }
4226 
4227    if (size_settings && (size_settings_size > 0))
4228    {
4229       for (i = 0; i < (unsigned)size_settings_size; i++)
4230          if (!size_settings[i].override ||
4231              !retroarch_override_setting_is_set(size_settings[i].override, NULL))
4232             config_set_int(conf,
4233                   size_settings[i].ident,
4234                   (int)*size_settings[i].ptr);
4235 
4236       free(size_settings);
4237    }
4238 
4239    for (i = 0; i < MAX_USERS; i++)
4240    {
4241       char cfg[64];
4242 
4243       cfg[0] = '\0';
4244 
4245       snprintf(cfg, sizeof(cfg), "input_device_p%u", i + 1);
4246       config_set_int(conf, cfg, settings->uints.input_device[i]);
4247       snprintf(cfg, sizeof(cfg), "input_player%u_joypad_index", i + 1);
4248       config_set_int(conf, cfg, settings->uints.input_joypad_index[i]);
4249       snprintf(cfg, sizeof(cfg), "input_libretro_device_p%u", i + 1);
4250       config_set_int(conf, cfg, input_config_get_device(i));
4251       snprintf(cfg, sizeof(cfg), "input_player%u_analog_dpad_mode", i + 1);
4252       config_set_int(conf, cfg, settings->uints.input_analog_dpad_mode[i]);
4253       snprintf(cfg, sizeof(cfg), "input_player%u_mouse_index", i + 1);
4254       config_set_int(conf, cfg, settings->uints.input_mouse_index[i]);
4255    }
4256 
4257    /* Boolean settings */
4258    if (bool_settings && (bool_settings_size > 0))
4259    {
4260       for (i = 0; i < (unsigned)bool_settings_size; i++)
4261          if (!bool_settings[i].override ||
4262              !retroarch_override_setting_is_set(bool_settings[i].override, NULL))
4263             config_set_bool(conf, bool_settings[i].ident,
4264                   *bool_settings[i].ptr);
4265 
4266       free(bool_settings);
4267    }
4268 
4269 #ifdef HAVE_NETWORKGAMEPAD
4270    for (i = 0; i < MAX_USERS; i++)
4271    {
4272       char tmp[64];
4273 
4274       tmp[0] = '\0';
4275 
4276       snprintf(tmp, sizeof(tmp), "network_remote_enable_user_p%u", i + 1);
4277       config_set_bool(conf, tmp, settings->bools.network_remote_enable_user[i]);
4278    }
4279 #endif
4280 
4281    /* Verbosity isn't in bool_settings since it needs to be loaded differently */
4282    if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_VERBOSITY, NULL))
4283       config_set_bool(conf, "log_verbosity",
4284             verbosity_is_enabled());
4285    config_set_bool(conf, "perfcnt_enable",
4286          rarch_ctl(RARCH_CTL_IS_PERFCNT_ENABLE, NULL));
4287 
4288    msg_color = (((int)(settings->floats.video_msg_color_r * 255.0f) & 0xff) << 16) +
4289                (((int)(settings->floats.video_msg_color_g * 255.0f) & 0xff) <<  8) +
4290                (((int)(settings->floats.video_msg_color_b * 255.0f) & 0xff));
4291 
4292    /* Hexadecimal settings */
4293    config_set_hex(conf, "video_message_color", msg_color);
4294 
4295    if (conf)
4296       video_driver_save_settings(global, conf);
4297 
4298 #ifdef HAVE_LAKKA
4299    if (settings->bools.ssh_enable)
4300       filestream_close(filestream_open(LAKKA_SSH_PATH,
4301                RETRO_VFS_FILE_ACCESS_WRITE,
4302                RETRO_VFS_FILE_ACCESS_HINT_NONE));
4303    else
4304       filestream_delete(LAKKA_SSH_PATH);
4305    if (settings->bools.samba_enable)
4306       filestream_close(filestream_open(LAKKA_SAMBA_PATH,
4307                RETRO_VFS_FILE_ACCESS_WRITE,
4308                RETRO_VFS_FILE_ACCESS_HINT_NONE));
4309    else
4310       filestream_delete(LAKKA_SAMBA_PATH);
4311    if (settings->bools.bluetooth_enable)
4312       filestream_close(filestream_open(LAKKA_BLUETOOTH_PATH,
4313                RETRO_VFS_FILE_ACCESS_WRITE,
4314                RETRO_VFS_FILE_ACCESS_HINT_NONE));
4315    else
4316       filestream_delete(LAKKA_BLUETOOTH_PATH);
4317 #endif
4318 
4319    for (i = 0; i < MAX_USERS; i++)
4320       input_config_save_keybinds_user(conf, i);
4321 
4322    ret = config_file_write(conf, path, true);
4323    config_file_free(conf);
4324 
4325    return ret;
4326 }
4327 
4328 /**
4329  * config_save_overrides:
4330  * @path            : Path that shall be written to.
4331  *
4332  * Writes a config file override to disk.
4333  *
4334  * Returns: true (1) on success, otherwise returns false (0).
4335  **/
config_save_overrides(enum override_type type,void * data)4336 bool config_save_overrides(enum override_type type, void *data)
4337 {
4338    int tmp_i                                   = 0;
4339    unsigned i                                  = 0;
4340    bool ret                                    = false;
4341    config_file_t *conf                         = NULL;
4342    settings_t *settings                        = NULL;
4343    struct config_bool_setting *bool_settings   = NULL;
4344    struct config_bool_setting *bool_overrides  = NULL;
4345    struct config_int_setting *int_settings     = NULL;
4346    struct config_uint_setting *uint_settings   = NULL;
4347    struct config_size_setting *size_settings   = NULL;
4348    struct config_int_setting *int_overrides    = NULL;
4349    struct config_uint_setting *uint_overrides  = NULL;
4350    struct config_size_setting *size_overrides  = NULL;
4351    struct config_float_setting *float_settings = NULL;
4352    struct config_float_setting *float_overrides= NULL;
4353    struct config_array_setting *array_settings = NULL;
4354    struct config_array_setting *array_overrides= NULL;
4355    struct config_path_setting *path_settings   = NULL;
4356    struct config_path_setting *path_overrides  = NULL;
4357    char config_directory[PATH_MAX_LENGTH];
4358    char override_directory[PATH_MAX_LENGTH];
4359    char core_path[PATH_MAX_LENGTH];
4360    char game_path[PATH_MAX_LENGTH];
4361    char content_path[PATH_MAX_LENGTH];
4362    settings_t *overrides                       = config_get_ptr();
4363    int bool_settings_size                      = sizeof(settings->bools)  / sizeof(settings->bools.placeholder);
4364    int float_settings_size                     = sizeof(settings->floats) / sizeof(settings->floats.placeholder);
4365    int int_settings_size                       = sizeof(settings->ints)   / sizeof(settings->ints.placeholder);
4366    int uint_settings_size                      = sizeof(settings->uints)  / sizeof(settings->uints.placeholder);
4367    int size_settings_size                      = sizeof(settings->sizes)  / sizeof(settings->sizes.placeholder);
4368    int array_settings_size                     = sizeof(settings->arrays) / sizeof(settings->arrays.placeholder);
4369    int path_settings_size                      = sizeof(settings->paths)  / sizeof(settings->paths.placeholder);
4370    rarch_system_info_t *system                 = (rarch_system_info_t*)data;
4371    const char *core_name                       = system ? system->info.library_name : NULL;
4372    const char *rarch_path_basename             = path_get(RARCH_PATH_BASENAME);
4373    const char *game_name                       = path_basename(rarch_path_basename);
4374    char content_dir_name[PATH_MAX_LENGTH];
4375 
4376    if (!string_is_empty(rarch_path_basename))
4377       fill_pathname_parent_dir_name(content_dir_name, rarch_path_basename, sizeof(content_dir_name));
4378 
4379    if (string_is_empty(core_name) || string_is_empty(game_name))
4380       return false;
4381 
4382    settings            = (settings_t*)calloc(1, sizeof(settings_t));
4383 
4384    config_directory[0] = override_directory[0] = core_path[0] =
4385           game_path[0] = '\0';
4386 
4387    fill_pathname_application_special(config_directory, sizeof(config_directory),
4388          APPLICATION_SPECIAL_DIRECTORY_CONFIG);
4389 
4390    fill_pathname_join(override_directory, config_directory, core_name,
4391       sizeof(override_directory));
4392 
4393    if (!path_is_directory(override_directory))
4394        path_mkdir(override_directory);
4395 
4396    /* Concatenate strings into full paths for core_path, game_path */
4397    fill_pathname_join_special_ext(game_path,
4398          config_directory, core_name,
4399          game_name,
4400          FILE_PATH_CONFIG_EXTENSION,
4401          sizeof(game_path));
4402 
4403    fill_pathname_join_special_ext(content_path,
4404          config_directory, core_name,
4405          content_dir_name,
4406          FILE_PATH_CONFIG_EXTENSION,
4407          sizeof(content_path));
4408 
4409    fill_pathname_join_special_ext(core_path,
4410          config_directory, core_name,
4411          core_name,
4412          FILE_PATH_CONFIG_EXTENSION,
4413          sizeof(core_path));
4414 
4415    if (!conf)
4416       conf = config_file_new_alloc();
4417 
4418    /* Load the original config file in memory */
4419    config_load_file(global_get_ptr(),
4420          path_get(RARCH_PATH_CONFIG), settings);
4421 
4422    bool_settings       = populate_settings_bool(settings,   &bool_settings_size);
4423    tmp_i               = sizeof(settings->bools) / sizeof(settings->bools.placeholder);
4424    bool_overrides      = populate_settings_bool(overrides,  &tmp_i);
4425 
4426    int_settings        = populate_settings_int(settings,    &int_settings_size);
4427    tmp_i               = sizeof(settings->ints) / sizeof(settings->ints.placeholder);
4428    int_overrides       = populate_settings_int (overrides,  &tmp_i);
4429 
4430    uint_settings       = populate_settings_uint(settings,    &uint_settings_size);
4431    tmp_i               = sizeof(settings->uints) / sizeof(settings->uints.placeholder);
4432    uint_overrides      = populate_settings_uint (overrides,  &tmp_i);
4433 
4434    size_settings       = populate_settings_size(settings,    &size_settings_size);
4435    tmp_i               = sizeof(settings->sizes) / sizeof(settings->sizes.placeholder);
4436    size_overrides      = populate_settings_size (overrides,  &tmp_i);
4437 
4438    float_settings      = populate_settings_float(settings,  &float_settings_size);
4439    tmp_i               = sizeof(settings->floats) / sizeof(settings->floats.placeholder);
4440    float_overrides     = populate_settings_float(overrides, &tmp_i);
4441 
4442    array_settings      = populate_settings_array(settings,  &array_settings_size);
4443    tmp_i               = sizeof(settings->arrays)   / sizeof(settings->arrays.placeholder);
4444    array_overrides     = populate_settings_array (overrides, &tmp_i);
4445 
4446    path_settings       = populate_settings_path(settings, &path_settings_size);
4447    tmp_i               = sizeof(settings->paths)   / sizeof(settings->paths.placeholder);
4448    path_overrides      = populate_settings_path (overrides, &tmp_i);
4449 
4450    RARCH_LOG("[Overrides]: Looking for changed settings... \n");
4451 
4452    if (conf)
4453    {
4454       for (i = 0; i < (unsigned)bool_settings_size; i++)
4455       {
4456          if ((*bool_settings[i].ptr) != (*bool_overrides[i].ptr))
4457             config_set_bool(conf, bool_overrides[i].ident,
4458                   (*bool_overrides[i].ptr));
4459       }
4460       for (i = 0; i < (unsigned)int_settings_size; i++)
4461       {
4462          if ((*int_settings[i].ptr) != (*int_overrides[i].ptr))
4463             config_set_int(conf, int_overrides[i].ident,
4464                   (*int_overrides[i].ptr));
4465       }
4466       for (i = 0; i < (unsigned)uint_settings_size; i++)
4467       {
4468          if ((*uint_settings[i].ptr) != (*uint_overrides[i].ptr))
4469             config_set_int(conf, uint_overrides[i].ident,
4470                   (*uint_overrides[i].ptr));
4471       }
4472       for (i = 0; i < (unsigned)size_settings_size; i++)
4473       {
4474          if ((*size_settings[i].ptr) != (*size_overrides[i].ptr))
4475             config_set_int(conf, size_overrides[i].ident,
4476                   (int)(*size_overrides[i].ptr));
4477       }
4478       for (i = 0; i < (unsigned)float_settings_size; i++)
4479       {
4480          if ((*float_settings[i].ptr) != (*float_overrides[i].ptr))
4481             config_set_float(conf, float_overrides[i].ident,
4482                   *float_overrides[i].ptr);
4483       }
4484 
4485       for (i = 0; i < (unsigned)array_settings_size; i++)
4486       {
4487          if (!string_is_equal(array_settings[i].ptr, array_overrides[i].ptr))
4488             config_set_string(conf, array_overrides[i].ident,
4489                   array_overrides[i].ptr);
4490       }
4491 
4492       for (i = 0; i < (unsigned)path_settings_size; i++)
4493       {
4494          if (!string_is_equal(path_settings[i].ptr, path_overrides[i].ptr))
4495             config_set_path(conf, path_overrides[i].ident,
4496                   path_overrides[i].ptr);
4497       }
4498 
4499       for (i = 0; i < MAX_USERS; i++)
4500       {
4501          char cfg[64];
4502 
4503          cfg[0] = '\0';
4504          if (settings->uints.input_device[i]
4505                != overrides->uints.input_device[i])
4506          {
4507             snprintf(cfg, sizeof(cfg), "input_device_p%u", i + 1);
4508             config_set_int(conf, cfg, overrides->uints.input_device[i]);
4509          }
4510 
4511          if (settings->uints.input_joypad_index[i]
4512                != overrides->uints.input_joypad_index[i])
4513          {
4514             snprintf(cfg, sizeof(cfg), "input_player%u_joypad_index", i + 1);
4515             config_set_int(conf, cfg, overrides->uints.input_joypad_index[i]);
4516          }
4517       }
4518 
4519       ret = false;
4520 
4521       switch (type)
4522       {
4523          case OVERRIDE_CORE:
4524             RARCH_LOG ("[Overrides]: Path \"%s\".\n", core_path);
4525             ret = config_file_write(conf, core_path, true);
4526             break;
4527          case OVERRIDE_GAME:
4528             RARCH_LOG ("[Overrides]: Path \"%s\".\n", game_path);
4529             ret = config_file_write(conf, game_path, true);
4530             break;
4531          case OVERRIDE_CONTENT_DIR:
4532             RARCH_LOG ("[Overrides]: Path \"%s\".\n", content_path);
4533             ret = config_file_write(conf, content_path, true);
4534             break;
4535          case OVERRIDE_NONE:
4536          default:
4537             break;
4538       }
4539 
4540       config_file_free(conf);
4541    }
4542 
4543    if (bool_settings)
4544       free(bool_settings);
4545    if (bool_overrides)
4546       free(bool_overrides);
4547    if (int_settings)
4548       free(int_settings);
4549    if (uint_settings)
4550       free(uint_settings);
4551    if (size_settings)
4552       free(size_settings);
4553    if (int_overrides)
4554       free(int_overrides);
4555    if (uint_overrides)
4556       free(uint_overrides);
4557    if (float_settings)
4558       free(float_settings);
4559    if (float_overrides)
4560       free(float_overrides);
4561    if (array_settings)
4562       free(array_settings);
4563    if (array_overrides)
4564       free(array_overrides);
4565    if (path_settings)
4566       free(path_settings);
4567    if (path_overrides)
4568       free(path_overrides);
4569    if (size_overrides)
4570       free(size_overrides);
4571    free(settings);
4572 
4573    return ret;
4574 }
4575 
4576 /* Replaces currently loaded configuration file with
4577  * another one. Will load a dummy core to flush state
4578  * properly. */
config_replace(bool config_replace_save_on_exit,char * path)4579 bool config_replace(bool config_replace_save_on_exit, char *path)
4580 {
4581    content_ctx_info_t content_info = {0};
4582    const char *rarch_path_config   = path_get(RARCH_PATH_CONFIG);
4583 
4584    /* If config file to be replaced is the same as the
4585     * current config file, exit. */
4586    if (string_is_equal(path, rarch_path_config))
4587       return false;
4588 
4589    if (config_replace_save_on_exit && !path_is_empty(RARCH_PATH_CONFIG))
4590       config_save_file(rarch_path_config);
4591 
4592    path_set(RARCH_PATH_CONFIG, path);
4593 
4594    rarch_ctl(RARCH_CTL_UNSET_BLOCK_CONFIG_READ, NULL);
4595 
4596    /* Load core in new (salamander) config. */
4597    path_clear(RARCH_PATH_CORE);
4598 
4599    return task_push_start_dummy_core(&content_info);
4600 }
4601 
4602 /**
4603  * input_remapping_load_file:
4604  * @data                     : Path to config file.
4605  *
4606  * Loads a remap file from disk to memory.
4607  *
4608  * Returns: true (1) if successful, otherwise false (0).
4609  **/
input_remapping_load_file(void * data,const char * path)4610 bool input_remapping_load_file(void *data, const char *path)
4611 {
4612    unsigned i, j;
4613    config_file_t *conf                              = (config_file_t*)data;
4614    settings_t *settings                             = config_get_ptr();
4615    global_t *global                                 = global_get_ptr();
4616    char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][8] = {
4617       "b", "y", "select", "start",
4618       "up", "down", "left", "right",
4619       "a", "x", "l", "r", "l2", "r2",
4620       "l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" };
4621 
4622    if (!conf || string_is_empty(path))
4623       return false;
4624 
4625    if (!string_is_empty(global->name.remapfile))
4626    {
4627       input_remapping_deinit();
4628       input_remapping_set_defaults(false);
4629    }
4630    global->name.remapfile = strdup(path);
4631 
4632    for (i = 0; i < MAX_USERS; i++)
4633    {
4634       char s1[32], s2[32], s3[32];
4635 
4636       s1[0] = '\0';
4637       s2[0] = '\0';
4638       s3[0] = '\0';
4639 
4640       snprintf(s1, sizeof(s1), "input_player%u_btn", i + 1);
4641       snprintf(s2, sizeof(s2), "input_player%u_key", i + 1);
4642       snprintf(s3, sizeof(s3), "input_player%u_stk", i + 1);
4643 
4644       for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 8; j++)
4645       {
4646          const char *key_string = key_strings[j];
4647 
4648          if (j < RARCH_FIRST_CUSTOM_BIND)
4649          {
4650             int btn_remap = -1;
4651             int key_remap = -1;
4652             char btn_ident[128];
4653             char key_ident[128];
4654 
4655             btn_ident[0] = key_ident[0] = '\0';
4656 
4657             fill_pathname_join_delim(btn_ident, s1,
4658                   key_string, '_', sizeof(btn_ident));
4659             fill_pathname_join_delim(key_ident, s2,
4660                   key_string, '_', sizeof(key_ident));
4661 
4662             if (config_get_int(conf, btn_ident, &btn_remap))
4663             {
4664                if (btn_remap == -1)
4665                   btn_remap = RARCH_UNMAPPED;
4666 
4667                configuration_set_uint(settings,
4668                      settings->uints.input_remap_ids[i][j], btn_remap);
4669             }
4670 
4671             if (!config_get_int(conf, key_ident, &key_remap))
4672                key_remap = RETROK_UNKNOWN;
4673 
4674             configuration_set_uint(settings,
4675                   settings->uints.input_keymapper_ids[i][j], key_remap);
4676          }
4677          else
4678          {
4679             char stk_ident[128];
4680             char key_ident[128];
4681             int stk_remap = -1;
4682             int key_remap = -1;
4683 
4684             stk_ident[0]  = '\0';
4685             key_ident[0]  = '\0';
4686 
4687             fill_pathname_join_delim(stk_ident, s3,
4688                   key_string, '$', sizeof(stk_ident));
4689 
4690             snprintf(stk_ident,
4691                   sizeof(stk_ident),
4692                   "%s_%s",
4693                   s3,
4694                   key_string);
4695 
4696             if (config_get_int(conf, stk_ident, &stk_remap))
4697             {
4698                if (stk_remap == -1)
4699                   stk_remap = RARCH_UNMAPPED;
4700 
4701                configuration_set_uint(settings,
4702                      settings->uints.input_remap_ids[i][j], stk_remap);
4703             }
4704 
4705             fill_pathname_join_delim(key_ident, s2,
4706                   key_string, '_', sizeof(key_ident));
4707 
4708             if (!config_get_int(conf, key_ident, &key_remap))
4709                key_remap = RETROK_UNKNOWN;
4710 
4711             configuration_set_uint(settings,
4712                   settings->uints.input_keymapper_ids[i][j], key_remap);
4713          }
4714       }
4715 
4716       snprintf(s1, sizeof(s1), "input_player%u_analog_dpad_mode", i + 1);
4717       CONFIG_GET_INT_BASE(conf, settings, uints.input_analog_dpad_mode[i], s1);
4718 
4719       snprintf(s1, sizeof(s1), "input_libretro_device_p%u", i + 1);
4720       CONFIG_GET_INT_BASE(conf, settings, uints.input_libretro_device[i], s1);
4721 
4722       snprintf(s1, sizeof(s1), "input_remap_port_p%u", i + 1);
4723       CONFIG_GET_INT_BASE(conf, settings, uints.input_remap_ports[i], s1);
4724    }
4725 
4726    input_remapping_update_port_map();
4727 
4728    /* Whenever a remap file is loaded, subsequent
4729     * changes to global remap-related parameters
4730     * must be reset at the next core deinitialisation */
4731    input_remapping_enable_global_config_restore();
4732 
4733    return true;
4734 }
4735 
4736 /**
4737  * input_remapping_save_file:
4738  * @path                     : Path to remapping file (relative path).
4739  *
4740  * Saves remapping values to file.
4741  *
4742  * Returns: true (1) if successful, otherwise false (0).
4743  **/
input_remapping_save_file(const char * path)4744 bool input_remapping_save_file(const char *path)
4745 {
4746    bool ret;
4747    unsigned i, j;
4748    char remap_file[PATH_MAX_LENGTH];
4749    char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][8] = {
4750       "b", "y", "select", "start",
4751       "up", "down", "left", "right",
4752       "a", "x", "l", "r", "l2", "r2",
4753       "l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" };
4754    config_file_t               *conf = NULL;
4755    unsigned max_users                = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS));
4756    settings_t              *settings = config_get_ptr();
4757    const char *dir_input_remapping   = settings->paths.directory_input_remapping;
4758 
4759    remap_file[0]                     = '\0';
4760 
4761    fill_pathname_join_concat(remap_file, dir_input_remapping, path,
4762          FILE_PATH_REMAP_EXTENSION,
4763          sizeof(remap_file));
4764 
4765    if (!(conf = config_file_new_from_path_to_string(remap_file)))
4766    {
4767       if (!(conf = config_file_new_alloc()))
4768          return false;
4769    }
4770 
4771    for (i = 0; i < MAX_USERS; i++)
4772    {
4773       bool skip_port = true;
4774       char s1[32];
4775       char s2[32];
4776       char s3[32];
4777 
4778       s1[0] = '\0';
4779       s2[0] = '\0';
4780       s3[0] = '\0';
4781 
4782       /* We must include all mapped ports + all those
4783        * with an index less than max_users */
4784       if (i < max_users)
4785          skip_port = false;
4786       else
4787       {
4788          /* Check whether current port is mapped
4789           * to an input device */
4790          for (j = 0; j < max_users; j++)
4791          {
4792             if (i == settings->uints.input_remap_ports[j])
4793             {
4794                skip_port = false;
4795                break;
4796             }
4797          }
4798       }
4799 
4800       if (skip_port)
4801          continue;
4802 
4803       snprintf(s1, sizeof(s1), "input_player%u_btn", i + 1);
4804       snprintf(s2, sizeof(s2), "input_player%u_key", i + 1);
4805       snprintf(s3, sizeof(s3), "input_player%u_stk", i + 1);
4806 
4807       for (j = 0; j < RARCH_FIRST_CUSTOM_BIND; j++)
4808       {
4809          char btn_ident[128];
4810          unsigned remap_id      = settings->uints.input_remap_ids[i][j];
4811          unsigned keymap_id     = settings->uints.input_keymapper_ids[i][j];
4812          const char *key_string = key_strings[j];
4813          btn_ident[0]           = '\0';
4814          fill_pathname_join_delim(btn_ident, s1,
4815                key_string, '_', sizeof(btn_ident));
4816 
4817          /* only save values that have been modified */
4818          if (remap_id == j)
4819             config_unset(conf, btn_ident);
4820          else
4821          {
4822             if (remap_id == RARCH_UNMAPPED)
4823                config_set_int(conf, btn_ident, -1);
4824             else
4825                config_set_int(conf, btn_ident,
4826                      settings->uints.input_remap_ids[i][j]);
4827          }
4828 
4829          if (keymap_id != RETROK_UNKNOWN)
4830          {
4831             char key_ident[128];
4832             key_ident[0] = '\0';
4833             fill_pathname_join_delim(key_ident, s2,
4834                   key_string, '_', sizeof(key_ident));
4835             config_set_int(conf, key_ident,
4836                   settings->uints.input_keymapper_ids[i][j]);
4837          }
4838       }
4839 
4840       for (j = RARCH_FIRST_CUSTOM_BIND; j < (RARCH_FIRST_CUSTOM_BIND + 8); j++)
4841       {
4842          char stk_ident[128];
4843          unsigned remap_id      = settings->uints.input_remap_ids[i][j];
4844          unsigned keymap_id     = settings->uints.input_keymapper_ids[i][j];
4845          const char *key_string = key_strings[j];
4846          stk_ident[0]           = '\0';
4847          fill_pathname_join_delim(stk_ident, s3,
4848                key_string, '_', sizeof(stk_ident));
4849 
4850          if (remap_id == j)
4851             config_unset(conf, stk_ident);
4852          else
4853          {
4854             if (remap_id == RARCH_UNMAPPED)
4855                config_set_int(conf, stk_ident,
4856                      -1);
4857             else
4858                config_set_int(conf, stk_ident,
4859                      settings->uints.input_remap_ids[i][j]);
4860          }
4861 
4862          if (keymap_id != RETROK_UNKNOWN)
4863          {
4864             char key_ident[128];
4865             key_ident[0] = '\0';
4866             fill_pathname_join_delim(key_ident, s2,
4867                   key_string, '_', sizeof(key_ident));
4868             config_set_int(conf, key_ident,
4869                   settings->uints.input_keymapper_ids[i][j]);
4870          }
4871       }
4872 
4873       snprintf(s1, sizeof(s1), "input_libretro_device_p%u", i + 1);
4874       config_set_int(conf, s1, input_config_get_device(i));
4875 
4876       snprintf(s1, sizeof(s1), "input_player%u_analog_dpad_mode", i + 1);
4877       config_set_int(conf, s1, settings->uints.input_analog_dpad_mode[i]);
4878 
4879       snprintf(s1, sizeof(s1), "input_remap_port_p%u", i + 1);
4880       config_set_int(conf, s1, settings->uints.input_remap_ports[i]);
4881    }
4882 
4883    ret = config_file_write(conf, remap_file, true);
4884    config_file_free(conf);
4885 
4886    return ret;
4887 }
4888 
input_remapping_remove_file(const char * path,const char * dir_input_remapping)4889 bool input_remapping_remove_file(const char *path,
4890       const char *dir_input_remapping)
4891 {
4892    char remap_file[PATH_MAX_LENGTH];
4893    remap_file[0]  = '\0';
4894    fill_pathname_join_concat(remap_file, dir_input_remapping, path,
4895          FILE_PATH_REMAP_EXTENSION,
4896          sizeof(remap_file));
4897    return filestream_delete(remap_file) == 0 ? true : false;
4898 }
4899 #endif
4900 
4901 #if !defined(HAVE_DYNAMIC)
4902 /* Salamander config file contains a single
4903  * entry (libretro_path), which is linked to
4904  * RARCH_PATH_CORE
4905  * > Used to select which core to load
4906  *   when launching a salamander build */
4907 
config_file_salamander_get_path(char * s,size_t len)4908 static bool config_file_salamander_get_path(char *s, size_t len)
4909 {
4910    const char *rarch_config_path = g_defaults.path_config;
4911 
4912    if (!string_is_empty(rarch_config_path))
4913       fill_pathname_resolve_relative(s,
4914             rarch_config_path,
4915             FILE_PATH_SALAMANDER_CONFIG,
4916             len);
4917    else
4918       strcpy_literal(s, FILE_PATH_SALAMANDER_CONFIG);
4919 
4920    return !string_is_empty(s);
4921 }
4922 
config_load_file_salamander(void)4923 void config_load_file_salamander(void)
4924 {
4925    config_file_t *config = NULL;
4926    char config_path[PATH_MAX_LENGTH];
4927    char libretro_path[PATH_MAX_LENGTH];
4928 
4929    config_path[0]   = '\0';
4930    libretro_path[0] = '\0';
4931 
4932    /* Get config file path */
4933    if (!config_file_salamander_get_path(
4934          config_path, sizeof(config_path)))
4935       return;
4936 
4937    /* Open config file */
4938    config = config_file_new_from_path_to_string(config_path);
4939 
4940    if (!config)
4941       return;
4942 
4943    /* Read 'libretro_path' value and update
4944     * RARCH_PATH_CORE */
4945    RARCH_LOG("[Config]: Loading salamander config from: \"%s\".\n",
4946          config_path);
4947 
4948    if (config_get_path(config, "libretro_path",
4949          libretro_path, sizeof(libretro_path)) &&
4950        !string_is_empty(libretro_path) &&
4951        !string_is_equal(libretro_path, "builtin"))
4952       path_set(RARCH_PATH_CORE, libretro_path);
4953 
4954    config_file_free(config);
4955 }
4956 
config_save_file_salamander(void)4957 void config_save_file_salamander(void)
4958 {
4959    config_file_t *config     = NULL;
4960    const char *libretro_path = path_get(RARCH_PATH_CORE);
4961    bool success              = false;
4962    char config_path[PATH_MAX_LENGTH];
4963 
4964    config_path[0] = '\0';
4965 
4966    if (string_is_empty(libretro_path) ||
4967        string_is_equal(libretro_path, "builtin"))
4968       return;
4969 
4970    /* Get config file path */
4971    if (!config_file_salamander_get_path(
4972          config_path, sizeof(config_path)))
4973       return;
4974 
4975    /* Open config file */
4976    config = config_file_new_from_path_to_string(config_path);
4977 
4978    if (!config)
4979       config = config_file_new_alloc();
4980 
4981    if (!config)
4982       goto end;
4983 
4984    /* Update config file */
4985    config_set_path(config, "libretro_path", libretro_path);
4986 
4987    /* Save config file
4988     * > Only one entry - no need to sort */
4989    success = config_file_write(config, config_path, false);
4990 
4991 end:
4992    if (success)
4993       RARCH_LOG("[Config]: Saving salamander config to: \"%s\".\n",
4994             config_path);
4995    else
4996       RARCH_ERR("[Config]: Failed to create new salamander config file in: \"%s\".\n",
4997             config_path);
4998 
4999    if (config)
5000       config_file_free(config);
5001 }
5002 #endif
5003