aboutsummaryrefslogtreecommitdiff
path: root/libretro_core_options.h
diff options
context:
space:
mode:
Diffstat (limited to 'libretro_core_options.h')
-rw-r--r--libretro_core_options.h322
1 files changed, 243 insertions, 79 deletions
diff --git a/libretro_core_options.h b/libretro_core_options.h
index 032cefd..9b89154 100644
--- a/libretro_core_options.h
+++ b/libretro_core_options.h
@@ -13,9 +13,10 @@
/*
********************************
- * VERSION: 1.3
+ * VERSION: 2.0
********************************
*
+ * - 2.0: Add support for core options v2 interface
* - 1.3: Move translations to libretro_core_options_intl.h
* - libretro_core_options_intl.h includes BOM and utf-8
* fix for MSVC 2010-2013
@@ -48,16 +49,28 @@ extern "C" {
* - Will be used as a fallback for any missing entries in
* frontend language definition */
-struct retro_core_option_definition option_defs_us[] = {
+struct retro_core_option_v2_category option_cats_us[] = {
+ {
+ "hacks",
+ "Emulation Hacks",
+ "Configure processor overclocking and emulation accuracy parameters affecting low-level performance and compatibility."
+ },
+ { NULL, NULL, NULL },
+};
+
+struct retro_core_option_v2_definition option_defs_us[] = {
/* These variable names and possible values constitute an ABI with ZMZ (ZSNES Libretro player).
* Changing "Show layer 1" is fine, but don't change "layer_1"/etc or the possible values ("Yes|No").
* Adding more variables and rearranging them is safe. */
{
- "catsfc_VideoMode",
+ "snes9x_2005_region",
"Console Region",
+ NULL,
"Specify which region the system is from. 'PAL' is 50hz, 'NTSC' is 60hz. Games will run faster or slower than normal if the incorrect region is selected.",
+ NULL,
+ NULL,
{
{ "auto", "Auto" },
{ "NTSC", NULL },
@@ -67,9 +80,12 @@ struct retro_core_option_definition option_defs_us[] = {
"auto"
},
{
- "catsfc_frameskip",
+ "snes9x_2005_frameskip",
"Frameskip",
+ NULL,
"Skip frames to avoid audio buffer under-run (crackling). Improves performance at the expense of visual smoothness. 'Auto' skips frames when advised by the frontend. 'Manual' utilises the 'Frameskip Threshold (%)' setting.",
+ NULL,
+ NULL,
{
{ "disabled", NULL },
{ "auto", "Auto" },
@@ -79,9 +95,12 @@ struct retro_core_option_definition option_defs_us[] = {
"disabled"
},
{
- "catsfc_frameskip_threshold",
+ "snes9x_2005_frameskip_threshold",
"Frameskip Threshold (%)",
+ NULL,
"When 'Frameskip' is set to 'Manual', specifies the audio buffer occupancy threshold (percentage) below which frames will be skipped. Higher values reduce the risk of crackling by causing frames to be dropped more frequently.",
+ NULL,
+ NULL,
{
{ "15", NULL },
{ "18", NULL },
@@ -104,9 +123,12 @@ struct retro_core_option_definition option_defs_us[] = {
"33"
},
{
- "catsfc_overclock_cycles",
+ "snes9x_2005_overclock_cycles",
"Reduce Slowdown (Hack, Unsafe, Restart)",
+ NULL,
"Many games for the SNES suffered from slowdown due to the weak main CPU. This option helps allievate that at the cost of possible bugs. COMPATIBLE: Reduce slowdown but keep as much game compatibility as much as possible. MAX: Reduce slowdown as much as possible but will break more games.",
+ NULL,
+ "hacks",
{
{ "disabled", NULL },
{ "compatible", "Compatible" },
@@ -116,9 +138,12 @@ struct retro_core_option_definition option_defs_us[] = {
"disabled"
},
{
- "catsfc_reduce_sprite_flicker",
+ "snes9x_2005_reduce_sprite_flicker",
"Reduce Flickering (Hack, Unsafe)",
- "Raises sprite limit to reduce flickering in games.",
+ NULL,
+ "Increases number of sprites that can be drawn simultaneously on screen. Reduces flickering in games.",
+ NULL,
+ "hacks",
{
{ "disabled", NULL },
{ "enabled", NULL },
@@ -126,7 +151,12 @@ struct retro_core_option_definition option_defs_us[] = {
},
"disabled"
},
- { NULL, NULL, NULL, {{0}}, NULL },
+ { NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },
+};
+
+struct retro_core_options_v2 options_us = {
+ option_cats_us,
+ option_defs_us
};
/*
@@ -136,8 +166,8 @@ struct retro_core_option_definition option_defs_us[] = {
*/
#ifndef HAVE_NO_LANGEXTRA
-struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = {
- option_defs_us, /* RETRO_LANGUAGE_ENGLISH */
+struct retro_core_options_v2 *options_intl[RETRO_LANGUAGE_LAST] = {
+ &options_us, /* RETRO_LANGUAGE_ENGLISH */
NULL, /* RETRO_LANGUAGE_JAPANESE */
NULL, /* RETRO_LANGUAGE_FRENCH */
NULL, /* RETRO_LANGUAGE_SPANISH */
@@ -160,9 +190,8 @@ struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = {
NULL, /* RETRO_LANGUAGE_PERSIAN */
NULL, /* RETRO_LANGUAGE_HEBREW */
NULL, /* RETRO_LANGUAGE_ASTURIAN */
-
+ NULL, /* RETRO_LANGUAGE_FINNISH */
};
-#endif
/*
********************************
@@ -178,124 +207,257 @@ struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = {
* be as painless as possible for core devs)
*/
-static INLINE void libretro_set_core_options(retro_environment_t environ_cb)
+static INLINE void libretro_set_core_options(retro_environment_t environ_cb,
+ bool *categories_supported)
{
- unsigned version = 0;
+ unsigned version = 0;
+#ifndef HAVE_NO_LANGEXTRA
+ unsigned language = 0;
+#endif
- if (!environ_cb)
+ if (!environ_cb || !categories_supported)
return;
- if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version >= 1))
+ *categories_supported = false;
+
+ if (!environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version))
+ version = 0;
+
+ if (version >= 2)
{
#ifndef HAVE_NO_LANGEXTRA
- struct retro_core_options_intl core_options_intl;
- unsigned language = 0;
+ struct retro_core_options_v2_intl core_options_intl;
- core_options_intl.us = option_defs_us;
+ core_options_intl.us = &options_us;
core_options_intl.local = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
(language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH))
- core_options_intl.local = option_defs_intl[language];
+ core_options_intl.local = options_intl[language];
- environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_intl);
+ *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL,
+ &core_options_intl);
#else
- environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, &option_defs_us);
+ *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2,
+ &options_us);
#endif
}
else
{
- size_t i;
+ size_t i, j;
+ size_t option_index = 0;
size_t num_options = 0;
+ struct retro_core_option_definition
+ *option_v1_defs_us = NULL;
+#ifndef HAVE_NO_LANGEXTRA
+ size_t num_options_intl = 0;
+ struct retro_core_option_v2_definition
+ *option_defs_intl = NULL;
+ struct retro_core_option_definition
+ *option_v1_defs_intl = NULL;
+ struct retro_core_options_intl
+ core_options_v1_intl;
+#endif
struct retro_variable *variables = NULL;
char **values_buf = NULL;
- /* Determine number of options */
- for (;;)
+ /* Determine total number of options */
+ while (true)
{
- if (!option_defs_us[num_options].key)
+ if (option_defs_us[num_options].key)
+ num_options++;
+ else
break;
- num_options++;
}
- /* Allocate arrays */
- variables = (struct retro_variable *)calloc(num_options + 1, sizeof(struct retro_variable));
- values_buf = (char **)calloc(num_options, sizeof(char *));
+ if (version >= 1)
+ {
+ /* Allocate US array */
+ option_v1_defs_us = (struct retro_core_option_definition *)
+ calloc(num_options + 1, sizeof(struct retro_core_option_definition));
- if (!variables || !values_buf)
- goto error;
+ /* Copy parameters from option_defs_us array */
+ for (i = 0; i < num_options; i++)
+ {
+ struct retro_core_option_v2_definition *option_def_us = &option_defs_us[i];
+ struct retro_core_option_value *option_values = option_def_us->values;
+ struct retro_core_option_definition *option_v1_def_us = &option_v1_defs_us[i];
+ struct retro_core_option_value *option_v1_values = option_v1_def_us->values;
+
+ option_v1_def_us->key = option_def_us->key;
+ option_v1_def_us->desc = option_def_us->desc;
+ option_v1_def_us->info = option_def_us->info;
+ option_v1_def_us->default_value = option_def_us->default_value;
+
+ /* Values must be copied individually... */
+ while (option_values->value)
+ {
+ option_v1_values->value = option_values->value;
+ option_v1_values->label = option_values->label;
- /* Copy parameters from option_defs_us array */
- for (i = 0; i < num_options; i++)
- {
- const char *key = option_defs_us[i].key;
- const char *desc = option_defs_us[i].desc;
- const char *default_value = option_defs_us[i].default_value;
- struct retro_core_option_value *values = option_defs_us[i].values;
- size_t buf_len = 3;
- size_t default_index = 0;
+ option_values++;
+ option_v1_values++;
+ }
+ }
- values_buf[i] = NULL;
+#ifndef HAVE_NO_LANGEXTRA
+ if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
+ (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH) &&
+ options_intl[language])
+ option_defs_intl = options_intl[language]->definitions;
- if (desc)
+ if (option_defs_intl)
{
- size_t num_values = 0;
-
- /* Determine number of values */
- for (;;)
+ /* Determine number of intl options */
+ while (true)
{
- if (!values[num_values].value)
+ if (option_defs_intl[num_options_intl].key)
+ num_options_intl++;
+ else
break;
+ }
+
+ /* Allocate intl array */
+ option_v1_defs_intl = (struct retro_core_option_definition *)
+ calloc(num_options_intl + 1, sizeof(struct retro_core_option_definition));
- /* Check if this is the default value */
- if (default_value)
- if (strcmp(values[num_values].value, default_value) == 0)
- default_index = num_values;
+ /* Copy parameters from option_defs_intl array */
+ for (i = 0; i < num_options_intl; i++)
+ {
+ struct retro_core_option_v2_definition *option_def_intl = &option_defs_intl[i];
+ struct retro_core_option_value *option_values = option_def_intl->values;
+ struct retro_core_option_definition *option_v1_def_intl = &option_v1_defs_intl[i];
+ struct retro_core_option_value *option_v1_values = option_v1_def_intl->values;
+
+ option_v1_def_intl->key = option_def_intl->key;
+ option_v1_def_intl->desc = option_def_intl->desc;
+ option_v1_def_intl->info = option_def_intl->info;
+ option_v1_def_intl->default_value = option_def_intl->default_value;
+
+ /* Values must be copied individually... */
+ while (option_values->value)
+ {
+ option_v1_values->value = option_values->value;
+ option_v1_values->label = option_values->label;
- buf_len += strlen(values[num_values].value);
- num_values++;
+ option_values++;
+ option_v1_values++;
+ }
}
+ }
- /* Build values string */
- if (num_values > 0)
- {
- size_t j;
+ core_options_v1_intl.us = option_v1_defs_us;
+ core_options_v1_intl.local = option_v1_defs_intl;
- buf_len += num_values - 1;
- buf_len += strlen(desc);
+ environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_v1_intl);
+#else
+ environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, option_v1_defs_us);
+#endif
+ }
+ else
+ {
+ /* Allocate arrays */
+ variables = (struct retro_variable *)calloc(num_options + 1,
+ sizeof(struct retro_variable));
+ values_buf = (char **)calloc(num_options, sizeof(char *));
- values_buf[i] = (char *)calloc(buf_len, sizeof(char));
- if (!values_buf[i])
- goto error;
+ if (!variables || !values_buf)
+ goto error;
- strcpy(values_buf[i], desc);
- strcat(values_buf[i], "; ");
+ /* Copy parameters from option_defs_us array */
+ for (i = 0; i < num_options; i++)
+ {
+ const char *key = option_defs_us[i].key;
+ const char *desc = option_defs_us[i].desc;
+ const char *default_value = option_defs_us[i].default_value;
+ struct retro_core_option_value *values = option_defs_us[i].values;
+ size_t buf_len = 3;
+ size_t default_index = 0;
+
+ values_buf[i] = NULL;
+
+ /* Skip options that are irrelevant when using the
+ * old style core options interface */
+ if (
+ (strcmp(key, "snes9x_show_advanced_av_settings") == 0)
+ )
+ continue;
+
+ if (desc)
+ {
+ size_t num_values = 0;
- /* Default value goes first */
- strcat(values_buf[i], values[default_index].value);
+ /* Determine number of values */
+ while (true)
+ {
+ if (values[num_values].value)
+ {
+ /* Check if this is the default value */
+ if (default_value)
+ if (strcmp(values[num_values].value, default_value) == 0)
+ default_index = num_values;
+
+ buf_len += strlen(values[num_values].value);
+ num_values++;
+ }
+ else
+ break;
+ }
- /* Add remaining values */
- for (j = 0; j < num_values; j++)
+ /* Build values string */
+ if (num_values > 0)
{
- if (j != default_index)
+ buf_len += num_values - 1;
+ buf_len += strlen(desc);
+
+ values_buf[i] = (char *)calloc(buf_len, sizeof(char));
+ if (!values_buf[i])
+ goto error;
+
+ strcpy(values_buf[i], desc);
+ strcat(values_buf[i], "; ");
+
+ /* Default value goes first */
+ strcat(values_buf[i], values[default_index].value);
+
+ /* Add remaining values */
+ for (j = 0; j < num_values; j++)
{
- strcat(values_buf[i], "|");
- strcat(values_buf[i], values[j].value);
+ if (j != default_index)
+ {
+ strcat(values_buf[i], "|");
+ strcat(values_buf[i], values[j].value);
+ }
}
}
}
+
+ variables[option_index].key = key;
+ variables[option_index].value = values_buf[i];
+ option_index++;
}
- variables[i].key = key;
- variables[i].value = values_buf[i];
+ /* Set variables */
+ environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
}
- /* Set variables */
- environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
-
error:
-
/* Clean up */
+
+ if (option_v1_defs_us)
+ {
+ free(option_v1_defs_us);
+ option_v1_defs_us = NULL;
+ }
+
+#ifndef HAVE_NO_LANGEXTRA
+ if (option_v1_defs_intl)
+ {
+ free(option_v1_defs_intl);
+ option_v1_defs_intl = NULL;
+ }
+#endif
+
if (values_buf)
{
for (i = 0; i < num_options; i++)
@@ -324,3 +486,5 @@ error:
#endif
#endif
+
+#endif