Merge pull request #11072 from jdgleaver/core-options-tweaks

Core option improvements
This commit is contained in:
Autechre 2020-07-24 19:12:19 +02:00 committed by GitHub
commit 80f978b683
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 184 additions and 63 deletions

View File

@ -1325,28 +1325,18 @@ static void menu_action_setting_disp_set_label_core_options(
char *s2, size_t len2)
{
core_option_manager_t *coreopts = NULL;
const char *core_opt = NULL;
const char *coreopt_label = NULL;
*s = '\0';
*w = 19;
if (rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts))
{
core_opt = core_option_manager_get_val_label(coreopts,
coreopt_label = core_option_manager_get_val_label(coreopts,
type - MENU_SETTINGS_CORE_OPTION_START);
strlcpy(s, "", len);
if (core_opt)
{
if (string_is_equal(core_opt,
msg_hash_to_str(MENU_ENUM_LABEL_ENABLED)))
core_opt = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON);
else if (string_is_equal(core_opt,
msg_hash_to_str(MENU_ENUM_LABEL_DISABLED)))
core_opt = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF);
strlcpy(s, core_opt, len);
}
if (!string_is_empty(coreopt_label))
strlcpy(s, coreopt_label, len);
}
strlcpy(s2, path, len2);

View File

@ -3440,17 +3440,77 @@ static int action_ok_audio_run(const char *path,
int action_ok_core_option_dropdown_list(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
char core_option_lbl[256];
char core_option_idx[256];
snprintf(core_option_lbl, sizeof(core_option_lbl),
"core_option_%d", (int)idx);
snprintf(core_option_idx, sizeof(core_option_idx), "%d",
type);
core_option_manager_t *coreopts = NULL;
struct core_option *option = NULL;
const char *value_label_0 = NULL;
const char *value_label_1 = NULL;
size_t option_index;
char option_path_str[256];
char option_lbl_str[256];
option_path_str[0] = '\0';
option_lbl_str[0] = '\0';
/* Boolean options are toggled directly,
* without the use of a drop-down list */
/* > Get current option index */
if (type < MENU_SETTINGS_CORE_OPTION_START)
goto push_dropdown_list;
option_index = type - MENU_SETTINGS_CORE_OPTION_START;
/* > Get core options struct */
if (!rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts) ||
(option_index >= coreopts->size))
goto push_dropdown_list;
/* > Get current option, and check whether
* it has exactly 2 values (i.e. on/off) */
option = (struct core_option*)&coreopts->opts[option_index];
if (!option ||
(option->vals->size != 2) ||
((option->index != 0) &&
(option->index != 1)))
goto push_dropdown_list;
/* > Check whether option values correspond
* to a boolean toggle */
value_label_0 = option->val_labels->elems[0].data;
value_label_1 = option->val_labels->elems[1].data;
if (string_is_empty(value_label_0) ||
string_is_empty(value_label_1) ||
!((string_is_equal(value_label_0, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)) &&
string_is_equal(value_label_1, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))) ||
(string_is_equal(value_label_0, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) &&
string_is_equal(value_label_1, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)))))
goto push_dropdown_list;
/* > Update value and return */
core_option_manager_set_val(coreopts, option_index,
(option->index == 0) ? 1 : 0);
return 0;
push_dropdown_list:
/* If this option is not a boolean toggle,
* push drop-down list */
snprintf(option_path_str, sizeof(option_path_str),
"core_option_%d", (int)idx);
snprintf(option_lbl_str, sizeof(option_lbl_str),
"%d", type);
/* TODO/FIXME: This should be refactored to make
* use of a core-option-specific drop-down list,
* rather than hijacking the generic one... */
generic_action_ok_displaylist_push(
core_option_lbl, NULL,
core_option_idx, 0, idx, 0,
option_path_str, NULL,
option_lbl_str, 0, idx, 0,
ACTION_OK_DL_DROPDOWN_BOX_LIST);
return 0;
}

View File

