Add enhanced core options
[pcsx_rearmed.git] / frontend / libretro_core_options.h
1 #ifndef LIBRETRO_CORE_OPTIONS_H__
2 #define LIBRETRO_CORE_OPTIONS_H__
3
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include <libretro.h>
8 #include <retro_inline.h>
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 /*
15  ********************************
16  * Core Option Definitions
17  ********************************
18 */
19
20 /* RETRO_LANGUAGE_ENGLISH */
21
22 /* Default language:
23  * - All other languages must include the same keys and values
24  * - Will be used as a fallback in the event that frontend language
25  *   is not available
26  * - Will be used as a fallback for any missing entries in
27  *   frontend language definition
28  */
29
30 #ifdef HAVE_PRE_ARMV7
31 #define PSX_CLOCK_DEFAULT "50"
32 #define PSX_CLOCK_LABEL "Overclock or underclock the PSX clock. Default is 50"
33 #else
34 #define PSX_CLOCK_DEFAULT "57"
35 #define PSX_CLOCK_LABEL "Overclock or underclock the PSX clock. Default is 57"
36 #endif
37
38 struct retro_core_option_definition option_defs_us[] = {
39    {
40       "pcsx_rearmed_frameskip",
41       "Frameskip",
42       "Choose how much frames should be skipped to improve performance at the expense of visual smoothness.",
43       {
44          { "0", NULL },
45          { "1", NULL },
46          { "2", NULL },
47          { "3", NULL },
48          { NULL, NULL},
49       },
50       "0",
51    },
52    {
53       "pcsx_rearmed_bios",
54       "Use BIOS",
55       "Allows you to use real bios file (if available) or emulated bios (HLE). Its recommended to use official bios file for better compatibility.",
56       {
57          { "auto", "auto" },
58          { "HLE", "hle" },
59          { NULL, NULL},
60       },
61       "auto",
62    },
63    {
64       "pcsx_rearmed_region",
65       "Region",
66       "Choose what region the system is from. 60 Hz for NTSC, 50 Hz for PAL.",
67       {
68          { "auto", "auto" },
69          { "NTSC", "ntsc" },
70          { "PAL", "pal" },
71          { NULL, NULL},
72       },
73       "auto",
74    },
75    {
76       "pcsx_rearmed_memcard2",
77       "Enable second memory card (shared)",
78       "Enabled the memory card slot 2. This is shared amongs all games.",
79       {
80          { "disable",  NULL },
81          { "enabled",  NULL },
82          { NULL, NULL},
83       },
84       "disable",
85    },
86    {
87       "pcsx_rearmed_pad1type",
88       "Pad 1 Type",
89       "Pad type for player 1",
90       {
91          { "standard", NULL },
92          { "analog", NULL },
93          { "dualshock", NULL },
94          { "negcon", NULL },
95          { "none", NULL },
96          { NULL, NULL},
97       },
98       "standard",
99    },
100    {
101       "pcsx_rearmed_pad2type",
102       "Pad 2 Type",
103       "Pad type for player 2",
104       {
105          { "standard", NULL },
106          { "analog", NULL },
107          { "dualshock", NULL },
108          { "negcon", NULL },
109          { "none", NULL },
110          { NULL, NULL},
111       },
112       "standard",
113    },
114    {
115       "pcsx_rearmed_pad3type",
116       "Pad 3 Type",
117       "Pad type for player 3",
118       {
119          { "standard", NULL },
120          { "analog", NULL },
121          { "dualshock", NULL },
122          { "negcon", NULL },
123          { "none", NULL },
124          { NULL, NULL},
125       },
126       "none",
127    },
128    {
129       "pcsx_rearmed_pad4type",
130       "Pad 4 Type",
131       "Pad type for player 4",
132       {
133          { "standard", NULL },
134          { "analog", NULL },
135          { "dualshock", NULL },
136          { "negcon", NULL },
137          { "none", NULL },
138          { NULL, NULL},
139       },
140       "none",
141    },
142    {
143       "pcsx_rearmed_pad5type",
144       "Pad 5 Type",
145       "Pad type for player 5",
146       {
147          { "standard", NULL },
148          { "analog",  NULL },
149          { "dualshock", NULL },
150          { "negcon", NULL },
151          { "none", NULL },
152          { NULL, NULL},
153       },
154       "none",
155    },{
156       "pcsx_rearmed_pad6type",
157       "Pad 6 Type",
158       "Pad type for player 6",
159       {
160          { "standard", NULL },
161          { "analog",  NULL },
162          { "dualshock", NULL },
163          { "negcon", NULL },
164          { "none", NULL },
165          { NULL, NULL},
166       },
167       "none",
168    },{
169       "pcsx_rearmed_pad7type",
170       "Pad 7 Type",
171       "Pad type for player 7",
172       {
173          { "standard", NULL },
174          { "analog",  NULL },
175          { "dualshock", NULL },
176          { "negcon", NULL },
177          { "none", NULL },
178          { NULL, NULL},
179       },
180       "none",
181    },{
182       "pcsx_rearmed_pad8type",
183       "Pad 8 Type",
184       "Pad type for player 8",
185       {
186          { "standard", NULL },
187          { "analog",  NULL },
188          { "dualshock", NULL },
189          { "negcon", NULL },
190          { "none", NULL },
191          { NULL, NULL},
192       },
193       "none",
194    },
195    {
196       "pcsx_rearmed_multitap1",
197       "Multitap 1",
198       "Enables/Disables multitap on port 1, allowing upto 5 players in games that permit it.",
199       {
200          { "auto", NULL },
201          { "disabled", NULL },
202          { "enabled",  NULL },
203          { NULL, NULL},
204       },
205       "auto",
206    },
207    {
208       "pcsx_rearmed_multitap2",
209       "Multitap 2",
210       "Enables/Disables multitap on port 2, allowing upto 8 players in games that permit it. Multitap 1 has to be enabled for this to work.",
211       {
212          { "auto", NULL },
213          { "disabled",  NULL },
214          { "enabled",   NULL },
215          { NULL, NULL},
216       },
217       "auto",
218    },
219    {
220       "pcsx_rearmed_negcon_deadzone",
221       "NegCon Twist Deadzone (percent)",
222       "Sets the deadzone of the RetroPad left analog stick when simulating the 'twist' action of emulated neGcon Controllers. Used to eliminate drift/unwanted input.",
223       {
224          { "0",  NULL },
225          { "5",  NULL },
226          { "10", NULL },
227          { "15", NULL },
228          { "20", NULL },
229          { "25", NULL },
230          { "30", NULL },
231          { NULL, NULL},
232       },
233       "0",
234    },
235    {
236       "pcsx_rearmed_negcon_response",
237       "NegCon Twist Response",
238       "Specifies the analog response when using a RetroPad left analog stick to simulate the 'twist' action of emulated neGcon Controllers.",
239       {
240          { "linear", NULL },
241          { "quadratic", NULL },
242          { "cubic", NULL },
243          { NULL, NULL},
244       },
245       "linear",
246    },
247    {
248       "pcsx_rearmed_vibration",
249       "Enable Vibration",
250       "Enables Vibration feedback for controllers that supports vibration features.",
251       {
252          { "disabled", NULL },
253          { "enabled",  NULL },
254          { NULL, NULL},
255       },
256       "enabled",
257    },
258    {
259       "pcsx_rearmed_dithering",
260       "Enable Dithering",
261       "If Off, disables the dithering pattern the PSX applies to combat color banding.",
262       {
263          { "disabled", NULL },
264          { "enabled",  NULL },
265          { NULL, NULL},
266       },
267       "enabled",
268    },
269
270 #ifndef DRC_DISABLE
271    {
272       "pcsx_rearmed_drc",
273       "Dynamic recompiler",
274       "Enables core to use dynamic recompiler or interpreter (slower) cpu instructions.",
275       {
276          { "disabled", NULL },
277          { "enabled",  NULL },
278          { NULL, NULL},
279       },
280       "enabled",
281    },
282    {
283       "pcsx_rearmed_psxclock",
284       "PSX CPU clock",
285       PSX_CLOCK_LABEL,
286       {
287          { "30", NULL },
288          { "31", NULL },
289          { "32", NULL },
290          { "33", NULL },
291          { "34", NULL },
292          { "35", NULL },
293          { "36", NULL },
294          { "37", NULL },
295          { "38", NULL },
296          { "39", NULL },
297          { "40", NULL },
298          { "41", NULL },
299          { "42", NULL },
300          { "43", NULL },
301          { "44", NULL },
302          { "45", NULL },
303          { "46", NULL },
304          { "47", NULL },
305          { "48", NULL },
306          { "49", NULL },
307          { "50", NULL },
308          { "51", NULL },
309          { "52", NULL },
310          { "53", NULL },
311          { "54", NULL },
312          { "55", NULL },
313          { "56", NULL },
314          { "57", NULL },
315          { "58", NULL },
316          { "59", NULL },
317          { "60", NULL },
318          { "61", NULL },
319          { "62", NULL },
320          { "63", NULL },
321          { "64", NULL },
322          { "65", NULL },
323          { "66", NULL },
324          { "67", NULL },
325          { "68", NULL },
326          { "69", NULL },
327          { "70", NULL },
328          { "71", NULL },
329          { "72", NULL },
330          { "73", NULL },
331          { "74", NULL },
332          { "75", NULL },
333          { "76", NULL },
334          { "77", NULL },
335          { "78", NULL },
336          { "79", NULL },
337          { "80", NULL },
338          { "81", NULL },
339          { "82", NULL },
340          { "83", NULL },
341          { "84", NULL },
342          { "85", NULL },
343          { "86", NULL },
344          { "87", NULL },
345          { "88", NULL },
346          { "89", NULL },
347          { "90", NULL },
348          { "91", NULL },
349          { "92", NULL },
350          { "93", NULL },
351          { "94", NULL },
352          { "95", NULL },
353          { "96", NULL },
354          { "97", NULL },
355          { "98", NULL },
356          { "99", NULL },
357          { "100", NULL },
358          { NULL, NULL},
359       },
360       PSX_CLOCK_DEFAULT,
361    },
362 #endif /* DRC_DISABLE */
363
364 #ifdef __ARM_NEON__
365    {
366       "pcsx_rearmed_neon_interlace_enable",
367       "Enable interlacing mode(s)",
368       "Enables fake scanlines effect.",
369       {
370          { "disabled", NULL },
371          { "enabled",  NULL },
372          { NULL, NULL},
373       },
374       "disabled",
375    },
376    {
377       "pcsx_rearmed_neon_enhancement_enable",
378       "Enhanced resolution (slow)",
379       "Renders in double resolution at the cost of lower performance",
380       {
381          { "disabled", NULL },
382          { "enabled",  NULL },
383          { NULL, NULL},
384       },
385       "disabled",
386    },
387    {
388       "pcsx_rearmed_neon_enhancement_no_main",
389       "Enhanced resolution speed hack",
390       "Speed hack for Enhanced resolution option (glitches some games).",
391       {
392          { "disabled", NULL },
393          { "enabled",  NULL },
394          { NULL, NULL},
395       },
396       "disabled",
397    },
398 #endif /* __ARM_NEON__ */
399
400    {
401       "pcsx_rearmed_duping_enable",
402       "Frame duping",
403       "A speedup, redraws/reuses the last frame if there was no new data.",
404       {
405          { "disabled", NULL },
406          { "enabled",  NULL },
407          { NULL, NULL},
408       },
409       "enabled",
410    },
411    {
412       "pcsx_rearmed_display_internal_fps",
413       "Display Internal FPS",
414       "Shows an on-screen frames per second counter when enabled.",
415       {
416          { "disabled", NULL },
417          { "enabled",  NULL },
418          { NULL, NULL},
419       },
420       "disabled",
421    },
422    {
423       "pcsx_rearmed_show_bios_bootlogo",
424       "Show Bios Bootlogo",
425       "When enabled, shows the playstation logo when starting or resetting. (Breaks some games).",
426       {
427          { "disabled", NULL },
428          { "enabled",  NULL },
429          { NULL, NULL},
430       },
431       "disabled",
432    },
433    {
434       "pcsx_rearmed_spu_reverb",
435       "Sound Reverb",
436       "Enables or disables audio reverb effect.",
437       {
438          { "disabled", NULL },
439          { "enabled",  NULL },
440          { NULL, NULL},
441       },
442       "enabled",
443    },
444    {
445       "pcsx_rearmed_spu_interpolation",
446       "Sound: Interpolation",
447       NULL,
448       {
449          { "simple", NULL },
450          { "gaussian", NULL },
451          { "cubic", NULL },
452          { "off", NULL },
453          { NULL, NULL},
454       },
455       "simple",
456    },
457    {
458       "pcsx_rearmed_idiablofix",
459       "Diablo Music Fix",
460       NULL,
461       {
462          { "disabled", NULL },
463          { "enabled",  NULL },
464          { NULL, NULL},
465       },
466       "disabled",
467    },
468    {
469       "pcsx_rearmed_pe2_fix",
470       "Parasite Eve 2/Vandal Hearts 1/2 Fix",
471       NULL,
472       {
473          { "disabled", NULL },
474          { "enabled",  NULL },
475          { NULL, NULL},
476       },
477       "disabled",
478    },
479    {
480       "pcsx_rearmed_inuyasha_fix",
481       "InuYasha Sengoku Battle Fix",
482       NULL,
483       {
484          { "disabled", NULL },
485          { "enabled",  NULL },
486          { NULL, NULL},
487       },
488       "disabled",
489    },
490
491    /* ADVANCED OPTIONS */
492    {
493       "pcsx_rearmed_noxadecoding",
494       "XA Decoding",
495       NULL,
496       {
497          { "disabled", NULL },
498          { "enabled",  NULL },
499          { NULL, NULL},
500       },
501       "enabled",
502    },
503    {
504       "pcsx_rearmed_nocdaudio",
505       "CD Audio",
506       NULL,
507       {
508          { "disabled", NULL },
509          { "enabled",  NULL },
510          { NULL, NULL},
511       },
512       "enabled",
513    },
514
515 #ifndef DRC_DISABLE
516    {
517       "pcsx_rearmed_nosmccheck",
518       "(Speed Hack) Disable SMC Checks",
519       "Will cause crashes when loading, break memcards.",
520       {
521          { "disabled", NULL },
522          { "enabled",  NULL },
523          { NULL, NULL},
524       },
525       "disabled",
526    },
527    {
528       "pcsx_rearmed_gteregsunneeded",
529       "(Speed Hack) Assume GTE Regs Unneeded",
530       "May cause graphical glitches.",
531       {
532          { "disabled", NULL },
533          { "enabled",  NULL },
534          { NULL, NULL},
535       },
536       "disabled",
537    },
538    {
539       "pcsx_rearmed_nogteflags",
540       "(Speed Hack) Disable GTE Flags",
541       "Will cause graphical glitches.",
542       {
543          { "disabled", NULL },
544          { "enabled",  NULL },
545          { NULL, NULL},
546       },
547       "disabled",
548    },
549 #endif /* DRC_DISABLE */
550
551    { NULL, NULL, NULL, { NULL, NULL }, NULL },
552 };
553
554 /* RETRO_LANGUAGE_JAPANESE */
555
556 /* RETRO_LANGUAGE_FRENCH */
557
558 /* RETRO_LANGUAGE_SPANISH */
559
560 /* RETRO_LANGUAGE_GERMAN */
561
562 /* RETRO_LANGUAGE_ITALIAN */
563
564 /* RETRO_LANGUAGE_DUTCH */
565
566 /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
567
568 /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
569
570 /* RETRO_LANGUAGE_RUSSIAN */
571
572 /* RETRO_LANGUAGE_KOREAN */
573
574 /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
575
576 /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
577
578 /* RETRO_LANGUAGE_ESPERANTO */
579
580 /* RETRO_LANGUAGE_POLISH */
581
582 /* RETRO_LANGUAGE_VIETNAMESE */
583
584 /* RETRO_LANGUAGE_ARABIC */
585
586 /* RETRO_LANGUAGE_GREEK */
587
588 /* RETRO_LANGUAGE_TURKISH */
589
590 /*
591  ********************************
592  * Language Mapping
593  ********************************
594 */
595
596 struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = {
597    option_defs_us, /* RETRO_LANGUAGE_ENGLISH */
598    NULL,           /* RETRO_LANGUAGE_JAPANESE */
599    NULL,           /* RETRO_LANGUAGE_FRENCH */
600    NULL,           /* RETRO_LANGUAGE_SPANISH */
601    NULL,           /* RETRO_LANGUAGE_GERMAN */
602    NULL,           /* RETRO_LANGUAGE_ITALIAN */
603    NULL,           /* RETRO_LANGUAGE_DUTCH */
604    NULL,           /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
605    NULL,           /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
606    NULL,           /* RETRO_LANGUAGE_RUSSIAN */
607    NULL,           /* RETRO_LANGUAGE_KOREAN */
608    NULL,           /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
609    NULL,           /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
610    NULL,           /* RETRO_LANGUAGE_ESPERANTO */
611    NULL,           /* RETRO_LANGUAGE_POLISH */
612    NULL,           /* RETRO_LANGUAGE_VIETNAMESE */
613    NULL,           /* RETRO_LANGUAGE_ARABIC */
614    NULL,           /* RETRO_LANGUAGE_GREEK */
615    NULL,           /* RETRO_LANGUAGE_TURKISH */
616 };
617
618 /*
619  ********************************
620  * Functions
621  ********************************
622 */
623
624 /* Handles configuration/setting of core options.
625  * Should only be called inside retro_set_environment().
626  * > We place the function body in the header to avoid the
627  *   necessity of adding more .c files (i.e. want this to
628  *   be as painless as possible for core devs)
629  */
630
631 static INLINE void libretro_set_core_options(retro_environment_t environ_cb)
632 {
633    unsigned version = 0;
634
635    if (!environ_cb)
636       return;
637
638    if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version == 1))
639    {
640       struct retro_core_options_intl core_options_intl;
641       unsigned language = 0;
642
643       core_options_intl.us    = option_defs_us;
644       core_options_intl.local = NULL;
645
646       if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
647           (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH))
648          core_options_intl.local = option_defs_intl[language];
649
650       environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_intl);
651    }
652    else
653    {
654       size_t i;
655       size_t option_index              = 0;
656       size_t num_options               = 0;
657       struct retro_variable *variables = NULL;
658       char **values_buf                = NULL;
659
660       /* Determine number of options
661        * > Note: We are going to skip a number of irrelevant
662        *   core options when building the retro_variable array,
663        *   but we'll allocate space for all of them. The difference
664        *   in resource usage is negligible, and this allows us to
665        *   keep the code 'cleaner' */
666       while (true)
667       {
668          if (option_defs_us[num_options].key)
669             num_options++;
670          else
671             break;
672       }
673
674       /* Allocate arrays */
675       variables  = (struct retro_variable *)calloc(num_options + 1, sizeof(struct retro_variable));
676       values_buf = (char **)calloc(num_options, sizeof(char *));
677
678       if (!variables || !values_buf)
679          goto error;
680
681       /* Copy parameters from option_defs_us array */
682       for (i = 0; i < num_options; i++)
683       {
684          const char *key                        = option_defs_us[i].key;
685          const char *desc                       = option_defs_us[i].desc;
686          const char *default_value              = option_defs_us[i].default_value;
687          struct retro_core_option_value *values = option_defs_us[i].values;
688          size_t buf_len                         = 3;
689          size_t default_index                   = 0;
690
691          values_buf[i] = NULL;
692
693          /* Skip options that are irrelevant when using the
694           * old style core options interface */
695          if ((strcmp(key, "fceumm_advance_sound_options") == 0))
696             continue;
697
698          if (desc)
699          {
700             size_t num_values = 0;
701
702             /* Determine number of values */
703             while (true)
704             {
705                if (values[num_values].value)
706                {
707                   /* Check if this is the default value */
708                   if (default_value)
709                      if (strcmp(values[num_values].value, default_value) == 0)
710                         default_index = num_values;
711
712                   buf_len += strlen(values[num_values].value);
713                   num_values++;
714                }
715                else
716                   break;
717             }
718
719             /* Build values string */
720             if (num_values > 1)
721             {
722                size_t j;
723
724                buf_len += num_values - 1;
725                buf_len += strlen(desc);
726
727                values_buf[i] = (char *)calloc(buf_len, sizeof(char));
728                if (!values_buf[i])
729                   goto error;
730
731                strcpy(values_buf[i], desc);
732                strcat(values_buf[i], "; ");
733
734                /* Default value goes first */
735                strcat(values_buf[i], values[default_index].value);
736
737                /* Add remaining values */
738                for (j = 0; j < num_values; j++)
739                {
740                   if (j != default_index)
741                   {
742                      strcat(values_buf[i], "|");
743                      strcat(values_buf[i], values[j].value);
744                   }
745                }
746             }
747          }
748
749          variables[option_index].key   = key;
750          variables[option_index].value = values_buf[i];
751          option_index++;
752       }
753
754       /* Set variables */
755       environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
756
757 error:
758
759       /* Clean up */
760       if (values_buf)
761       {
762          for (i = 0; i < num_options; i++)
763          {
764             if (values_buf[i])
765             {
766                free(values_buf[i]);
767                values_buf[i] = NULL;
768             }
769          }
770
771          free(values_buf);
772          values_buf = NULL;
773       }
774
775       if (variables)
776       {
777          free(variables);
778          variables = NULL;
779       }
780    }
781 }
782
783 #ifdef __cplusplus
784 }
785 #endif
786
787 #endif