ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
libretro-core-options.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef LIBRETRO_CORE_OPTIONS_H__
23 #define LIBRETRO_CORE_OPTIONS_H__
24 
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include <libretro.h>
29 #include <retro_inline.h>
30 
31 #ifndef HAVE_NO_LANGEXTRA
32 #include "libretro-core-options-intl.h"
33 #endif
34 
35 /*
36  ********************************
37  * VERSION: 2.0
38  ********************************
39  *
40  * - 2.0: Add support for core options v2 interface
41  * - 1.3: Move translations to libretro_core_options_intl.h
42  * - libretro_core_options_intl.h includes BOM and utf-8
43  * fix for MSVC 2010-2013
44  * - Added HAVE_NO_LANGEXTRA flag to disable translations
45  * on platforms/compilers without BOM support
46  * - 1.2: Use core options v1 interface when
47  * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1
48  * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1)
49  * - 1.1: Support generation of core options v0 retro_core_option_value
50  * arrays containing options with a single value
51  * - 1.0: First commit
52  */
53 
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 /*
59  ********************************
60  * Core Option Definitions
61  ********************************
62  */
63 
64 /* RETRO_LANGUAGE_ENGLISH */
65 
66 /* Default language:
67  * - All other languages must include the same keys and values
68  * - Will be used as a fallback in the event that frontend language
69  * is not available
70  * - Will be used as a fallback for any missing entries in
71  * frontend language definition */
72 
73 
74 struct retro_core_option_v2_category option_cats_us[] = {
75  {
76  "video",
77  "Video settings",
78  "Configure video settings"
79  },
80  {
81  "cursor",
82  "Cursor Movement",
83  "Configure cursor movement settings"
84  },
85  {
86  "timing",
87  "Timing",
88  "Configure timing settings"
89  },
90  {
91  "retropad",
92  "RetroPad mapping",
93  "Configure RetroPad mapping"
94  },
95  { NULL, NULL, NULL },
96 };
97 
98 struct retro_core_option_v2_definition option_defs_us[] = {
99  {
100  "scummvm_gamepad_cursor_only",
101  "Cursor > Exclusive cursor control with RetroPad",
102  "Exclusive cursor control with RetroPad",
103  "Allows the use of RetroPad only to control mouse cursor, excluding the other inputs (e.g. physical mouse, touch screen).",
104  NULL,
105  "cursor",
106  {
107  {"disabled", NULL},
108  {"enabled", NULL},
109  {NULL, NULL},
110  },
111  "disabled"
112  },
113  {
114  "scummvm_gamepad_cursor_speed",
115  "Cursor > Gamepad Cursor Speed",
116  "Gamepad Cursor Speed",
117  "Sets the mouse cursor speed multiplier when moving the cursor with the RetroPad left analog stick or D-Pad. The default value of '1.0' is optimised for games that have a native resolution of '320x200' or '320x240'. When running 'high definition' games with a resolution of '640x400' or '640x480', a Gamepad Cursor Speed of '2.0' is recommended.",
118  NULL,
119  "cursor",
120  {
121  {"0.25", NULL},
122  {"0.5", NULL},
123  {"0.75", NULL},
124  {"1.0", NULL},
125  {"1.5", NULL},
126  {"2.0", NULL},
127  {"2.5", NULL},
128  {"3.0", NULL},
129  {NULL, NULL},
130  },
131  "1.0"
132  },
133  {
134  "scummvm_gamepad_cursor_acceleration_time",
135  "Cursor > Gamepad Cursor Acceleration",
136  "Gamepad Cursor Acceleration",
137  "The amount of time (In seconds) it takes for the cursor to reach full speed",
138  NULL,
139  "cursor",
140  {
141  {"off", NULL},
142  {"0.1", NULL},
143  {"0.2", NULL},
144  {"0.3", NULL},
145  {"0.4", NULL},
146  {"0.5", NULL},
147  {"0.6", NULL},
148  {"0.7", NULL},
149  {"0.8", NULL},
150  {"0.9", NULL},
151  {"1.0", NULL},
152  {NULL, NULL},
153  },
154  "0.2"
155  },
156  {
157  "scummvm_analog_response",
158  "Cursor > Analog Cursor Response",
159  "Analog Cursor Response",
160  "Determines how the speed of the cursor varies when tilting the RetroPad left analog stick. 'Linear': Speed is directly proportional to analog stick displacement. This is standard behaviour with which most users will be familiar. 'Quadratic': Speed increases quadratically with analog stick displacement. This allows for greater precision when making small movements without sacrificing maximum speed at full analog range. This mode may require practice for effective use.",
161  NULL,
162  "cursor",
163  {
164  {"linear", "Linear"},
165  {"quadratic", "Quadratic"},
166  {NULL, NULL},
167  },
168  "linear"
169  },
170  {
171  "scummvm_analog_deadzone",
172  "Cursor > Analog Deadzone",
173  "Analog Deadzone",
174  "Sets the deadzone in percentage of the RetroPad analog sticks. Used to eliminate cursor drift/unwanted input.",
175  NULL,
176  "cursor",
177  {
178  {"0", "0 %"},
179  {"5", "5 %"},
180  {"10", "10 %"},
181  {"15", "15 %"},
182  {"20", "20 %"},
183  {"25", "25 %"},
184  {"30", "30 %"},
185  {NULL, NULL},
186  },
187  "15"
188  },
189  {
190  "scummvm_mouse_speed",
191  "Cursor > Mouse Speed",
192  "Mouse Speed",
193  "Sets the mouse cursor speed multiplier when moving the cursor with the RetroMouse.",
194  NULL,
195  "cursor",
196  {
197  {"0.05", NULL},
198  {"0.1", NULL},
199  {"0.15", NULL},
200  {"0.2", NULL},
201  {"0.25", NULL},
202  {"0.3", NULL},
203  {"0.35", NULL},
204  {"0.4", NULL},
205  {"0.45", NULL},
206  {"0.5", NULL},
207  {"0.6", NULL},
208  {"0.7", NULL},
209  {"0.8", NULL},
210  {"0.9", NULL},
211  {"1.0", NULL},
212  {"1.25", NULL},
213  {"1.5", NULL},
214  {"1.75", NULL},
215  {"2.0", NULL},
216  {"2.5", NULL},
217  {"3.0", NULL},
218  {NULL, NULL},
219  },
220  "1.0"
221  },
222  {
223  "scummvm_mouse_fine_control_speed_reduction",
224  "Cursor > Mouse Fine Control Speed Reduction",
225  "Mouse Fine Control Speed Reduction",
226  "Sets the mouse cursor speed reduction as percentage of normal speed when fine control is activated.",
227  NULL,
228  "cursor",
229  {
230  {"2", "50 %"},
231  {"4", "20 %"},
232  {"10", "10 %"},
233  {NULL, NULL},
234  },
235  "4"
236  },
237  {
238  "scummvm_framerate",
239  "Timing > Frame rate cap",
240  "Frame rate cap",
241  "Set core frame rate upper limit. Reducing the limit will improve the performance on lower end devices. Changing this setting will reset the core.",
242  NULL,
243  "timing",
244  {
245  { "disabled", NULL },
246  { "60 Hz", NULL },
247  { "50 Hz", NULL },
248  { "30 Hz", NULL },
249  { "25 Hz", NULL },
250  { NULL, NULL },
251  },
252  "disabled"
253  },
254  {
255  "scummvm_samplerate",
256  "Timing > Sample rate",
257  "Sample rate",
258  "Set core sample rate. Reducing the rate will slightly improve the performance on lower end devices. Changing this setting will reset the core.",
259  NULL,
260  "timing",
261  {
262  { "48000 Hz", NULL },
263  { "44100 Hz", NULL },
264  { NULL, NULL },
265  },
266  "48000 Hz"
267  },
268  /* Button mappings */
269  {
270  "scummvm_mapper_up",
271  "RetroPad > Up",
272  "Up",
273  NULL,
274  NULL,
275  "retropad",
276  {
277  { NULL, NULL }
278  },
279  "RETROKE_UP"
280  },
281  {
282  "scummvm_mapper_down",
283  "RetroPad > Down",
284  "Down",
285  NULL,
286  NULL,
287  "retropad",
288  {
289  { NULL, NULL }
290  },
291  "RETROKE_DOWN"
292  },
293  {
294  "scummvm_mapper_left",
295  "RetroPad > Left",
296  "Left",
297  NULL,
298  NULL,
299  "retropad",
300  {
301  { NULL, NULL }
302  },
303  "RETROKE_LEFT"
304  },
305  {
306  "scummvm_mapper_right",
307  "RetroPad > Right",
308  "Right",
309  NULL,
310  NULL,
311  "retropad",
312  {
313  { NULL, NULL }
314  },
315  "RETROKE_RIGHT"
316  },
317  {
318  "scummvm_mapper_a",
319  "RetroPad > A",
320  "A",
321  NULL,
322  NULL,
323  "retropad",
324  {
325  { NULL, NULL }
326  },
327  "RETROK_SPACE"
328  },
329  {
330  "scummvm_mapper_b",
331  "RetroPad > B",
332  "B",
333  NULL,
334  NULL,
335  "retropad",
336  {
337  { NULL, NULL }
338  },
339  "RETROK_RETURN"
340  },
341  {
342  "scummvm_mapper_x",
343  "RetroPad > X",
344  "X",
345  NULL,
346  NULL,
347  "retropad",
348  {
349  { NULL, NULL }
350  },
351  "RETROK_F5"
352  },
353  {
354  "scummvm_mapper_y",
355  "RetroPad > Y",
356  "Y",
357  NULL,
358  NULL,
359  "retropad",
360  {
361  { NULL, NULL }
362  },
363  "RETROK_ESCAPE"
364  },
365  {
366  "scummvm_mapper_select",
367  "RetroPad > Select",
368  "Select",
369  NULL,
370  NULL,
371  "retropad",
372  {
373  { NULL, NULL }
374  },
375  "RETROKE_VKBD"
376  },
377  {
378  "scummvm_mapper_start",
379  "RetroPad > Start",
380  "Start",
381  NULL,
382  NULL,
383  "retropad",
384  {
385  { NULL, NULL }
386  },
387  "RETROKE_SCUMMVM_GUI"
388  },
389  {
390  "scummvm_mapper_l",
391  "RetroPad > L",
392  "L",
393  NULL,
394  NULL,
395  "retropad",
396  {
397  { NULL, NULL }
398  },
399  "RETROKE_LEFT_BUTTON"
400  },
401  {
402  "scummvm_mapper_r",
403  "RetroPad > R",
404  "R",
405  NULL,
406  NULL,
407  "retropad",
408  {
409  { NULL, NULL }
410  },
411  "RETROKE_RIGHT_BUTTON"
412  },
413  {
414  "scummvm_mapper_l2",
415  "RetroPad > L2",
416  "L2",
417  NULL,
418  NULL,
419  "retropad",
420  {
421  { NULL, NULL }
422  },
423  "---"
424  },
425  {
426  "scummvm_mapper_r2",
427  "RetroPad > R2",
428  "R2",
429  NULL,
430  NULL,
431  "retropad",
432  {
433  { NULL, NULL }
434  },
435  "RETROKE_FINE_CONTROL"
436  },
437  {
438  "scummvm_mapper_l3",
439  "RetroPad > L3",
440  "L3",
441  NULL,
442  NULL,
443  "retropad",
444  {
445  { NULL, NULL }
446  },
447  "---"
448  },
449  {
450  "scummvm_mapper_r3",
451  "RetroPad > R3",
452  "R3",
453  NULL,
454  NULL,
455  "retropad",
456  {
457  { NULL, NULL }
458  },
459  "---"
460  },
461  /* Left Stick */
462  {
463  "scummvm_mapper_lu",
464  "RetroPad > Left Analog > Up",
465  "Left Analog > Up",
466  NULL,
467  NULL,
468  "retropad",
469  {
470  { NULL, NULL }
471  },
472  "RETROKE_UP"
473  },
474  {
475  "scummvm_mapper_ld",
476  "RetroPad > Left Analog > Down",
477  "Left Analog > Down",
478  NULL,
479  NULL,
480  "retropad",
481  {
482  { NULL, NULL }
483  },
484  "RETROKE_DOWN"
485  },
486  {
487  "scummvm_mapper_ll",
488  "RetroPad > Left Analog > Left",
489  "Left Analog > Left",
490  NULL,
491  NULL,
492  "retropad",
493  {
494  { NULL, NULL }
495  },
496  "RETROKE_LEFT"
497  },
498  {
499  "scummvm_mapper_lr",
500  "RetroPad > Left Analog > Right",
501  "Left Analog > Right",
502  NULL,
503  NULL,
504  "retropad",
505  {
506  { NULL, NULL }
507  },
508  "RETROKE_RIGHT"
509  },
510  /* Right Stick */
511  {
512  "scummvm_mapper_ru",
513  "RetroPad > Right Analog > Up",
514  "Right Analog > Up",
515  NULL,
516  NULL,
517  "retropad",
518  {
519  { NULL, NULL }
520  },
521  "RETROK_UP"
522  },
523  {
524  "scummvm_mapper_rd",
525  "RetroPad > Right Analog > Down",
526  "Right Analog > Down",
527  NULL,
528  NULL,
529  "retropad",
530  {
531  { NULL, NULL }
532  },
533  "RETROK_DOWN"
534  },
535  {
536  "scummvm_mapper_rl",
537  "RetroPad > Right Analog > Left",
538  "Right Analog > Left",
539  NULL,
540  NULL,
541  "retropad",
542  {
543  { NULL, NULL }
544  },
545  "RETROK_LEFT"
546  },
547  {
548  "scummvm_mapper_rr",
549  "RetroPad > Right Analog > Right",
550  "Right Analog > Right",
551  NULL,
552  NULL,
553  "retropad",
554  {
555  { NULL, NULL }
556  },
557  "RETROK_RIGHT"
558  },
559  {
560  "scummvm_video_hw_acceleration",
561  "Video > Hardware acceleration",
562  "Hardware acceleration",
563  "Request video hardware acceleration (OpenGL or OpenGLES2) to the frontend if supported. It is needed to reload the core to apply this setting.",
564  NULL,
565  "video",
566  {
567  {"disabled", NULL},
568 #ifdef USE_OPENGL
569  {"enabled", NULL},
570 #endif
571  {NULL, NULL},
572  },
573 #ifdef USE_OPENGL
574  "enabled"
575 #else
576  "disabled"
577 #endif
578  },
579 #ifdef USE_HIGHRES
580  {
581  "scummvm_gui_aspect_ratio",
582  "Video > GUI aspect ratio",
583  "ScummVM Launcher aspect ratio",
584  "Set ScummVM Launcher aspect ratio.",
585  NULL,
586  "video",
587  {
588  {"0", "4:3"},
589  {"1", "16:9"},
590  {NULL, NULL},
591  },
592  "1"
593  },
594  {
595  "scummvm_gui_h_res",
596  "Video > GUI resolution",
597  "ScummVM Launcher resolution",
598  "Set ScummVM Launcher resolution.",
599  NULL,
600  "video",
601  {
602  {"240", "LD"},
603  {"480", "SD"},
604  {"720", "HD"},
605  {"1080", "FHD"},
606  {NULL, NULL},
607  },
608  "720"
609  },
610 #endif
611  { NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },
612 };
613 
614 struct retro_core_options_v2 options_us = {
615  option_cats_us,
616  option_defs_us
617 };
618 
619 /* List has been reduced to fit RETRO_NUM_CORE_OPTION_VALUES_MAX.
620  * Latest element {NULL, NULL} has been omitted in this case as the array is exactly sized
621  * RETRO_NUM_CORE_OPTION_VALUES_MAX; in case the array size will be reduced, {NULL, NULL}
622  * element to be uncommented.
623  */
624 
625 struct retro_core_option_value retro_keys_label_us [] = {
626  {"---", "---"},
627  {"RETROKE_VKBD", "Toggle Virtual Keyboard"},
628  {"RETROKE_LEFT", "Mouse Cursor Left"},
629  {"RETROKE_UP", "Mouse Cursor Up"},
630  {"RETROKE_DOWN", "Mouse Cursor Down"},
631  {"RETROKE_RIGHT", "Mouse Cursor Right"},
632  {"RETROKE_LEFT_BUTTON", "Mouse Left Button"},
633  {"RETROKE_RIGHT_BUTTON", "Mouse Right Button"},
634  {"RETROKE_FINE_CONTROL", "Mouse Cursor Fine Control"},
635  {"RETROKE_SCUMMVM_GUI", "ScummVM GUI"},
636  {"RETROKE_SHIFT_MOD", "Keyboard Shift (Modifier)"},
637  {"RETROKE_CTRL_MOD", "Keyboard Control (Modifier)"},
638  {"RETROKE_ALT_MOD", "Keyboard Alt (Modifier)"},
639  {"RETROK_BACKSPACE", "Keyboard Backspace"},
640  {"RETROK_TAB", "Keyboard Tab"},
641  {"RETROK_CLEAR", "Keyboard Clear"},
642  {"RETROK_RETURN", "Keyboard Return"},
643  {"RETROK_PAUSE", "Keyboard Pause"},
644  {"RETROK_ESCAPE", "Keyboard Escape"},
645  {"RETROK_SPACE", "Keyboard Space"},
646  {"RETROK_EXCLAIM", "Keyboard !"},
647  {"RETROK_QUOTEDBL", "Keyboard \""},
648  {"RETROK_HASH", "Keyboard #"},
649  {"RETROK_DOLLAR", "Keyboard $"},
650  {"RETROK_AMPERSAND", "Keyboard &"},
651  {"RETROK_QUOTE", "Keyboard \'"},
652  {"RETROK_LEFTPAREN", "Keyboard ("},
653  {"RETROK_RIGHTPAREN", "Keyboard )"},
654  {"RETROK_ASTERISK", "Keyboard *"},
655  {"RETROK_PLUS", "Keyboard +"},
656  {"RETROK_COMMA", "Keyboard ,"},
657  {"RETROK_MINUS", "Keyboard -"},
658  {"RETROK_PERIOD", "Keyboard ."},
659  {"RETROK_SLASH", "Keyboard /"},
660  {"RETROK_0", "Keyboard 0"},
661  {"RETROK_1", "Keyboard 1"},
662  {"RETROK_2", "Keyboard 2"},
663  {"RETROK_3", "Keyboard 3"},
664  {"RETROK_4", "Keyboard 4"},
665  {"RETROK_5", "Keyboard 5"},
666  {"RETROK_6", "Keyboard 6"},
667  {"RETROK_7", "Keyboard 7"},
668  {"RETROK_8", "Keyboard 8"},
669  {"RETROK_9", "Keyboard 9"},
670  {"RETROK_COLON", "Keyboard :"},
671  {"RETROK_SEMICOLON", "Keyboard ;"},
672  {"RETROK_LESS", "Keyboard <"},
673  {"RETROK_EQUALS", "Keyboard ="},
674  {"RETROK_GREATER", "Keyboard >"},
675  {"RETROK_QUESTION", "Keyboard ?"},
676  {"RETROK_AT", "Keyboard @"},
677  {"RETROK_LEFTBRACKET", "Keyboard ["},
678  {"RETROK_BACKSLASH", "Keyboard \\"},
679  {"RETROK_RIGHTBRACKET", "Keyboard ]"},
680  {"RETROK_CARET", "Keyboard ^"},
681  {"RETROK_UNDERSCORE", "Keyboard _"},
682  {"RETROK_BACKQUOTE", "Keyboard `"},
683  {"RETROK_a", "Keyboard a"},
684  {"RETROK_b", "Keyboard b"},
685  {"RETROK_c", "Keyboard c"},
686  {"RETROK_d", "Keyboard d"},
687  {"RETROK_e", "Keyboard e"},
688  {"RETROK_f", "Keyboard f"},
689  {"RETROK_g", "Keyboard g"},
690  {"RETROK_h", "Keyboard h"},
691  {"RETROK_i", "Keyboard i"},
692  {"RETROK_j", "Keyboard j"},
693  {"RETROK_k", "Keyboard k"},
694  {"RETROK_l", "Keyboard l"},
695  {"RETROK_m", "Keyboard m"},
696  {"RETROK_n", "Keyboard n"},
697  {"RETROK_o", "Keyboard o"},
698  {"RETROK_p", "Keyboard p"},
699  {"RETROK_q", "Keyboard q"},
700  {"RETROK_r", "Keyboard r"},
701  {"RETROK_s", "Keyboard s"},
702  {"RETROK_t", "Keyboard t"},
703  {"RETROK_u", "Keyboard u"},
704  {"RETROK_v", "Keyboard v"},
705  {"RETROK_w", "Keyboard w"},
706  {"RETROK_x", "Keyboard x"},
707  {"RETROK_y", "Keyboard y"},
708  {"RETROK_z", "Keyboard z"},
709  {"RETROK_KP0", "Keyboard Numpad 0"},
710  {"RETROK_KP1", "Keyboard Numpad 1"},
711  {"RETROK_KP2", "Keyboard Numpad 2"},
712  {"RETROK_KP3", "Keyboard Numpad 3"},
713  {"RETROK_KP4", "Keyboard Numpad 4"},
714  {"RETROK_KP5", "Keyboard Numpad 5"},
715  {"RETROK_KP6", "Keyboard Numpad 6"},
716  {"RETROK_KP7", "Keyboard Numpad 7"},
717  {"RETROK_KP8", "Keyboard Numpad 8"},
718  {"RETROK_KP9", "Keyboard Numpad 9"},
719  {"RETROK_KP_PERIOD", "Keyboard Numpad ."},
720  {"RETROK_KP_DIVIDE", "Keyboard Numpad /"},
721  {"RETROK_KP_MULTIPLY", "Keyboard Numpad *"},
722  {"RETROK_KP_MINUS", "Keyboard Numpad -"},
723  {"RETROK_KP_PLUS", "Keyboard Numpad +"},
724  {"RETROK_KP_ENTER", "Keyboard Numpad Enter"},
725  {"RETROK_KP_EQUALS", "Keyboard Numpad ="},
726  {"RETROK_UP", "Keyboard Up"},
727  {"RETROK_DOWN", "Keyboard Down"},
728  {"RETROK_LEFT", "Keyboard Left"},
729  {"RETROK_RIGHT", "Keyboard Right"},
730  {"RETROK_INSERT", "Keyboard Insert"},
731  {"RETROK_DELETE", "Keyboard Delete"},
732  {"RETROK_HOME", "Keyboard Home"},
733  {"RETROK_END", "Keyboard End"},
734  {"RETROK_PAGEUP", "Keyboard PageUp"},
735  {"RETROK_PAGEDOWN", "Keyboard PageDown"},
736  {"RETROK_F1", "Keyboard F1"},
737  {"RETROK_F2", "Keyboard F2"},
738  {"RETROK_F3", "Keyboard F3"},
739  {"RETROK_F4", "Keyboard F4"},
740  {"RETROK_F5", "Keyboard F5"},
741  {"RETROK_F6", "Keyboard F6"},
742  {"RETROK_F7", "Keyboard F7"},
743  {"RETROK_F8", "Keyboard F8"},
744  {"RETROK_F9", "Keyboard F9"},
745  {"RETROK_F10", "Keyboard F10"},
746  {"RETROK_F11", "Keyboard F11"},
747  {"RETROK_F12", "Keyboard F12"},
748 //{"RETROK_F13","Keyboard F13"},
749 //{"RETROK_F14","Keyboard F14"},
750 //{"RETROK_F15","Keyboard F15"},
751 //{"RETROK_NUMLOCK","Keyboard NumLock"},
752 //{"RETROK_CAPSLOCK","Keyboard Caps Lock"},
753 //{"RETROK_SCROLLOCK","Keyboard Scroll Lock"},
754  {"RETROK_LSHIFT", "Keyboard Left Shift"},
755  {"RETROK_RSHIFT", "Keyboard Right Shift"},
756  {"RETROK_LCTRL", "Keyboard Left Control"},
757  {"RETROK_RCTRL", "Keyboard Right Control"},
758  {"RETROK_LALT", "Keyboard Left Alt"},
759  {"RETROK_RALT", "Keyboard Right Alt"},
760 //{"RETROK_LMETA","Keyboard Left Meta"},
761 //{"RETROK_RMETA","Keyboard Right Meta"},
762 //{"RETROK_LSUPER","Keyboard Left Super"},
763 //{"RETROK_RSUPER","Keyboard Right Super"},
764 //{"RETROK_MODE","Keyboard Mode"},
765 //{"RETROK_COMPOSE","Keyboard Compose"},
766 //{"RETROK_HELP","Keyboard Help"},
767 //{"RETROK_PRINT","Keyboard Print"},
768 //{"RETROK_SYSREQ","Keyboard SysReq"},
769 //{"RETROK_BREAK","Keyboard Break"},
770 //{"RETROK_MENU","Keyboard Menu"},
771 //{"RETROK_POWER","Keyboard Power"},
772 //{"RETROK_EURO","Keyboard Euro"},
773 //{"RETROK_UNDO","Keyboard Undo"},
774 //{NULL, NULL}
775 };
776 
777 /*
778  ********************************
779  * Language Mapping
780  ********************************
781  */
782 
783 #ifndef HAVE_NO_LANGEXTRA
784 struct retro_core_options_v2 *options_intl[RETRO_LANGUAGE_LAST] = {
785  &options_us, /* RETRO_LANGUAGE_ENGLISH */
786  NULL, /* RETRO_LANGUAGE_JAPANESE */
787  NULL, /* RETRO_LANGUAGE_FRENCH */
788  NULL, /* RETRO_LANGUAGE_SPANISH */
789  NULL, /* RETRO_LANGUAGE_GERMAN */
790  &options_it, /* RETRO_LANGUAGE_ITALIAN */
791  NULL, /* RETRO_LANGUAGE_DUTCH */
792  NULL, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
793  NULL, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
794  NULL, /* RETRO_LANGUAGE_RUSSIAN */
795  NULL, /* RETRO_LANGUAGE_KOREAN */
796  NULL, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
797  NULL, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
798  NULL, /* RETRO_LANGUAGE_ESPERANTO */
799  NULL, /* RETRO_LANGUAGE_POLISH */
800  NULL, /* RETRO_LANGUAGE_VIETNAMESE */
801  NULL, /* RETRO_LANGUAGE_ARABIC */
802  NULL, /* RETRO_LANGUAGE_GREEK */
803  NULL, /* RETRO_LANGUAGE_TURKISH */
804 };
805 
806 struct retro_core_option_value *retro_keys_labels_intl[RETRO_LANGUAGE_LAST] = {
807  retro_keys_label_us, /* RETRO_LANGUAGE_ENGLISH */
808  NULL, /* RETRO_LANGUAGE_JAPANESE */
809  NULL, /* RETRO_LANGUAGE_FRENCH */
810  NULL, /* RETRO_LANGUAGE_SPANISH */
811  NULL, /* RETRO_LANGUAGE_GERMAN */
812  retro_keys_label_it, /* RETRO_LANGUAGE_ITALIAN */
813  NULL, /* RETRO_LANGUAGE_DUTCH */
814  NULL, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
815  NULL, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
816  NULL, /* RETRO_LANGUAGE_RUSSIAN */
817  NULL, /* RETRO_LANGUAGE_KOREAN */
818  NULL, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
819  NULL, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
820  NULL, /* RETRO_LANGUAGE_ESPERANTO */
821  NULL, /* RETRO_LANGUAGE_POLISH */
822  NULL, /* RETRO_LANGUAGE_VIETNAMESE */
823  NULL, /* RETRO_LANGUAGE_ARABIC */
824  NULL, /* RETRO_LANGUAGE_GREEK */
825  NULL, /* RETRO_LANGUAGE_TURKISH */
826 };
827 #endif
828 
829 /*
830  ********************************
831  * Functions
832  ********************************
833  */
834 
835 static INLINE void libretro_fill_options_mapper_data(retro_environment_t environ_cb) {
836  /* Fill in the values for all the mappers */
837  int m = 0;
838  int n = 0;
839  while (option_defs_us[m].key) {
840  if (strstr(option_defs_us[m].key, "scummvm_mapper_")) {
841  n = 0;
842  while (retro_keys_label_us[n].label && n < RETRO_NUM_CORE_OPTION_VALUES_MAX - 1) {
843  option_defs_us[m].values[n].value = retro_keys_label_us[n].value;
844  option_defs_us[m].values[n].label = retro_keys_label_us[n].label;
845  ++n;
846  }
847  option_defs_us[m].values[n].value = NULL;
848  option_defs_us[m].values[n].label = NULL;
849  }
850  ++m;
851  }
852 #ifndef HAVE_NO_LANGEXTRA
853  struct retro_core_option_value *retro_keys_label_intl = NULL;
854  unsigned language = 0;
855 
856  if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
857  (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH))
858  retro_keys_label_intl = retro_keys_labels_intl[language];
859 
860  if (! options_intl[language] || ! retro_keys_label_intl)
861  return;
862 
863  m = 0;
864  n = 0;
865  while (options_intl[language]->definitions[m].key) {
866  if (strstr(options_intl[language]->definitions[m].key, "scummvm_mapper_")) {
867  n = 0;
868  while ((retro_keys_label_intl + n)->label && n < RETRO_NUM_CORE_OPTION_VALUES_MAX - 1) {
869  options_intl[language]->definitions[m].values[n].value = (retro_keys_label_intl + n)->value;
870  options_intl[language]->definitions[m].values[n].label = (retro_keys_label_intl + n)->label;
871  ++n;
872  }
873  options_intl[language]->definitions[m].values[n].value = NULL;
874  options_intl[language]->definitions[m].values[n].label = NULL;
875  }
876  ++m;
877  }
878 #endif
879 }
880 
881 /* Handles configuration/setting of core options.
882  * Should be called as early as possible - ideally inside
883  * retro_set_environment(), and no later than retro_load_game()
884  * > We place the function body in the header to avoid the
885  * necessity of adding more .c files (i.e. want this to
886  * be as painless as possible for core devs)
887  */
888 
889 static INLINE void libretro_set_core_options(retro_environment_t environ_cb,
890  bool *categories_supported) {
891  unsigned version = 0;
892 #ifndef HAVE_NO_LANGEXTRA
893  unsigned language = 0;
894 #endif
895 
896  if (!environ_cb || !categories_supported)
897  return;
898 
899  *categories_supported = false;
900 
901  if (!environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version))
902  version = 0;
903 
904  if (version >= 2) {
905 #ifndef HAVE_NO_LANGEXTRA
906  struct retro_core_options_v2_intl core_options_intl;
907 
908  core_options_intl.us = &options_us;
909  core_options_intl.local = NULL;
910 
911  if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
912  (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH))
913  core_options_intl.local = options_intl[language];
914 
915  *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL,
916  &core_options_intl);
917 #else
918  *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2,
919  &options_us);
920 #endif
921  } else {
922  size_t i, j;
923  size_t option_index = 0;
924  size_t num_options = 0;
925  struct retro_core_option_definition
926  *option_v1_defs_us = NULL;
927 #ifndef HAVE_NO_LANGEXTRA
928  size_t num_options_intl = 0;
929  struct retro_core_option_v2_definition
930  *option_defs_intl = NULL;
931  struct retro_core_option_definition
932  *option_v1_defs_intl = NULL;
933  struct retro_core_options_intl
934  core_options_v1_intl;
935 #endif
936  struct retro_variable *variables = NULL;
937  char **values_buf = NULL;
938 
939  /* Determine total number of options */
940  while (true) {
941  if (option_defs_us[num_options].key)
942  num_options++;
943  else
944  break;
945  }
946 
947  if (version >= 1) {
948  /* Allocate US array */
949  option_v1_defs_us = (struct retro_core_option_definition *)
950  calloc(num_options + 1, sizeof(struct retro_core_option_definition));
951 
952  /* Copy parameters from option_defs_us array */
953  for (i = 0; i < num_options; i++) {
954  struct retro_core_option_v2_definition *option_def_us = &option_defs_us[i];
955  struct retro_core_option_value *option_values = option_def_us->values;
956  struct retro_core_option_definition *option_v1_def_us = &option_v1_defs_us[i];
957  struct retro_core_option_value *option_v1_values = option_v1_def_us->values;
958 
959  option_v1_def_us->key = option_def_us->key;
960  option_v1_def_us->desc = option_def_us->desc;
961  option_v1_def_us->info = option_def_us->info;
962  option_v1_def_us->default_value = option_def_us->default_value;
963 
964  /* Values must be copied individually... */
965  while (option_values->value) {
966  option_v1_values->value = option_values->value;
967  option_v1_values->label = option_values->label;
968 
969  option_values++;
970  option_v1_values++;
971  }
972  }
973 
974 #ifndef HAVE_NO_LANGEXTRA
975  if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
976  (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH) &&
977  options_intl[language])
978  option_defs_intl = options_intl[language]->definitions;
979 
980  if (option_defs_intl) {
981  /* Determine number of intl options */
982  while (true) {
983  if (option_defs_intl[num_options_intl].key)
984  num_options_intl++;
985  else
986  break;
987  }
988 
989  /* Allocate intl array */
990  option_v1_defs_intl = (struct retro_core_option_definition *)
991  calloc(num_options_intl + 1, sizeof(struct retro_core_option_definition));
992 
993  /* Copy parameters from option_defs_intl array */
994  for (i = 0; i < num_options_intl; i++) {
995  struct retro_core_option_v2_definition *option_def_intl = &option_defs_intl[i];
996  struct retro_core_option_value *option_values = option_def_intl->values;
997  struct retro_core_option_definition *option_v1_def_intl = &option_v1_defs_intl[i];
998  struct retro_core_option_value *option_v1_values = option_v1_def_intl->values;
999 
1000  option_v1_def_intl->key = option_def_intl->key;
1001  option_v1_def_intl->desc = option_def_intl->desc;
1002  option_v1_def_intl->info = option_def_intl->info;
1003  option_v1_def_intl->default_value = option_def_intl->default_value;
1004 
1005  /* Values must be copied individually... */
1006  while (option_values->value) {
1007  option_v1_values->value = option_values->value;
1008  option_v1_values->label = option_values->label;
1009 
1010  option_values++;
1011  option_v1_values++;
1012  }
1013  }
1014  }
1015 
1016  core_options_v1_intl.us = option_v1_defs_us;
1017  core_options_v1_intl.local = option_v1_defs_intl;
1018 
1019  environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_v1_intl);
1020 #else
1021  environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, option_v1_defs_us);
1022 #endif
1023  } else {
1024  /* Allocate arrays */
1025  variables = (struct retro_variable *)calloc(num_options + 1,
1026  sizeof(struct retro_variable));
1027  values_buf = (char **)calloc(num_options, sizeof(char *));
1028 
1029  if (!variables || !values_buf)
1030  goto error;
1031 
1032  /* Copy parameters from option_defs_us array */
1033  for (i = 0; i < num_options; i++) {
1034  const char *key = option_defs_us[i].key;
1035  const char *desc = option_defs_us[i].desc;
1036  const char *default_value = option_defs_us[i].default_value;
1037  struct retro_core_option_value *values = option_defs_us[i].values;
1038  size_t buf_len = 3;
1039  size_t default_index = 0;
1040 
1041  values_buf[i] = NULL;
1042 
1043  if (desc) {
1044  size_t num_values = 0;
1045 
1046  /* Determine number of values */
1047  while (true) {
1048  if (values[num_values].value) {
1049  /* Check if this is the default value */
1050  if (default_value)
1051  if (strcmp(values[num_values].value, default_value) == 0)
1052  default_index = num_values;
1053 
1054  buf_len += strlen(values[num_values].value);
1055  num_values++;
1056  } else
1057  break;
1058  }
1059 
1060  /* Build values string */
1061  if (num_values > 0) {
1062  buf_len += num_values - 1;
1063  buf_len += strlen(desc);
1064 
1065  values_buf[i] = (char *)calloc(buf_len, sizeof(char));
1066  if (!values_buf[i])
1067  goto error;
1068 
1069  strcpy(values_buf[i], desc);
1070  strcat(values_buf[i], "; ");
1071 
1072  /* Default value goes first */
1073  strcat(values_buf[i], values[default_index].value);
1074 
1075  /* Add remaining values */
1076  for (j = 0; j < num_values; j++) {
1077  if (j != default_index) {
1078  strcat(values_buf[i], "|");
1079  strcat(values_buf[i], values[j].value);
1080  }
1081  }
1082  }
1083  }
1084 
1085  variables[option_index].key = key;
1086  variables[option_index].value = values_buf[i];
1087  option_index++;
1088  }
1089 
1090  /* Set variables */
1091  environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
1092  }
1093 
1094 error:
1095  /* Clean up */
1096 
1097  if (option_v1_defs_us) {
1098  free(option_v1_defs_us);
1099  option_v1_defs_us = NULL;
1100  }
1101 
1102 #ifndef HAVE_NO_LANGEXTRA
1103  if (option_v1_defs_intl) {
1104  free(option_v1_defs_intl);
1105  option_v1_defs_intl = NULL;
1106  }
1107 #endif
1108 
1109  if (values_buf) {
1110  for (i = 0; i < num_options; i++) {
1111  if (values_buf[i]) {
1112  free(values_buf[i]);
1113  values_buf[i] = NULL;
1114  }
1115  }
1116 
1117  free(values_buf);
1118  values_buf = NULL;
1119  }
1120 
1121  if (variables) {
1122  free(variables);
1123  variables = NULL;
1124  }
1125  }
1126 }
1127 
1128 #ifdef __cplusplus
1129 }
1130 #endif
1131 
1132 #endif
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1