@ -10531,25 +10531,21 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
* toggles the Quick Menu off and on again (returning
* to the Core Options menu) the menu must be refreshed
* (or undefined behaviour occurs).
* We therefore have to cache the last set menu size,
* and compare this with the new size after processing
* the current core_option_manager_t struct.
* Note: It would be 'nicer' to only refresh the menu
* if the selection marker is at an index higher than
* the new size, but we don't really have access that
* information at this stage (i.e. the selection can
* change after this function is called) */
static size_t prev_count = 0;
* To prevent the menu selection from going out of bounds,
* we therefore have to check that the current selection
* index is less than the current number of menu entries
* - if not, we reset the navigation pointer */
size_t selection = menu_navigation_get_selection();
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
if (rarch_ctl(RARCH_CTL_HAS_CORE_OPTIONS, NULL))
{
size_t opts = 0;
size_t num_opts = 0;
settings_t *settings = config_get_ptr();
bool game_specific_options = settings->bools.game_specific_options;
rarch_ctl(RARCH_CTL_GET_CORE_OPTION_SIZE, &opts);
rarch_ctl(RARCH_CTL_GET_CORE_OPTION_SIZE, &num_opts);
if (game_specific_options)
{
@ -10557,9 +10553,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
{
if (menu_entries_append_enum(info->list,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE),
MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE),
msg_hash_to_str(
MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS_CREATE),
MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS_CREATE),
MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS_CREATE,
MENU_SETTINGS_CORE_OPTION_CREATE, 0, 0))
count++;
@ -10567,29 +10563,28 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
else
if (menu_entries_append_enum(info->list,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE),
MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE),
msg_hash_to_str(
MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS_IN_USE),
MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS_IN_USE),
MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS_IN_USE,
MENU_SETTINGS_CORE_OPTION_CREATE, 0, 0))
count++;
}
if (opts != 0)
if (num_opts != 0)
{
core_option_manager_t *coreopts = NULL;
rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts);
for (i = 0; i < opts; i++)
if (rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts))
{
if (core_option_manager_get_visible(coreopts, i))
for (i = 0; i < num_opts; i++)
{
menu_entries_append_enum(info->list,
core_option_manager_get_desc(coreopts, i), "",
MENU_ENUM_LABEL_CORE_OPTION_ENTRY,
(unsigned)(MENU_SETTINGS_CORE_OPTION_START + i), 0, 0);
count++;
if (core_option_manager_get_visible(coreopts, i))
if (menu_entries_append_enum(info->list,
core_option_manager_get_desc(coreopts, i), "",
MENU_ENUM_LABEL_CORE_OPTION_ENTRY,
(unsigned)(MENU_SETTINGS_CORE_OPTION_START + i), 0, 0))
count++;
}
}
}
@ -10602,11 +10597,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
MENU_ENUM_LABEL_NO_CORE_OPTIONS_AVAILABLE,
MENU_SETTINGS_CORE_OPTION_NONE, 0, 0);
if (count != prev_count)
if (selection >= count)
{
info->need_refresh = true;
info->need_navigation_clear = true;
prev_count = count;
}
info->need_push = true;
}

View File

