mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-26 04:36:01 +00:00
736 lines
34 KiB
C
736 lines
34 KiB
C
/* RetroArch - A frontend for libretro.
|
|
* Copyright (C) 2013-2014 - Jason Fetters
|
|
*
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "settings_data.h"
|
|
#include "file_path.h"
|
|
#include "input/input_common.h"
|
|
#include "config.def.h"
|
|
|
|
#define ENFORCE_RANGE(setting, type) \
|
|
{ \
|
|
if (setting->flags & SD_FLAG_HAS_RANGE) \
|
|
{ \
|
|
if (*setting->value.type < setting->min) \
|
|
*setting->value.type = setting->min; \
|
|
if (*setting->value.type > setting->max) \
|
|
*setting->value.type = setting->max; \
|
|
} \
|
|
}
|
|
|
|
// HACK
|
|
struct settings fake_settings;
|
|
struct global fake_extern;
|
|
|
|
void setting_data_load_current(void)
|
|
{
|
|
memcpy(&fake_settings, &g_settings, sizeof(struct settings));
|
|
memcpy(&fake_extern, &g_extern, sizeof(struct global));
|
|
}
|
|
|
|
// Input
|
|
static const char* get_input_config_prefix(const rarch_setting_t* setting)
|
|
{
|
|
static char buffer[32];
|
|
snprintf(buffer, 32, "input%cplayer%d", setting->index ? '_' : '\0', setting->index);
|
|
return buffer;
|
|
}
|
|
|
|
static const char* get_input_config_key(const rarch_setting_t* setting, const char* type)
|
|
{
|
|
static char buffer[64];
|
|
snprintf(buffer, 64, "%s_%s%c%s", get_input_config_prefix(setting), setting->name, type ? '_' : '\0', type);
|
|
return buffer;
|
|
}
|
|
|
|
//FIXME - make portable
|
|
#ifdef APPLE
|
|
static const char* get_key_name(const rarch_setting_t* setting)
|
|
{
|
|
if (BINDFOR(*setting).key == RETROK_UNKNOWN)
|
|
return "nul";
|
|
|
|
uint32_t hidkey = input_translate_rk_to_keysym(BINDFOR(*setting).key);
|
|
|
|
for (int i = 0; apple_key_name_map[i].hid_id; i ++)
|
|
if (apple_key_name_map[i].hid_id == hidkey)
|
|
return apple_key_name_map[i].keyname;
|
|
|
|
return "nul";
|
|
}
|
|
#endif
|
|
|
|
|
|
static const char* get_button_name(const rarch_setting_t* setting)
|
|
{
|
|
static char buffer[32];
|
|
|
|
if (BINDFOR(*setting).joykey == NO_BTN)
|
|
return "nul";
|
|
|
|
snprintf(buffer, 32, "%lld", (long long int)(BINDFOR(*setting).joykey));
|
|
return buffer;
|
|
}
|
|
|
|
static const char* get_axis_name(const rarch_setting_t* setting)
|
|
{
|
|
static char buffer[32];
|
|
|
|
uint32_t joyaxis = BINDFOR(*setting).joyaxis;
|
|
|
|
if (AXIS_NEG_GET(joyaxis) != AXIS_DIR_NONE)
|
|
snprintf(buffer, 8, "-%d", AXIS_NEG_GET(joyaxis));
|
|
else if (AXIS_POS_GET(joyaxis) != AXIS_DIR_NONE)
|
|
snprintf(buffer, 8, "+%d", AXIS_POS_GET(joyaxis));
|
|
else
|
|
return "nul";
|
|
|
|
return buffer;
|
|
}
|
|
|
|
void setting_data_reset_setting(const rarch_setting_t* setting)
|
|
{
|
|
switch (setting->type)
|
|
{
|
|
case ST_BOOL:
|
|
*setting->value.boolean = setting->default_value.boolean;
|
|
break;
|
|
case ST_INT:
|
|
*setting->value.integer = setting->default_value.integer;
|
|
break;
|
|
case ST_UINT:
|
|
*setting->value.unsigned_integer = setting->default_value.unsigned_integer;
|
|
break;
|
|
case ST_FLOAT:
|
|
*setting->value.fraction = setting->default_value.fraction;
|
|
break;
|
|
case ST_BIND:
|
|
*setting->value.keybind = *setting->default_value.keybind;
|
|
break;
|
|
case ST_STRING:
|
|
case ST_PATH:
|
|
if (setting->default_value.string)
|
|
{
|
|
if (setting->type == ST_STRING)
|
|
strlcpy(setting->value.string, setting->default_value.string, setting->size);
|
|
else
|
|
fill_pathname_expand_special(setting->value.string, setting->default_value.string, setting->size);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (setting->change_handler)
|
|
setting->change_handler(setting);
|
|
}
|
|
|
|
void setting_data_reset(const rarch_setting_t* settings)
|
|
{
|
|
const rarch_setting_t *i;
|
|
memset(&fake_settings, 0, sizeof(fake_settings));
|
|
memset(&fake_extern, 0, sizeof(fake_extern));
|
|
|
|
for (i = settings; i->type != ST_NONE; i ++)
|
|
setting_data_reset_setting(i);
|
|
}
|
|
|
|
bool setting_data_load_config_path(const rarch_setting_t* settings, const char* path)
|
|
{
|
|
config_file_t* config = (config_file_t*)config_file_new(path);
|
|
|
|
if (config)
|
|
{
|
|
setting_data_load_config(settings, config);
|
|
config_file_free(config);
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
bool setting_data_load_config(const rarch_setting_t* settings, config_file_t* config)
|
|
{
|
|
const rarch_setting_t *i;
|
|
if (!config)
|
|
return false;
|
|
|
|
for (i = settings; i->type != ST_NONE; i ++)
|
|
{
|
|
switch (i->type)
|
|
{
|
|
case ST_BOOL:
|
|
config_get_bool (config, i->name, i->value.boolean);
|
|
break;
|
|
case ST_PATH:
|
|
config_get_path (config, i->name, i->value.string, i->size);
|
|
break;
|
|
case ST_STRING:
|
|
config_get_array (config, i->name, i->value.string, i->size);
|
|
break;
|
|
case ST_INT:
|
|
config_get_int(config, i->name, i->value.integer);
|
|
ENFORCE_RANGE(i, integer);
|
|
break;
|
|
case ST_UINT:
|
|
config_get_uint(config, i->name, i->value.unsigned_integer);
|
|
ENFORCE_RANGE(i, unsigned_integer);
|
|
break;
|
|
case ST_FLOAT:
|
|
config_get_float(config, i->name, i->value.fraction);
|
|
ENFORCE_RANGE(i, fraction);
|
|
break;
|
|
case ST_BIND:
|
|
{
|
|
const char *prefix = (const char *)get_input_config_prefix(i);
|
|
input_config_parse_key (config, prefix, i->name, i->value.keybind);
|
|
input_config_parse_joy_button(config, prefix, i->name, i->value.keybind);
|
|
input_config_parse_joy_axis (config, prefix, i->name, i->value.keybind);
|
|
}
|
|
break;
|
|
case ST_HEX:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool setting_data_save_config_path(const rarch_setting_t* settings, const char* path)
|
|
{
|
|
bool result = false;
|
|
config_file_t* config = (config_file_t*)config_file_new(path);
|
|
|
|
if (!config)
|
|
config = config_file_new(0);
|
|
|
|
setting_data_save_config(settings, config);
|
|
result = config_file_write(config, path);
|
|
config_file_free(config);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool setting_data_save_config(const rarch_setting_t* settings, config_file_t* config)
|
|
{
|
|
const rarch_setting_t *i;
|
|
if (!config)
|
|
return false;
|
|
|
|
for (i = settings; i->type != ST_NONE; i ++)
|
|
{
|
|
switch (i->type)
|
|
{
|
|
case ST_BOOL:
|
|
config_set_bool(config, i->name, *i->value.boolean);
|
|
break;
|
|
case ST_PATH:
|
|
config_set_path(config, i->name, i->value.string);
|
|
break;
|
|
case ST_STRING:
|
|
config_set_string(config, i->name, i->value.string);
|
|
break;
|
|
case ST_INT:
|
|
ENFORCE_RANGE(i, integer);
|
|
config_set_int(config, i->name, *i->value.integer);
|
|
break;
|
|
case ST_UINT:
|
|
ENFORCE_RANGE(i, unsigned_integer);
|
|
config_set_uint64(config, i->name, *i->value.unsigned_integer);
|
|
break;
|
|
case ST_FLOAT:
|
|
ENFORCE_RANGE(i, fraction);
|
|
config_set_float(config, i->name, *i->value.fraction);
|
|
break;
|
|
case ST_BIND:
|
|
//FIXME: make portable
|
|
#ifdef APPLE
|
|
config_set_string(config, get_input_config_key(i, 0 ), get_key_name(i));
|
|
#endif
|
|
config_set_string(config, get_input_config_key(i, "btn" ), get_button_name(i));
|
|
config_set_string(config, get_input_config_key(i, "axis"), get_axis_name(i));
|
|
break;
|
|
case ST_HEX:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
const rarch_setting_t* setting_data_find_setting(const rarch_setting_t* settings, const char* name)
|
|
{
|
|
const rarch_setting_t *i;
|
|
if (!name)
|
|
return 0;
|
|
|
|
for (i = settings; i->type != ST_NONE; i ++)
|
|
if (i->type <= ST_GROUP && strcmp(i->name, name) == 0)
|
|
return i;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void setting_data_set_with_string_representation(const rarch_setting_t* setting, const char* value)
|
|
{
|
|
if (!setting || !value)
|
|
return;
|
|
|
|
switch (setting->type)
|
|
{
|
|
case ST_INT:
|
|
sscanf(value, "%d", setting->value.integer);
|
|
ENFORCE_RANGE(setting, integer);
|
|
break;
|
|
case ST_UINT:
|
|
sscanf(value, "%u", setting->value.unsigned_integer);
|
|
ENFORCE_RANGE(setting, unsigned_integer);
|
|
break;
|
|
case ST_FLOAT:
|
|
sscanf(value, "%f", setting->value.fraction);
|
|
ENFORCE_RANGE(setting, fraction);
|
|
break;
|
|
case ST_PATH:
|
|
strlcpy(setting->value.string, value, setting->size);
|
|
break;
|
|
case ST_STRING:
|
|
strlcpy(setting->value.string, value, setting->size);
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
if (setting->change_handler)
|
|
setting->change_handler(setting);
|
|
}
|
|
|
|
const char* setting_data_get_string_representation(const rarch_setting_t* setting, char* buffer, size_t length)
|
|
{
|
|
if (!setting || !buffer || !length)
|
|
return "";
|
|
|
|
switch (setting->type)
|
|
{
|
|
case ST_BOOL:
|
|
snprintf(buffer, length, "%s", *setting->value.boolean ? "True" : "False");
|
|
break;
|
|
case ST_INT:
|
|
snprintf(buffer, length, "%d", *setting->value.integer);
|
|
break;
|
|
case ST_UINT:
|
|
snprintf(buffer, length, "%u", *setting->value.unsigned_integer);
|
|
break;
|
|
case ST_FLOAT:
|
|
snprintf(buffer, length, "%f", *setting->value.fraction);
|
|
break;
|
|
case ST_PATH:
|
|
strlcpy(buffer, setting->value.string, length);
|
|
break;
|
|
case ST_STRING:
|
|
strlcpy(buffer, setting->value.string, length);
|
|
break;
|
|
case ST_BIND:
|
|
#ifdef APPLE
|
|
snprintf(buffer, length, "[KB:%s] [JS:%s] [AX:%s]", get_key_name(setting), get_button_name(setting), get_axis_name(setting));
|
|
#endif
|
|
break;
|
|
default:
|
|
return "";
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
|
|
rarch_setting_t setting_data_group_setting(enum setting_type type, const char* name)
|
|
{
|
|
rarch_setting_t result = { type, name };
|
|
return result;
|
|
}
|
|
|
|
#define DEFINE_BASIC_SETTING_TYPE(TAG, TYPE, VALUE, SETTING_TYPE) \
|
|
rarch_setting_t setting_data_##TAG##_setting(const char* name, const char* description, TYPE* target, TYPE default_value) \
|
|
{ \
|
|
rarch_setting_t result = { SETTING_TYPE, name, sizeof(TYPE), description }; \
|
|
result.value.VALUE = target; \
|
|
result.default_value.VALUE = default_value; \
|
|
return result; \
|
|
}
|
|
|
|
DEFINE_BASIC_SETTING_TYPE(bool, bool, boolean, ST_BOOL)
|
|
DEFINE_BASIC_SETTING_TYPE(int, int, integer, ST_INT)
|
|
DEFINE_BASIC_SETTING_TYPE(uint, unsigned int, unsigned_integer, ST_UINT)
|
|
DEFINE_BASIC_SETTING_TYPE(float, float, fraction, ST_FLOAT)
|
|
|
|
rarch_setting_t setting_data_string_setting(enum setting_type type,
|
|
const char* name, const char* description, char* target,
|
|
unsigned size, const char* default_value)
|
|
{
|
|
rarch_setting_t result = { type, name, size, description };
|
|
result.value.string = target;
|
|
result.default_value.string = default_value;
|
|
return result;
|
|
}
|
|
|
|
rarch_setting_t setting_data_bind_setting(const char* name,
|
|
const char* description, struct retro_keybind* target,
|
|
uint32_t index, const struct retro_keybind* default_value)
|
|
{
|
|
rarch_setting_t result = { ST_BIND, name, 0, description };
|
|
result.value.keybind = target;
|
|
result.default_value.keybind = default_value;
|
|
result.index = index;
|
|
return result;
|
|
}
|
|
|
|
|
|
#ifdef IOS
|
|
static const uint32_t features = SD_FEATURE_SHADERS;
|
|
#elif defined(OSX)
|
|
static const uint32_t features = SD_FEATURE_VIDEO_MODE | SD_FEATURE_SHADERS |
|
|
SD_FEATURE_VSYNC | SD_FEATURE_AUDIO_DEVICE;
|
|
#else
|
|
static const uint32_t features = SD_FEATURE_VSYNC;
|
|
#endif
|
|
|
|
#define g_settings fake_settings
|
|
#define g_extern fake_extern
|
|
|
|
#define DEFAULT_ME_YO 0
|
|
#define NEXT (list[index++])
|
|
#define WITH_FEATURE(FTS) if (!FTS || features & FTS)
|
|
#define START_GROUP(NAME) { NEXT = setting_data_group_setting (ST_GROUP, NAME);
|
|
#define END_GROUP() NEXT = setting_data_group_setting (ST_END_GROUP, 0); }
|
|
#define START_SUB_GROUP(NAME) { NEXT = setting_data_group_setting (ST_SUB_GROUP, NAME);
|
|
#define END_SUB_GROUP() NEXT = setting_data_group_setting (ST_END_SUB_GROUP, 0); }
|
|
#define CONFIG_BOOL(TARGET, NAME, SHORT, DEF) NEXT = setting_data_bool_setting (NAME, SHORT, &TARGET, DEF);
|
|
#define CONFIG_INT(TARGET, NAME, SHORT, DEF) NEXT = setting_data_int_setting (NAME, SHORT, &TARGET, DEF);
|
|
#define CONFIG_UINT(TARGET, NAME, SHORT, DEF) NEXT = setting_data_uint_setting (NAME, SHORT, &TARGET, DEF);
|
|
#define CONFIG_FLOAT(TARGET, NAME, SHORT, DEF) NEXT = setting_data_float_setting (NAME, SHORT, &TARGET, DEF);
|
|
#define CONFIG_PATH(TARGET, NAME, SHORT, DEF) NEXT = setting_data_string_setting(ST_PATH, NAME, SHORT, TARGET, sizeof(TARGET), DEF);
|
|
#define CONFIG_STRING(TARGET, NAME, SHORT, DEF) NEXT = setting_data_string_setting(ST_STRING, NAME, SHORT, TARGET, sizeof(TARGET), DEF);
|
|
#define CONFIG_HEX(TARGET, NAME, SHORT)
|
|
#define CONFIG_BIND(TARGET, PLAYER, NAME, SHORT, DEF) \
|
|
NEXT = setting_data_bind_setting (NAME, SHORT, &TARGET, PLAYER, DEF);
|
|
|
|
#define WITH_FLAGS(FLAGS) (list[index - 1]).flags |= FLAGS;
|
|
|
|
#define WITH_RANGE(MIN, MAX) \
|
|
(list[index - 1]).min = MIN; \
|
|
(list[index - 1]).max = MAX; \
|
|
WITH_FLAGS(SD_FLAG_HAS_RANGE)
|
|
|
|
#define WITH_VALUES(VALUES) (list[index -1]).values = VALUES;
|
|
|
|
const rarch_setting_t* setting_data_get_list(void)
|
|
{
|
|
int i, player, index;
|
|
static rarch_setting_t list[512];
|
|
static bool initialized = false;
|
|
|
|
if (!initialized)
|
|
{
|
|
for (i = 0; i < 512; i++)
|
|
{
|
|
list[i].type = ST_NONE;
|
|
list[i].name = NULL;
|
|
list[i].size = 0;
|
|
list[i].short_description = NULL;
|
|
list[i].index = 0;
|
|
list[i].min = 0;
|
|
list[i].max = 0;
|
|
list[i].values = NULL;
|
|
list[i].flags = 0;
|
|
}
|
|
|
|
initialized = true;
|
|
}
|
|
|
|
if (list[0].type == ST_NONE)
|
|
{
|
|
index = 0;
|
|
|
|
/***********/
|
|
/* DRIVERS */
|
|
/***********/
|
|
WITH_FEATURE(SD_FEATURE_MULTI_DRIVER) START_GROUP("Drivers")
|
|
START_SUB_GROUP("Drivers")
|
|
CONFIG_STRING(g_settings.video.driver, "video_driver", "Video Driver", config_get_default_video())
|
|
#ifdef HAVE_OPENGL
|
|
CONFIG_STRING(g_settings.video.gl_context, "video_gl_context", "OpenGL Driver", "")
|
|
#endif
|
|
CONFIG_STRING(g_settings.audio.driver, "audio_driver", "Audio Driver", config_get_default_audio())
|
|
CONFIG_STRING(g_settings.input.driver, "input_driver", "Input Driver", config_get_default_input())
|
|
#ifdef HAVE_CAMERA
|
|
CONFIG_STRING(g_settings.camera.device, "camera_device", "Camera Driver", config_get_default_camera())
|
|
#endif
|
|
#ifdef HAVE_LOCATION
|
|
CONFIG_STRING(g_settings.location.driver, "location_driver", "Location Driver", config_get_default_location())
|
|
#endif
|
|
CONFIG_STRING(g_settings.input.joypad_driver, "input_joypad_driver", "Joypad Driver", "")
|
|
CONFIG_STRING(g_settings.input.keyboard_layout, "input_keyboard_layout", "Keyboard Layout", DEFAULT_ME_YO)
|
|
|
|
END_SUB_GROUP()
|
|
END_GROUP()
|
|
|
|
/*********/
|
|
/* PATHS */
|
|
/*********/
|
|
START_GROUP("Paths")
|
|
START_SUB_GROUP("Paths")
|
|
#ifdef HAVE_MENU
|
|
CONFIG_PATH(g_settings.rgui_content_directory, "rgui_browser_directory", "Content Directory", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR)
|
|
CONFIG_PATH(g_settings.assets_directory, "assets_directory", "Assets Directory", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR)
|
|
CONFIG_PATH(g_settings.rgui_config_directory, "rgui_config_directory", "Config Directory", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR)
|
|
CONFIG_BOOL(g_settings.rgui_show_start_screen, "rgui_show_start_screen", "Show Start Screen", rgui_show_start_screen)
|
|
#endif
|
|
CONFIG_PATH(g_settings.libretro, "libretro_path", "Libretro Path", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY)
|
|
CONFIG_PATH(g_settings.libretro_info_path, "libretro_info_path", "Core Info Directory", default_libretro_info_path) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR)
|
|
CONFIG_PATH(g_settings.core_options_path, "core_options_path", "Core Options Path", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY)
|
|
CONFIG_PATH(g_settings.cheat_database, "cheat_database_path", "Cheat Database", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY)
|
|
CONFIG_PATH(g_settings.cheat_settings_path, "cheat_settings_path", "Cheat Settings", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY)
|
|
CONFIG_PATH(g_settings.game_history_path, "game_history_path", "Content History Path", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY)
|
|
CONFIG_UINT(g_settings.game_history_size, "game_history_size", "Content History Size", game_history_size)
|
|
|
|
|
|
#ifdef HAVE_OVERLAY
|
|
CONFIG_PATH(g_extern.overlay_dir, "overlay_directory", "Overlay Directory", default_overlay_dir) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR)
|
|
#endif
|
|
CONFIG_PATH(g_settings.screenshot_directory, "screenshot_directory", "Screenshot Directory", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR)
|
|
|
|
// savefile_directory
|
|
// savestate_directory
|
|
// system_directory
|
|
END_SUB_GROUP()
|
|
END_GROUP()
|
|
|
|
|
|
/*************/
|
|
/* EMULATION */
|
|
/*************/
|
|
START_GROUP("Emulation")
|
|
START_SUB_GROUP("Emulation")
|
|
CONFIG_BOOL(g_settings.pause_nonactive, "pause_nonactive", "Pause when inactive", pause_nonactive)
|
|
CONFIG_BOOL(g_settings.rewind_enable, "rewind_enable", "Rewind", rewind_enable)
|
|
//CONFIG_INT(g_settings.rewind_buffer_size, "rewind_buffer_size", "Rewind Buffer Size", rewind_buffer_size) WITH_SCALE(1000000)
|
|
CONFIG_UINT(g_settings.rewind_granularity, "rewind_granularity", "Rewind Granularity", rewind_granularity)
|
|
CONFIG_FLOAT(g_settings.slowmotion_ratio, "slowmotion_ratio", "Slow Motion Ratio", slowmotion_ratio) WITH_RANGE(0, 1)
|
|
CONFIG_FLOAT(g_settings.fastforward_ratio, "fastforward_ratio", "Fast Forward Ratio", fastforward_ratio)
|
|
CONFIG_BOOL(g_settings.fps_show, "fps_show", "Show Framerate", DEFAULT_ME_YO)
|
|
END_SUB_GROUP()
|
|
|
|
START_SUB_GROUP("Saves")
|
|
CONFIG_UINT(g_settings.autosave_interval, "autosave_interval", "Autosave Interval", autosave_interval)
|
|
CONFIG_BOOL(g_settings.block_sram_overwrite, "block_sram_overwrite", "Block SRAM overwrite", block_sram_overwrite)
|
|
CONFIG_BOOL(g_settings.savestate_auto_index, "savestate_auto_index", "Save State Auto Index", savestate_auto_index)
|
|
CONFIG_BOOL(g_settings.savestate_auto_save, "savestate_auto_save", "Auto Save State", savestate_auto_save)
|
|
CONFIG_BOOL(g_settings.savestate_auto_load, "savestate_auto_load", "Auto Load State", savestate_auto_load)
|
|
CONFIG_INT(g_extern.state_slot, "state_slot", "State Slot", 0)
|
|
END_SUB_GROUP()
|
|
END_GROUP()
|
|
|
|
/*********/
|
|
/* VIDEO */
|
|
/*********/
|
|
START_GROUP("Video")
|
|
WITH_FEATURE(SD_FEATURE_VIDEO_MODE) START_SUB_GROUP("Monitor")
|
|
CONFIG_UINT(g_settings.video.monitor_index, "video_monitor_index", "Monitor Index", monitor_index)
|
|
CONFIG_BOOL(g_settings.video.fullscreen, "video_fullscreen", "Use Fullscreen mode", fullscreen)
|
|
CONFIG_BOOL(g_settings.video.windowed_fullscreen, "video_windowed_fullscreen", "Windowed Fullscreen Mode", windowed_fullscreen)
|
|
CONFIG_UINT(g_settings.video.fullscreen_x, "video_fullscreen_x", "Fullscreen Width", fullscreen_x)
|
|
CONFIG_UINT(g_settings.video.fullscreen_y, "video_fullscreen_y", "Fullscreen Height", fullscreen_y)
|
|
CONFIG_FLOAT(g_settings.video.refresh_rate, "video_refresh_rate", "Refresh Rate", refresh_rate)
|
|
END_SUB_GROUP()
|
|
|
|
/* Video: Window Manager */
|
|
WITH_FEATURE(SD_FEATURE_WINDOW_MANAGER) START_SUB_GROUP("Window Manager")
|
|
CONFIG_BOOL(g_settings.video.disable_composition, "video_disable_composition", "Disable Window Composition", disable_composition)
|
|
END_SUB_GROUP()
|
|
|
|
START_SUB_GROUP("Aspect")
|
|
CONFIG_BOOL(g_settings.video.force_aspect, "video_force_aspect", "Force aspect ratio", force_aspect)
|
|
CONFIG_FLOAT(g_settings.video.aspect_ratio, "video_aspect_ratio", "Aspect Ratio", aspect_ratio)
|
|
CONFIG_BOOL(g_settings.video.aspect_ratio_auto, "video_aspect_ratio_auto", "Use Auto Aspect Ratio", aspect_ratio_auto)
|
|
CONFIG_UINT(g_settings.video.aspect_ratio_idx, "aspect_ratio_index", "Aspect Ratio Index", aspect_ratio_idx)
|
|
END_SUB_GROUP()
|
|
|
|
START_SUB_GROUP("Scaling")
|
|
CONFIG_FLOAT(g_settings.video.xscale, "video_xscale", "X Scale", xscale)
|
|
CONFIG_FLOAT(g_settings.video.yscale, "video_yscale", "Y Scale", yscale)
|
|
CONFIG_BOOL(g_settings.video.scale_integer, "video_scale_integer", "Integer Scale", scale_integer)
|
|
|
|
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.x, "custom_viewport_x", "Custom Viewport X", 0)
|
|
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.y, "custom_viewport_y", "Custom Viewport Y", 0)
|
|
CONFIG_UINT(g_extern.console.screen.viewports.custom_vp.width, "custom_viewport_width", "Custom Viewport Width", 0)
|
|
CONFIG_UINT(g_extern.console.screen.viewports.custom_vp.height, "custom_viewport_height", "Custom Viewport Height", 0)
|
|
|
|
CONFIG_BOOL(g_settings.video.smooth, "video_smooth", "Use bilinear filtering", video_smooth)
|
|
CONFIG_UINT(g_settings.video.rotation, "video_rotation", "Rotation", DEFAULT_ME_YO)
|
|
END_SUB_GROUP()
|
|
|
|
WITH_FEATURE(SD_FEATURE_SHADERS) START_SUB_GROUP("Shader")
|
|
CONFIG_BOOL(g_settings.video.shader_enable, "video_shader_enable", "Enable Shaders", shader_enable)
|
|
CONFIG_PATH(g_settings.video.shader_dir, "video_shader_dir", "Shader Directory", default_shader_dir) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR)
|
|
CONFIG_PATH(g_settings.video.shader_path, "video_shader", "Shader", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY)
|
|
END_SUB_GROUP()
|
|
|
|
WITH_FEATURE(SD_FEATURE_VSYNC) START_SUB_GROUP("Sync")
|
|
CONFIG_BOOL(g_settings.video.threaded, "video_threaded", "Threaded Video", video_threaded)
|
|
CONFIG_BOOL(g_settings.video.vsync, "video_vsync", "VSync", vsync)
|
|
CONFIG_UINT(g_settings.video.swap_interval, "video_swap_interval", "VSync Swap Interval", swap_interval) WITH_RANGE(1, 4)
|
|
CONFIG_BOOL(g_settings.video.hard_sync, "video_hard_sync", "Hard GPU Sync", hard_sync)
|
|
CONFIG_UINT(g_settings.video.hard_sync_frames, "video_hard_sync_frames", "Hard GPU Sync Frames", hard_sync_frames) WITH_RANGE(0, 3)
|
|
CONFIG_BOOL(g_settings.video.black_frame_insertion,"video_black_frame_insertion","Black Frame Insertion", black_frame_insertion)
|
|
END_SUB_GROUP()
|
|
|
|
START_SUB_GROUP("Misc")
|
|
CONFIG_BOOL(g_settings.video.post_filter_record, "video_post_filter_record", "Post filter record", post_filter_record)
|
|
CONFIG_BOOL(g_settings.video.gpu_record, "video_gpu_record", "GPU Record", gpu_record)
|
|
CONFIG_BOOL(g_settings.video.gpu_screenshot, "video_gpu_screenshot", "GPU Screenshot", gpu_screenshot)
|
|
CONFIG_BOOL(g_settings.video.allow_rotate, "video_allow_rotate", "Allow rotation", allow_rotate)
|
|
CONFIG_BOOL(g_settings.video.crop_overscan, "video_crop_overscan", "Crop Overscan (reload)", crop_overscan)
|
|
|
|
CONFIG_PATH(g_settings.video.filter_path, "video_filter", "Software filter", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY)
|
|
END_SUB_GROUP()
|
|
|
|
START_SUB_GROUP("Messages")
|
|
CONFIG_PATH(g_settings.video.font_path, "video_font_path", "Font Path", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY)
|
|
CONFIG_FLOAT(g_settings.video.font_size, "video_font_size", "OSD Font Size", font_size)
|
|
CONFIG_BOOL(g_settings.video.font_enable, "video_font_enable", "OSD Font Enable", font_enable)
|
|
CONFIG_FLOAT(g_settings.video.msg_pos_x, "video_message_pos_x", "Message X Position", message_pos_offset_x)
|
|
CONFIG_FLOAT(g_settings.video.msg_pos_y, "video_message_pos_y", "Message Y Position", message_pos_offset_y)
|
|
/* message color */
|
|
END_SUB_GROUP()
|
|
END_GROUP()
|
|
|
|
/*********/
|
|
/* AUDIO */
|
|
/*********/
|
|
START_GROUP("Audio")
|
|
START_SUB_GROUP("State")
|
|
CONFIG_BOOL(g_settings.audio.enable, "audio_enable", "Audio Enable", audio_enable)
|
|
CONFIG_BOOL(g_extern.audio_data.mute, "audio_mute", "Audio Mute", DEFAULT_ME_YO)
|
|
CONFIG_FLOAT(g_settings.audio.volume, "audio_volume", "Volume Level", audio_volume)
|
|
END_SUB_GROUP()
|
|
|
|
START_SUB_GROUP("Sync")
|
|
CONFIG_BOOL(g_settings.audio.sync, "audio_sync", "Enable Sync", audio_sync)
|
|
CONFIG_UINT(g_settings.audio.latency, "audio_latency", "Latency", out_latency)
|
|
CONFIG_BOOL(g_settings.audio.rate_control, "audio_rate_control", "Enable Rate Control", rate_control)
|
|
CONFIG_FLOAT(g_settings.audio.rate_control_delta, "audio_rate_control_delta", "Rate Control Delta", rate_control_delta)
|
|
CONFIG_UINT(g_settings.audio.block_frames, "audio_block_frames", "Block Frames", DEFAULT_ME_YO)
|
|
END_SUB_GROUP()
|
|
|
|
WITH_FEATURE(SD_FEATURE_AUDIO_DEVICE) START_SUB_GROUP("Misc")
|
|
CONFIG_STRING(g_settings.audio.device, "audio_device", "Device", DEFAULT_ME_YO)
|
|
CONFIG_UINT(g_settings.audio.out_rate, "audio_out_rate", "Ouput Rate", out_rate)
|
|
CONFIG_PATH(g_settings.audio.dsp_plugin, "audio_dsp_plugin", "DSP Plugin", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY)
|
|
END_SUB_GROUP()
|
|
END_GROUP()
|
|
|
|
/*********/
|
|
/* INPUT */
|
|
/*********/
|
|
START_GROUP("Input")
|
|
START_SUB_GROUP("Input")
|
|
CONFIG_BOOL(g_settings.input.autodetect_enable, "input_autodetect_enable", "Autodetect Enable", input_autodetect_enable)
|
|
CONFIG_PATH(g_settings.input.autoconfig_dir, "joypad_autoconfig_dir", "Joypad Autoconfig Directory",DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR)
|
|
END_SUB_GROUP()
|
|
|
|
START_SUB_GROUP("Joypad Mapping")
|
|
//TODO: input_libretro_device_p%u
|
|
CONFIG_INT(g_settings.input.joypad_map[0], "input_player1_joypad_index", "Player 1 Pad Index", 0)
|
|
CONFIG_INT(g_settings.input.joypad_map[1], "input_player2_joypad_index", "Player 2 Pad Index", 1)
|
|
CONFIG_INT(g_settings.input.joypad_map[2], "input_player3_joypad_index", "Player 3 Pad Index", 2)
|
|
CONFIG_INT(g_settings.input.joypad_map[3], "input_player4_joypad_index", "Player 4 Pad Index", 3)
|
|
CONFIG_INT(g_settings.input.joypad_map[4], "input_player5_joypad_index", "Player 5 Pad Index", 4)
|
|
END_SUB_GROUP()
|
|
|
|
START_SUB_GROUP("Turbo/Deadzone")
|
|
CONFIG_FLOAT(g_settings.input.axis_threshold, "input_axis_threshold", "Axis Deadzone", axis_threshold)
|
|
CONFIG_UINT(g_settings.input.turbo_period, "input_turbo_period", "Turbo Period", turbo_period)
|
|
CONFIG_UINT(g_settings.input.turbo_duty_cycle, "input_duty_cycle", "Duty Cycle", turbo_duty_cycle)
|
|
END_SUB_GROUP()
|
|
|
|
START_SUB_GROUP("Misc")
|
|
CONFIG_BOOL(g_settings.input.netplay_client_swap_input, "netplay_client_swap_input", "Swap Netplay Input", netplay_client_swap_input)
|
|
CONFIG_BOOL(g_settings.input.debug_enable, "input_debug_enable", "Enable Input Debugging", input_debug_enable)
|
|
END_SUB_GROUP()
|
|
|
|
#ifdef HAVE_OVERLAY
|
|
START_SUB_GROUP("Overlay")
|
|
CONFIG_PATH(g_settings.input.overlay, "input_overlay", "Input Overlay", DEFAULT_ME_YO) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY) WITH_VALUES("cfg")
|
|
CONFIG_FLOAT(g_settings.input.overlay_opacity, "input_overlay_opacity", "Overlay Opacity", 0.7f) WITH_RANGE(0, 1)
|
|
CONFIG_FLOAT(g_settings.input.overlay_scale, "input_overlay_scale", "Overlay Scale", 1.0f)
|
|
END_SUB_GROUP()
|
|
#endif
|
|
|
|
#ifdef ANDROID
|
|
START_SUB_GROUP("Android")
|
|
CONFIG_UINT(g_settings.input.back_behavior, "input_back_behavior", "Back Behavior", BACK_BUTTON_QUIT)
|
|
CONFIG_UINT(g_settings.input.icade_profile[0], "input_autodetect_icade_profile_pad1", "iCade 1", DEFAULT_ME_YO)
|
|
CONFIG_UINT(g_settings.input.icade_profile[1], "input_autodetect_icade_profile_pad2", "iCade 2", DEFAULT_ME_YO)
|
|
CONFIG_UINT(g_settings.input.icade_profile[2], "input_autodetect_icade_profile_pad3", "iCade 3", DEFAULT_ME_YO)
|
|
CONFIG_UINT(g_settings.input.icade_profile[3], "input_autodetect_icade_profile_pad4", "iCade 4", DEFAULT_ME_YO)
|
|
END_SUB_GROUP()
|
|
#endif
|
|
|
|
// The second argument to config bind is 1 based for players and 0 only for meta keys
|
|
START_SUB_GROUP("Meta Keys")
|
|
for (i = 0; i != RARCH_BIND_LIST_END; i ++)
|
|
if (input_config_bind_map[i].meta)
|
|
{
|
|
const struct input_bind_map* bind = &input_config_bind_map[i];
|
|
CONFIG_BIND(g_settings.input.binds[0][i], 0, bind->base, bind->desc, &retro_keybinds_1[i])
|
|
}
|
|
END_SUB_GROUP()
|
|
|
|
for (player = 0; player < MAX_PLAYERS; player ++)
|
|
{
|
|
char buffer[32];
|
|
const struct retro_keybind* const defaults = (player == 0) ? retro_keybinds_1 : retro_keybinds_rest;
|
|
|
|
snprintf(buffer, 32, "Player %d", player + 1);
|
|
START_SUB_GROUP(strdup(buffer))
|
|
for (i = 0; i != RARCH_BIND_LIST_END; i ++)
|
|
{
|
|
if (!input_config_bind_map[i].meta)
|
|
{
|
|
const struct input_bind_map* bind = (const struct input_bind_map*)&input_config_bind_map[i];
|
|
CONFIG_BIND(g_settings.input.binds[player][i], player + 1, bind->base, bind->desc, &defaults[i])
|
|
}
|
|
}
|
|
END_SUB_GROUP()
|
|
}
|
|
END_GROUP()
|
|
|
|
/********/
|
|
/* Misc */
|
|
/********/
|
|
START_GROUP("Misc")
|
|
START_SUB_GROUP("Misc")
|
|
CONFIG_BOOL(g_extern.config_save_on_exit, "config_save_on_exit", "Configuration Save On Exit", config_save_on_exit)
|
|
CONFIG_BOOL(g_settings.network_cmd_enable, "network_cmd_enable", "Network Commands", network_cmd_enable)
|
|
//CONFIG_INT(g_settings.network_cmd_port, "network_cmd_port", "Network Command Port", network_cmd_port)
|
|
CONFIG_BOOL(g_settings.stdin_cmd_enable, "stdin_cmd_enable", "stdin command", stdin_cmd_enable)
|
|
END_SUB_GROUP()
|
|
END_GROUP()
|
|
}
|
|
|
|
return list;
|
|
}
|