diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 176de586f8..bc501414db 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -309,6 +309,61 @@ static unsigned input_frame(uint64_t trigger_state) return MENU_ACTION_NOOP; } +void apply_deferred_settings() +{ + rarch_setting_t *setting = driver.menu->list_settings; + bool change = false; + + for (; setting->type != ST_NONE; setting++) + { + if ((setting->type < ST_GROUP) && (setting->flags & SD_FLAG_IS_DEFERRED)) + { + switch (setting->type) + { + case ST_BOOL: + if (*setting->value.boolean != setting->original_value.boolean) + { + setting->original_value.boolean = *setting->value.boolean; + change = true; + } + break; + case ST_INT: + if (*setting->value.integer != setting->original_value.integer) + { + setting->original_value.integer = *setting->value.integer; + change = true; + } + break; + case ST_UINT: + if (*setting->value.unsigned_integer != setting->original_value.unsigned_integer) + { + setting->original_value.unsigned_integer = *setting->value.unsigned_integer; + change = true; + } + break; + case ST_FLOAT: + if (*setting->value.fraction != setting->original_value.fraction) + { + setting->original_value.fraction = *setting->value.fraction; + change = true; + } + break; + case ST_PATH: + case ST_DIR: + case ST_STRING: + case ST_BIND: + /* always run the deferred write handler */ + change = true; + break; + default: + break; + } + if (change) + setting->deferred_handler(setting); + } + } +} + /* Returns: * 0 - Forcibly wake up the loop. * -1 - Quit out of iteration loop. diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 9810f060b8..38b1699b71 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -160,6 +160,8 @@ int menu_common_core_setting_toggle(unsigned setting, unsigned action); int menu_common_setting_set_perf(unsigned setting, unsigned action, struct retro_perf_counter **counters, unsigned offset); +void apply_deferred_settings(); + #ifdef __cplusplus } #endif diff --git a/retroarch.c b/retroarch.c index 903c9e277b..6b8f60e543 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2015,6 +2015,8 @@ void rarch_main_set_state(unsigned cmd) break; case RARCH_ACTION_STATE_MENU_RUNNING_FINISHED: #ifdef HAVE_MENU + apply_deferred_settings(); + g_extern.is_menu = false; driver_set_nonblock_state(driver.nonblock_state); diff --git a/settings_data.c b/settings_data.c index fa8a120bea..2d4d0fc7ee 100644 --- a/settings_data.c +++ b/settings_data.c @@ -703,6 +703,7 @@ rarch_setting_t setting_data_float_setting(const char* name, result.change_handler = change_handler; result.read_handler = read_handler; result.value.fraction = target; + result.original_value.fraction = *target; result.default_value.fraction = default_value; return result; } @@ -718,6 +719,7 @@ rarch_setting_t setting_data_bool_setting(const char* name, result.change_handler = change_handler; result.read_handler = read_handler; result.value.boolean = target; + result.original_value.boolean = *target; result.default_value.boolean = default_value; result.boolean.off_label = off; result.boolean.on_label = on; @@ -735,6 +737,7 @@ rarch_setting_t setting_data_int_setting(const char* name, result.change_handler = change_handler; result.read_handler = read_handler; result.value.integer = target; + result.original_value.integer = *target; result.default_value.integer = default_value; return result; } @@ -750,6 +753,7 @@ rarch_setting_t setting_data_uint_setting(const char* name, result.change_handler = change_handler; result.read_handler = read_handler; result.value.unsigned_integer = target; + result.original_value.unsigned_integer = *target; result.default_value.unsigned_integer = default_value; return result; @@ -3631,7 +3635,7 @@ bool setting_data_append_list_audio_options( general_write_handler, general_read_handler); settings_list_current_add_range(list, list_info, 1, 256, 1.0, true, true); - + settings_list_current_add_flags(list, list_info, SD_FLAG_IS_DEFERRED); CONFIG_FLOAT( g_settings.audio.rate_control_delta, diff --git a/settings_list.c b/settings_list.c index 211f476ebf..8e6d91e017 100644 --- a/settings_list.c +++ b/settings_list.c @@ -56,12 +56,24 @@ bool settings_list_append(rarch_setting_t **list, return true; } +static void null_write_handler(void *data) +{ + return; +} + void settings_list_current_add_flags( rarch_setting_t **list, rarch_setting_info_t *list_info, unsigned values) { + (*list)[list_info->index - 1].flags |= values; + + if (values & SD_FLAG_IS_DEFERRED) + { + (*list)[list_info->index - 1].deferred_handler = (*list)[list_info->index - 1].change_handler; + (*list)[list_info->index - 1].change_handler = null_write_handler; + } } void settings_list_current_add_range( diff --git a/settings_list.h b/settings_list.h index 99d215746a..bcba7aa5eb 100644 --- a/settings_list.h +++ b/settings_list.h @@ -56,6 +56,7 @@ enum setting_flags SD_FLAG_EXIT = (1 << 8), SD_FLAG_CMD_APPLY_AUTO = (1 << 9), SD_FLAG_IS_CATEGORY = (1 << 10), + SD_FLAG_IS_DEFERRED = (1 << 11), }; enum setting_list_flags @@ -112,6 +113,7 @@ typedef struct rarch_setting uint64_t flags; change_handler_t change_handler; + change_handler_t deferred_handler; change_handler_t read_handler; union @@ -134,6 +136,14 @@ typedef struct rarch_setting struct retro_keybind* keybind; } value; + union + { + bool boolean; + int integer; + unsigned int unsigned_integer; + float fraction; + } original_value; + struct { const char *empty_path;