@ -17354,11 +17354,64 @@ int main(int argc, char *argv[])
#endif
/* CORE OPTIONS */
static const char *core_option_manager_parse_value_label(
const char *value, const char *value_label)
{
/* 'value_label' may be NULL */
const char *label = string_is_empty(value_label) ?
value : value_label;
if (string_is_empty(label))
return NULL;
/* Any label starting with a digit (or +/-)
* cannot be a boolean string, and requires
* no further processing */
if (isdigit((unsigned char)*label) ||
(*label == '+') ||
(*label == '-'))
return label;
/* Core devs have a habit of using arbitrary
* strings to label boolean values (i.e. enabled,
* Enabled, on, On, ON, true, True, TRUE, disabled,
* Disabled, off, Off, OFF, false, False, FALSE).
* These should all be converted to standard ON/OFF
* strings
* > Note: We require some duplication here
* (e.g. MENU_ENUM_LABEL_ENABLED *and*
* MENU_ENUM_LABEL_VALUE_ENABLED) in order
* to match both localised and non-localised
* strings. This function is not performance
* critical, so these extra comparisons do
* no harm */
if (string_is_equal_noncase(label, msg_hash_to_str(MENU_ENUM_LABEL_ENABLED)) ||
string_is_equal_noncase(label, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ENABLED)) ||
string_is_equal_noncase(label, "enable") ||
string_is_equal_noncase(label, "on") ||
string_is_equal_noncase(label, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)) ||
string_is_equal_noncase(label, "true") ||
string_is_equal_noncase(label, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_TRUE)))
label = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON);
else if (string_is_equal_noncase(label, msg_hash_to_str(MENU_ENUM_LABEL_DISABLED)) ||
string_is_equal_noncase(label, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED)) ||
string_is_equal_noncase(label, "disable") ||
string_is_equal_noncase(label, "off") ||
string_is_equal_noncase(label, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) ||
string_is_equal_noncase(label, "false") ||
string_is_equal_noncase(label, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FALSE)))
label = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF);
return label;
}
static bool core_option_manager_parse_variable(
core_option_manager_t *opt, size_t idx,
const struct retro_variable *var,
config_file_t *config_src)
{
size_t i;
union string_list_elem_attr attr;
const char *val_start = NULL;
char *value = NULL;
char *desc_end = NULL;
@ -17391,13 +17444,30 @@ static bool core_option_manager_parse_variable(
if (!option->vals)
goto error;
/* Legacy core option interface has no concept of
* value labels - use actual values for display purposes */
option->val_labels = string_list_clone(option->vals);
/* Legacy core option interface has no concept
* of value labels
* > Use actual values for display purposes */
attr.i = 0;
option->val_labels = string_list_new();
if (!option->val_labels)
goto error;
/* > Loop over values and 'extract' labels */
for (i = 0; i < option->vals->size; i++)
{
const char *value = option->vals->elems[i].data;
const char *value_label = core_option_manager_parse_value_label(
value, NULL);
/* Redundant safely check... */
value_label = string_is_empty(value_label) ?
value : value_label;
/* Append value label string */
string_list_append(option->val_labels, value_label, attr);
}
/* Legacy core option interface always uses first
* defined value as the default */
option->default_index = 0;
@ -17411,8 +17481,6 @@ static bool core_option_manager_parse_variable(
/* Set current config value */
if (entry && !string_is_empty(entry->value))
{
size_t i;
for (i = 0; i < option->vals->size; i++)
{
if (string_is_equal(option->vals->elems[i].data, entry->value))
@ -17475,26 +17543,35 @@ static bool core_option_manager_parse_option(
if (!option->vals || !option->val_labels)
return false;
/* Initialse default value */
/* Initialise default value */
option->default_index = 0;
option->index = 0;
/* Extract value/label pairs */
for (i = 0; i < num_vals; i++)
{
/* We know that 'value' is valid */
string_list_append(option->vals, values[i].value, attr);
const char *value = values[i].value;
const char *value_label = values[i].label;
/* Value 'label' may be NULL */
if (!string_is_empty(values[i].label))
string_list_append(option->val_labels, values[i].label, attr);
else
string_list_append(option->val_labels, values[i].value, attr);
/* Append value string
* > We know that 'value' is always valid */
string_list_append(option->vals, value, attr);
/* Value label requires additional processing */
value_label = core_option_manager_parse_value_label(
value, value_label);
/* > Redundant safely check... */
value_label = string_is_empty(value_label) ?
value : value_label;
/* Append value label string */
string_list_append(option->val_labels, value_label, attr);
/* Check whether this value is the default setting */
if (!string_is_empty(option_def->default_value))
{
if (string_is_equal(option_def->default_value, values[i].value))
if (string_is_equal(option_def->default_value, value))
{
option->default_index = i;
option->index = i;