diff --git a/config.def.h b/config.def.h index 49a2eacb94..94f3cf2491 100644 --- a/config.def.h +++ b/config.def.h @@ -497,6 +497,9 @@ /* Save configuration file on exit. */ #define DEFAULT_CONFIG_SAVE_ON_EXIT true +/* Save active input remap file on exit/close content */ +#define DEFAULT_REMAP_SAVE_ON_EXIT true + #define DEFAULT_SHOW_HIDDEN_FILES false /* Initialise file browser with the last used start directory */ diff --git a/configuration.c b/configuration.c index 8d758ea957..a9fe123e74 100644 --- a/configuration.c +++ b/configuration.c @@ -1963,6 +1963,7 @@ static struct config_bool_setting *populate_settings_bool( SETTING_BOOL("sort_savestates_by_content_enable", &settings->bools.sort_savestates_by_content_enable, true, default_sort_savestates_by_content_enable, false); SETTING_BOOL("sort_screenshots_by_content_enable", &settings->bools.sort_screenshots_by_content_enable, true, default_sort_screenshots_by_content_enable, false); SETTING_BOOL("config_save_on_exit", &settings->bools.config_save_on_exit, true, DEFAULT_CONFIG_SAVE_ON_EXIT, false); + SETTING_BOOL("remap_save_on_exit", &settings->bools.remap_save_on_exit, true, DEFAULT_REMAP_SAVE_ON_EXIT, false); SETTING_BOOL("show_hidden_files", &settings->bools.show_hidden_files, true, DEFAULT_SHOW_HIDDEN_FILES, false); SETTING_BOOL("use_last_start_directory", &settings->bools.use_last_start_directory, true, DEFAULT_USE_LAST_START_DIRECTORY, false); SETTING_BOOL("input_autodetect_enable", &settings->bools.input_autodetect_enable, true, input_autodetect_enable, false); diff --git a/configuration.h b/configuration.h index f452a22bc7..34d13d88ea 100644 --- a/configuration.h +++ b/configuration.h @@ -892,6 +892,7 @@ typedef struct settings bool sort_savestates_by_content_enable; bool sort_screenshots_by_content_enable; bool config_save_on_exit; + bool remap_save_on_exit; bool show_hidden_files; bool use_last_start_directory; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 85490e433e..5cd41c0381 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -460,6 +460,10 @@ MSG_HASH( MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT, "config_save_on_exit" ) +MSG_HASH( + MENU_ENUM_LABEL_REMAP_SAVE_ON_EXIT, + "remap_save_on_exit" + ) MSG_HASH( MENU_ENUM_LABEL_CONNECT_WIFI, "connect_wifi" @@ -2844,6 +2848,10 @@ MSG_HASH( MENU_ENUM_LABEL_REMAP_FILE_RESET, "remap_file_reset" ) +MSG_HASH( + MENU_ENUM_LABEL_REMAP_FILE_FLUSH, + "remap_file_flush" + ) MSG_HASH( MENU_ENUM_LABEL_RESTART_CONTENT, "restart_content" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index a99ff16b1c..7e0bcc26a9 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3381,6 +3381,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, "Save changes to the configuration file on quit." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_SAVE_ON_EXIT, + "Save Remap Files on Quit" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_REMAP_SAVE_ON_EXIT, + "Save changes to any active input remap file when closing content or quitting RetroArch." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, "Load Content-Specific Core Options Automatically" @@ -7193,6 +7201,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_REMAP_FILE_RESET, "Set all input remapping options to default values." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_REMAP_FILE_FLUSH, + "Update Input Remap File" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_REMAP_FILE_FLUSH, + "Overwrite the active remap file with current input remapping options." + ) /* Quick Menu > Controls > Manage Remap Files > Load Remap File */ @@ -12574,6 +12590,14 @@ MSG_HASH( MSG_CORE_REMAP_FILE_LOADED, "Core remap file loaded." ) +MSG_HASH( + MSG_REMAP_FILE_FLUSHED, + "Input remapping options saved to:" + ) +MSG_HASH( + MSG_REMAP_FILE_FLUSH_FAILED, + "Failed to save input remapping options to:" + ) MSG_HASH( MSG_RUNAHEAD_ENABLED, "Run-Ahead enabled. Latency frames removed: %u." diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 435aeeae22..13623136cd 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -3615,6 +3615,49 @@ static int action_ok_remap_file_reset(const char *path, return 0; } +static int action_ok_remap_file_flush(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + runloop_state_t *runloop_st = runloop_state_get_ptr(); + const char *path_remapfile = runloop_st->name.remapfile; + const char *remapfile = NULL; + bool success = false; + char msg[256]; + + msg[0] = '\0'; + + /* Check if a remap file is active */ + if (!string_is_empty(path_remapfile)) + { + /* Update existing remap file */ + success = input_remapping_save_file(path_remapfile); + + /* Get remap file name for display purposes */ + remapfile = path_basename(path_remapfile); + } + + if (string_is_empty(remapfile)) + remapfile = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN); + + /* Log result */ + RARCH_LOG(success ? + "[Remaps]: Saved input remapping options to \"%s\".\n" : + "[Remaps]: Failed to save input remapping options to \"%s\".\n", + path_remapfile ? path_remapfile : "UNKNOWN"); + + snprintf(msg, sizeof(msg), "%s \"%s\"", + success ? + msg_hash_to_str(MSG_REMAP_FILE_FLUSHED) : + msg_hash_to_str(MSG_REMAP_FILE_FLUSH_FAILED), + remapfile); + + runloop_msg_queue_push( + msg, 1, 100, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + + return 0; +} + int action_ok_path_use_directory(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -8210,6 +8253,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, {MENU_ENUM_LABEL_REMAP_FILE_REMOVE_CONTENT_DIR, action_ok_remap_file_remove_content_dir}, {MENU_ENUM_LABEL_REMAP_FILE_REMOVE_GAME, action_ok_remap_file_remove_game}, {MENU_ENUM_LABEL_REMAP_FILE_RESET, action_ok_remap_file_reset}, + {MENU_ENUM_LABEL_REMAP_FILE_FLUSH, action_ok_remap_file_flush}, {MENU_ENUM_LABEL_PLAYLISTS_TAB, action_ok_content_collection_list}, {MENU_ENUM_LABEL_BROWSE_URL_LIST, action_ok_browse_url_list}, {MENU_ENUM_LABEL_CORE_LIST, action_ok_core_list}, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 52ba84848b..ee1e67a4b3 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -450,6 +450,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_hard_sync_frames, MENU_ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_threaded, MENU_ENUM_SUBLABEL_VIDEO_THREADED) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_settings, MENU_ENUM_SUBLABEL_SETTINGS) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_config_save_on_exit, MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_remap_save_on_exit, MENU_ENUM_SUBLABEL_REMAP_SAVE_ON_EXIT) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_configuration_settings_list, MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_configurations_list_list, MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_shared_context, MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT) @@ -844,6 +845,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_shader_options, DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_input_remapping_options, MENU_ENUM_SUBLABEL_CORE_INPUT_REMAPPING_OPTIONS) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_remap_file_manager_list, MENU_ENUM_SUBLABEL_REMAP_FILE_MANAGER_LIST) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_remap_file_reset, MENU_ENUM_SUBLABEL_REMAP_FILE_RESET) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_remap_file_flush, MENU_ENUM_SUBLABEL_REMAP_FILE_FLUSH) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_option_override_list, MENU_ENUM_SUBLABEL_CORE_OPTION_OVERRIDE_LIST) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_options_reset, MENU_ENUM_SUBLABEL_CORE_OPTIONS_RESET) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_options_flush, MENU_ENUM_SUBLABEL_CORE_OPTIONS_FLUSH) @@ -2918,6 +2920,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_REMAP_FILE_RESET: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_remap_file_reset); break; + case MENU_ENUM_LABEL_REMAP_FILE_FLUSH: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_remap_file_flush); + break; case MENU_ENUM_LABEL_CORE_CHEAT_OPTIONS: #ifdef HAVE_CHEATS BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_cheat_options); @@ -4035,6 +4040,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_config_save_on_exit); break; + case MENU_ENUM_LABEL_REMAP_SAVE_ON_EXIT: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_remap_save_on_exit); + break; case MENU_ENUM_LABEL_CONFIGURATION_SETTINGS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_configuration_settings_list); break; diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index cf36413792..fcd35a9c61 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -10313,6 +10313,7 @@ static void materialui_list_insert( node->icon_type = MUI_ICON_TYPE_INTERNAL; break; case MENU_SETTING_ACTION_CORE_OPTIONS_FLUSH: + case MENU_SETTING_ACTION_REMAP_FILE_FLUSH: node->icon_texture_index = MUI_TEXTURE_FILE; node->icon_type = MUI_ICON_TYPE_INTERNAL; break; diff --git a/menu/drivers/ozone.c b/menu/drivers/ozone.c index 230a6bde70..2cdc5f01ff 100644 --- a/menu/drivers/ozone.c +++ b/menu/drivers/ozone.c @@ -1903,6 +1903,7 @@ static uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone, case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG: case MENU_ENUM_LABEL_SAVE_NEW_CONFIG: case MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT: + case MENU_ENUM_LABEL_REMAP_SAVE_ON_EXIT: case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE: case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_AS: case MENU_ENUM_LABEL_CHEAT_FILE_SAVE_AS: @@ -1935,6 +1936,7 @@ static uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone, case MENU_ENUM_LABEL_REMAP_FILE_RESET: return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_UNDO]; case MENU_ENUM_LABEL_CORE_OPTIONS_FLUSH: + case MENU_ENUM_LABEL_REMAP_FILE_FLUSH: return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_FILE]; case MENU_ENUM_LABEL_CORE_LOCK: case MENU_ENUM_LABEL_CORE_SET_STANDALONE_EXEMPT: diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index cc55e5f4ef..8435f10156 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2776,6 +2776,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG: case MENU_ENUM_LABEL_SAVE_NEW_CONFIG: case MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT: + case MENU_ENUM_LABEL_REMAP_SAVE_ON_EXIT: case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE: case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_AS: case MENU_ENUM_LABEL_CHEAT_FILE_SAVE_AS: @@ -2808,6 +2809,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, case MENU_ENUM_LABEL_REMAP_FILE_RESET: return xmb->textures.list[XMB_TEXTURE_UNDO]; case MENU_ENUM_LABEL_CORE_OPTIONS_FLUSH: + case MENU_ENUM_LABEL_REMAP_FILE_FLUSH: return xmb->textures.list[XMB_TEXTURE_FILE]; case MENU_ENUM_LABEL_CORE_LOCK: case MENU_ENUM_LABEL_CORE_SET_STANDALONE_EXEMPT: diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 7e69974eac..eaedea88a8 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1302,6 +1302,7 @@ static unsigned menu_displaylist_parse_remap_file_manager_list( bool core_remap_active = retroarch_ctl(RARCH_CTL_IS_REMAPS_CORE_ACTIVE, NULL); bool content_dir_remap_active = retroarch_ctl(RARCH_CTL_IS_REMAPS_CONTENT_DIR_ACTIVE, NULL); bool game_remap_active = retroarch_ctl(RARCH_CTL_IS_REMAPS_GAME_ACTIVE, NULL); + bool remap_save_on_exit = settings->bools.remap_save_on_exit; /* Sanity check - cannot handle remap files * unless a valid core is running */ @@ -1389,6 +1390,18 @@ static unsigned menu_displaylist_parse_remap_file_manager_list( MENU_ENUM_LABEL_REMAP_FILE_RESET, MENU_SETTING_ACTION_REMAP_FILE_RESET, 0, 0)) count++; + + /* Flush input remaps to disk */ + if (!remap_save_on_exit && + (core_remap_active || + content_dir_remap_active || + game_remap_active) && + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_REMAP_FILE_FLUSH), + msg_hash_to_str(MENU_ENUM_LABEL_REMAP_FILE_FLUSH), + MENU_ENUM_LABEL_REMAP_FILE_FLUSH, + MENU_SETTING_ACTION_REMAP_FILE_FLUSH, 0, 0)) + count++; end: /* Fallback */ if (count == 0) @@ -9737,6 +9750,7 @@ unsigned menu_displaylist_build_list( { menu_displaylist_build_info_t build_list[] = { {MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT, PARSE_ONLY_BOOL}, + {MENU_ENUM_LABEL_REMAP_SAVE_ON_EXIT, PARSE_ONLY_BOOL}, {MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS, PARSE_ONLY_BOOL}, {MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE, PARSE_ONLY_BOOL}, {MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE, PARSE_ONLY_BOOL}, diff --git a/menu/menu_driver.h b/menu/menu_driver.h index a2c87a509c..6db7a0237a 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -284,6 +284,7 @@ enum menu_settings_type MENU_SETTING_ACTION_REMAP_FILE_REMOVE_CONTENT_DIR, MENU_SETTING_ACTION_REMAP_FILE_REMOVE_GAME, MENU_SETTING_ACTION_REMAP_FILE_RESET, + MENU_SETTING_ACTION_REMAP_FILE_FLUSH, MENU_SETTING_ACTION_CONTENTLESS_CORE_RUN, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 82832b6b22..950537fd77 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -10226,7 +10226,7 @@ static bool setting_append_list( case SETTINGS_LIST_CONFIGURATION: { uint8_t i; - struct bool_entry bool_entries[7]; + struct bool_entry bool_entries[8]; START_GROUP(list, list_info, &group_info, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS), parent_group); @@ -10277,6 +10277,12 @@ static bool setting_append_list( bool_entries[6].default_value = default_global_core_options; bool_entries[6].flags = SD_FLAG_NONE; + bool_entries[7].target = &settings->bools.remap_save_on_exit; + bool_entries[7].name_enum_idx = MENU_ENUM_LABEL_REMAP_SAVE_ON_EXIT; + bool_entries[7].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_REMAP_SAVE_ON_EXIT; + bool_entries[7].default_value = DEFAULT_REMAP_SAVE_ON_EXIT; + bool_entries[7].flags = SD_FLAG_NONE; + for (i = 0; i < ARRAY_SIZE(bool_entries); i++) { CONFIG_BOOL( diff --git a/msg_hash.h b/msg_hash.h index cec3567916..1ea55971ba 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -486,6 +486,8 @@ enum msg_hash_enums MSG_GAME_REMAP_FILE_LOADED, MSG_DIRECTORY_REMAP_FILE_LOADED, MSG_CORE_REMAP_FILE_LOADED, + MSG_REMAP_FILE_FLUSHED, + MSG_REMAP_FILE_FLUSH_FAILED, MSG_RUNAHEAD_ENABLED, MSG_RUNAHEAD_ENABLED_WITH_SECOND_INSTANCE, MSG_RUNAHEAD_DISABLED, @@ -2050,6 +2052,7 @@ enum msg_hash_enums MENU_LABEL(LIBRETRO_LOG_LEVEL), MENU_LABEL(AUTOSAVE_INTERVAL), MENU_LABEL(CONFIG_SAVE_ON_EXIT), + MENU_LABEL(REMAP_SAVE_ON_EXIT), MENU_LABEL(CONFIGURATION_LIST), MENU_LABEL(CONFIRM_ON_EXIT), MENU_LABEL(SHOW_HIDDEN_FILES), @@ -2621,6 +2624,7 @@ enum msg_hash_enums MENU_LABEL(REMAP_FILE_REMOVE_CONTENT_DIR), MENU_LABEL(REMAP_FILE_REMOVE_GAME), MENU_LABEL(REMAP_FILE_RESET), + MENU_LABEL(REMAP_FILE_FLUSH), MENU_LABEL(RESTART_CONTENT), MENU_LABEL(RESUME), diff --git a/retroarch.c b/retroarch.c index f88d2e8dbd..100462db07 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1912,7 +1912,7 @@ bool command_event(enum event_command cmd, void *data) || !string_is_empty(runloop_st->name.remapfile) ) { - input_remapping_deinit(true); + input_remapping_deinit(settings->bools.remap_save_on_exit); input_remapping_set_defaults(true); } else @@ -6053,7 +6053,7 @@ bool retroarch_main_quit(void) || !string_is_empty(runloop_st->name.remapfile) ) { - input_remapping_deinit(true); + input_remapping_deinit(settings->bools.remap_save_on_exit); input_remapping_set_defaults(true); } else diff --git a/runloop.c b/runloop.c index 46055e8fbc..91e6d48cf4 100644 --- a/runloop.c +++ b/runloop.c @@ -5034,7 +5034,7 @@ void runloop_event_deinit_core(void) || !string_is_empty(runloop_st->name.remapfile) ) { - input_remapping_deinit(true); + input_remapping_deinit(settings->bools.remap_save_on_exit); input_remapping_set_defaults(true); } else