picodrive-irixxxx/platform/libretro/libretro_core_options.h
bmaupin ad577afb13 Add option to change sound quality
Reducing the sound rate can make picodrive more performant on less powerful systems such as the PSP
2020-03-05 13:25:58 -05:00

425 lines
12 KiB
C

#ifndef LIBRETRO_CORE_OPTIONS_H__
#define LIBRETRO_CORE_OPTIONS_H__
#include <stdlib.h>
#include <string.h>
#include <libretro.h>
#include <retro_inline.h>
#ifndef HAVE_NO_LANGEXTRA
#include "libretro_core_options_intl.h"
#endif
/*
********************************
* VERSION: 1.3
********************************
*
* - 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
* - Added HAVE_NO_LANGEXTRA flag to disable translations
* on platforms/compilers without BOM support
* - 1.2: Use core options v1 interface when
* RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1
* (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1)
* - 1.1: Support generation of core options v0 retro_core_option_value
* arrays containing options with a single value
* - 1.0: First commit
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
********************************
* Core Option Definitions
********************************
*/
/* RETRO_LANGUAGE_ENGLISH */
/* Default language:
* - All other languages must include the same keys and values
* - Will be used as a fallback in the event that frontend language
* is not available
* - Will be used as a fallback for any missing entries in
* frontend language definition */
struct retro_core_option_definition option_defs_us[] = {
{
"picodrive_input1",
"Input device 1",
"Choose which kind of controller is plugged in slot 1.",
{
{ "3 button pad", NULL },
{ "6 button pad", NULL },
{ "None", NULL },
{ NULL, NULL },
},
"3 button pad"
},
{
"picodrive_input2",
"Input device 2",
"Choose which kind of controller is plugged in slot 2.",
{
{ "3 button pad", NULL },
{ "6 button pad", NULL },
{ "None", NULL },
{ NULL, NULL },
},
"3 button pad"
},
{
"picodrive_sprlim",
"No sprite limit",
"Enable this to remove the sprite limit.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL },
},
"disabled"
},
{
"picodrive_ramcart",
"MegaCD RAM cart",
"Emulate a MegaCD RAM cart, used for save game data.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL },
},
"disabled"
},
{
"picodrive_region",
"Region",
"Force a specific region.",
{
{ "Auto", NULL },
{ "Japan NTSC", NULL },
{ "Japan PAL", NULL },
{ "US", NULL },
{ "Europe", NULL },
{ NULL, NULL },
},
"Auto"
},
{
"picodrive_aspect",
"Core-provided aspect ratio",
"Choose the core-provided aspect ratio. RetroArch's aspect ratio must be set to Core provided in the Video settings.",
{
{ "PAR", NULL },
{ "4/3", NULL },
{ "CRT", NULL },
{ NULL, NULL },
},
"PAR"
},
{
"picodrive_overscan",
"Show Overscan",
"Crop out the potentially random glitchy video output that would have been hidden by the bezel around the edge of a standard-definition television screen.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL },
},
"disabled"
},
{
"picodrive_overclk68k",
"68K Overclock",
"Overclock the emulated 68K chip.",
{
{ "disabled", NULL },
{ "+25%", NULL },
{ "+50%", NULL },
{ "+75%", NULL },
{ "+100%", NULL },
{ "+200%", NULL },
{ "+400%", NULL },
{ NULL, NULL },
},
"disabled"
},
#ifdef DRC_SH2
{
"picodrive_drc",
"Dynamic recompilers",
"Enable dynamic recompilers which help to improve performance. Less accurate than interpreter CPU cores, but much faster.",
{
{ "enabled", NULL },
{ "disabled", NULL },
{ NULL, NULL },
},
"enabled"
},
#endif
{
"picodrive_audio_filter",
"Audio filter",
"Enable a low pass audio filter to better simulate the characteristic sound of a Model 1 Genesis. This option is ignored when running Master System and PICO titles. Only the Genesis and its add-on hardware (Sega CD, 32X) employed a physical low pass filter.",
{
{ "disabled", NULL },
{ "low-pass", NULL },
{ NULL, NULL },
},
"disabled"
},
{
"picodrive_lowpass_range",
"Low-pass filter %",
"Specify the cut-off frequency of the audio low pass filter. A higher value increases the perceived 'strength' of the filter, since a wider range of the high frequency spectrum is attenuated.",
{
{ "5", NULL },
{ "10", NULL },
{ "15", NULL },
{ "20", NULL },
{ "25", NULL },
{ "30", NULL },
{ "35", NULL },
{ "40", NULL },
{ "45", NULL },
{ "50", NULL },
{ "55", NULL },
{ "60", NULL },
{ "65", NULL },
{ "70", NULL },
{ "75", NULL },
{ "80", NULL },
{ "85", NULL },
{ "90", NULL },
{ "95", NULL },
{ NULL, NULL },
},
"60"
},
#if !defined(RENDER_GSKIT_PS2)
{
"picodrive_renderer",
"Renderer",
"Fast renderer can't render any mid-frame image changes so it is useful only for some games.",
{
{ "accurate", NULL },
{ "fast", NULL },
{ NULL, NULL },
},
"accurate"
},
#endif
{
"picodrive_sound_rate",
"Sound quality",
"Sound quality (in Hz). A lower value may increase performance.",
{
{ "16000", NULL },
{ "22050", NULL },
{ "32000", NULL },
{ "44100", NULL },
{ NULL, NULL },
},
"44100"
},
{ NULL, NULL, NULL, {{0}}, NULL },
};
/*
********************************
* Language Mapping
********************************
*/
#ifndef HAVE_NO_LANGEXTRA
struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = {
option_defs_us, /* RETRO_LANGUAGE_ENGLISH */
NULL, /* RETRO_LANGUAGE_JAPANESE */
NULL, /* RETRO_LANGUAGE_FRENCH */
NULL, /* RETRO_LANGUAGE_SPANISH */
NULL, /* RETRO_LANGUAGE_GERMAN */
NULL, /* RETRO_LANGUAGE_ITALIAN */
NULL, /* RETRO_LANGUAGE_DUTCH */
NULL, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
NULL, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
NULL, /* RETRO_LANGUAGE_RUSSIAN */
NULL, /* RETRO_LANGUAGE_KOREAN */
NULL, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
NULL, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
NULL, /* RETRO_LANGUAGE_ESPERANTO */
NULL, /* RETRO_LANGUAGE_POLISH */
NULL, /* RETRO_LANGUAGE_VIETNAMESE */
NULL, /* RETRO_LANGUAGE_ARABIC */
NULL, /* RETRO_LANGUAGE_GREEK */
option_defs_tr, /* RETRO_LANGUAGE_TURKISH */
};
#endif
/*
********************************
* Functions
********************************
*/
/* Handles configuration/setting of core options.
* Should be called as early as possible - ideally inside
* retro_set_environment(), and no later than retro_load_game()
* > We place the function body in the header to avoid the
* necessity of adding more .c files (i.e. want this to
* be as painless as possible for core devs)
*/
static INLINE void libretro_set_core_options(retro_environment_t environ_cb)
{
unsigned version = 0;
if (!environ_cb)
return;
if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version >= 1))
{
#ifndef HAVE_NO_LANGEXTRA
struct retro_core_options_intl core_options_intl;
unsigned language = 0;
core_options_intl.us = option_defs_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];
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_intl);
#else
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, &option_defs_us);
#endif
}
else
{
size_t i;
size_t num_options = 0;
struct retro_variable *variables = NULL;
char **values_buf = NULL;
/* Determine number of options */
while (true)
{
if (option_defs_us[num_options].key)
num_options++;
else
break;
}
/* Allocate arrays */
variables = (struct retro_variable *)calloc(num_options + 1, sizeof(struct retro_variable));
values_buf = (char **)calloc(num_options, sizeof(char *));
if (!variables || !values_buf)
goto error;
/* 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;
if (desc)
{
size_t num_values = 0;
/* 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;
}
/* Build values string */
if (num_values > 0)
{
size_t j;
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++)
{
if (j != default_index)
{
strcat(values_buf[i], "|");
strcat(values_buf[i], values[j].value);
}
}
}
}
variables[i].key = key;
variables[i].value = values_buf[i];
}
/* Set variables */
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
error:
/* Clean up */
if (values_buf)
{
for (i = 0; i < num_options; i++)
{
if (values_buf[i])
{
free(values_buf[i]);
values_buf[i] = NULL;
}
}
free(values_buf);
values_buf = NULL;
}
if (variables)
{
free(variables);
variables = NULL;
}
}
}
#ifdef __cplusplus
}
#endif
#endif