From 1d7cba8378c06edf0d00ed20a023b2acb8671352 Mon Sep 17 00:00:00 2001 From: Kimimaru Date: Sat, 25 Apr 2026 01:21:03 +0300 Subject: [PATCH] Added direct save and load hotkeys for savestate slots 0 through 9 --- command.h | 22 +++++ config.def.h | 5 ++ config.def.keybinds.h | 164 +++++++++++++++++++++++++++++++--- configuration.c | 25 ++++++ configuration.h | 1 + input/input_defines.h | 20 +++++ intl/msg_hash_lbl.h | 4 + intl/msg_hash_us.c | 3 + intl/msg_hash_us.h | 168 +++++++++++++++++++++++++++++++++++ menu/cbs/menu_cbs_sublabel.c | 84 ++++++++++++++++++ menu/menu_displaylist.c | 56 ++++++++++++ menu/menu_setting.c | 29 ++++++ msg_hash.h | 41 +++++++++ msg_hash_lbl_str.h | 1 + retroarch.c | 78 ++++++++++------ runloop.c | 21 +++++ ui/drivers/ui_qt_widgets.cpp | 1 + 17 files changed, 684 insertions(+), 39 deletions(-) diff --git a/command.h b/command.h index 7a6858e9da9a..a473fccc3c38 100644 --- a/command.h +++ b/command.h @@ -62,7 +62,9 @@ enum event_command CMD_EVENT_UNDO_SAVE_STATE, /* Save state hotkeys. */ CMD_EVENT_LOAD_STATE, + CMD_EVENT_LOAD_STATE_SLOT, CMD_EVENT_SAVE_STATE, + CMD_EVENT_SAVE_STATE_SLOT, CMD_EVENT_SAVE_STATE_DECREMENT, CMD_EVENT_SAVE_STATE_INCREMENT, /* Replay hotkeys. */ @@ -480,6 +482,26 @@ static const struct cmd_map map[] = { { "FAST_FORWARD_HOLD", RARCH_FAST_FORWARD_HOLD_KEY }, { "SLOWMOTION", RARCH_SLOWMOTION_KEY }, { "SLOWMOTION_HOLD", RARCH_SLOWMOTION_HOLD_KEY }, + { "LOAD_STATE_SLOT0", RARCH_LOAD_STATE_SLOT0_KEY }, + { "LOAD_STATE_SLOT1", RARCH_LOAD_STATE_SLOT1_KEY }, + { "LOAD_STATE_SLOT2", RARCH_LOAD_STATE_SLOT2_KEY }, + { "LOAD_STATE_SLOT3", RARCH_LOAD_STATE_SLOT3_KEY }, + { "LOAD_STATE_SLOT4", RARCH_LOAD_STATE_SLOT4_KEY }, + { "LOAD_STATE_SLOT5", RARCH_LOAD_STATE_SLOT5_KEY }, + { "LOAD_STATE_SLOT6", RARCH_LOAD_STATE_SLOT6_KEY }, + { "LOAD_STATE_SLOT7", RARCH_LOAD_STATE_SLOT7_KEY }, + { "LOAD_STATE_SLOT8", RARCH_LOAD_STATE_SLOT8_KEY }, + { "LOAD_STATE_SLOT9", RARCH_LOAD_STATE_SLOT9_KEY }, + { "SAVE_STATE_SLOT0", RARCH_SAVE_STATE_SLOT0_KEY }, + { "SAVE_STATE_SLOT1", RARCH_SAVE_STATE_SLOT1_KEY }, + { "SAVE_STATE_SLOT2", RARCH_SAVE_STATE_SLOT2_KEY }, + { "SAVE_STATE_SLOT3", RARCH_SAVE_STATE_SLOT3_KEY }, + { "SAVE_STATE_SLOT4", RARCH_SAVE_STATE_SLOT4_KEY }, + { "SAVE_STATE_SLOT5", RARCH_SAVE_STATE_SLOT5_KEY }, + { "SAVE_STATE_SLOT6", RARCH_SAVE_STATE_SLOT6_KEY }, + { "SAVE_STATE_SLOT7", RARCH_SAVE_STATE_SLOT7_KEY }, + { "SAVE_STATE_SLOT8", RARCH_SAVE_STATE_SLOT8_KEY }, + { "SAVE_STATE_SLOT9", RARCH_SAVE_STATE_SLOT9_KEY }, { "REWIND", RARCH_REWIND }, { "PAUSE_TOGGLE", RARCH_PAUSE_TOGGLE }, { "FRAMEADVANCE", RARCH_FRAMEADVANCE }, diff --git a/config.def.h b/config.def.h index 4446b93ad6fc..5406be1b78f8 100644 --- a/config.def.h +++ b/config.def.h @@ -1390,6 +1390,11 @@ * This could potentially lead to buggy games. */ #define DEFAULT_BLOCK_SRAM_OVERWRITE false +/* Specifies the maximum savestate slot that can be + * directly saved or loaded into, with a max slot of 9. + * Setting this value to -1 disables the feature entirely. */ +#define DEFAULT_SAVESTATE_MAX_DIRECT_SLOT -1 + /* When saving savestates, state index is automatically * incremented before saving. * When the content is loaded, state index will be set diff --git a/config.def.keybinds.h b/config.def.keybinds.h index 85d3d51ec09a..0ecc0d84f565 100644 --- a/config.def.keybinds.h +++ b/config.def.keybinds.h @@ -23,28 +23,28 @@ /* User 1 */ static const struct retro_keybind retro_keybinds_1[] = { #ifdef __QNX__ - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, RETROK_k, RETRO_DEVICE_ID_JOYPAD_B, NO_BTN, NO_BTN, 0, true }, - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, RETROK_i, RETRO_DEVICE_ID_JOYPAD_Y, NO_BTN, NO_BTN, 0, true }, - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, RETROK_v, RETRO_DEVICE_ID_JOYPAD_SELECT, NO_BTN, NO_BTN, 0, true }, - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, RETROK_b, @@ -395,6 +395,76 @@ static const struct retro_keybind retro_keybinds_1[] = { RARCH_LOAD_STATE_KEY, NO_BTN, NO_BTN, 0, true }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT0_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT0_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT1_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT1_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT2_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT2_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT3_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT3_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT4_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT4_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT5_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT5_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT6_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT6_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT7_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT7_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT8_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT8_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT9_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_SLOT9_KEY, NO_BTN, NO_BTN, 0, + true + }, { NULL, NULL, AXIS_NONE, AXIS_NONE, @@ -402,6 +472,76 @@ static const struct retro_keybind retro_keybinds_1[] = { RARCH_SAVE_STATE_KEY, NO_BTN, NO_BTN, 0, true }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT0_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT0_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT1_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT1_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT2_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT2_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT3_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT3_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT4_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT4_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT5_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT5_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT6_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT6_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT7_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT7_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT8_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT8_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT9_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_SLOT9_KEY, NO_BTN, NO_BTN, 0, + true + }, { NULL, NULL, AXIS_NONE, AXIS_NONE, @@ -690,28 +830,28 @@ static const struct retro_keybind retro_keybinds_1[] = { true }, #elif defined(DINGUX) - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, RETROK_LALT, RETRO_DEVICE_ID_JOYPAD_B, NO_BTN, NO_BTN, 0, true }, - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, RETROK_LSHIFT, RETRO_DEVICE_ID_JOYPAD_Y, NO_BTN, NO_BTN, 0, true }, - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, RETROK_ESCAPE, RETRO_DEVICE_ID_JOYPAD_SELECT, NO_BTN, NO_BTN, 0, true }, - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, RETROK_RETURN, @@ -1357,28 +1497,28 @@ static const struct retro_keybind retro_keybinds_1[] = { true }, #else - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, RETROK_z, RETRO_DEVICE_ID_JOYPAD_B, NO_BTN, NO_BTN, 0, true }, - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, RETROK_a, RETRO_DEVICE_ID_JOYPAD_Y, NO_BTN, NO_BTN, 0, true }, - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, RETROK_RSHIFT, RETRO_DEVICE_ID_JOYPAD_SELECT, NO_BTN, NO_BTN, 0, true }, - { + { NULL, NULL, AXIS_NONE, AXIS_NONE, MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, RETROK_RETURN, diff --git a/configuration.c b/configuration.c index dd9082bf9343..a3c2f370938d 100644 --- a/configuration.c +++ b/configuration.c @@ -376,7 +376,31 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = { DECLARE_META_BIND(2, volume_down, RARCH_VOLUME_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN), DECLARE_META_BIND(1, load_state, RARCH_LOAD_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY), + + DECLARE_META_BIND(1, load_state_slot0, RARCH_LOAD_STATE_SLOT0_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT0_KEY), + DECLARE_META_BIND(1, load_state_slot1, RARCH_LOAD_STATE_SLOT1_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT1_KEY), + DECLARE_META_BIND(1, load_state_slot2, RARCH_LOAD_STATE_SLOT2_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT2_KEY), + DECLARE_META_BIND(1, load_state_slot3, RARCH_LOAD_STATE_SLOT3_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT3_KEY), + DECLARE_META_BIND(1, load_state_slot4, RARCH_LOAD_STATE_SLOT4_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT4_KEY), + DECLARE_META_BIND(1, load_state_slot5, RARCH_LOAD_STATE_SLOT5_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT5_KEY), + DECLARE_META_BIND(1, load_state_slot6, RARCH_LOAD_STATE_SLOT6_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT6_KEY), + DECLARE_META_BIND(1, load_state_slot7, RARCH_LOAD_STATE_SLOT7_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT7_KEY), + DECLARE_META_BIND(1, load_state_slot8, RARCH_LOAD_STATE_SLOT8_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT8_KEY), + DECLARE_META_BIND(1, load_state_slot9, RARCH_LOAD_STATE_SLOT9_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT9_KEY), + DECLARE_META_BIND(1, save_state, RARCH_SAVE_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY), + + DECLARE_META_BIND(1, save_state_slot0, RARCH_SAVE_STATE_SLOT0_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT0_KEY), + DECLARE_META_BIND(1, save_state_slot1, RARCH_SAVE_STATE_SLOT1_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT1_KEY), + DECLARE_META_BIND(1, save_state_slot2, RARCH_SAVE_STATE_SLOT2_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT2_KEY), + DECLARE_META_BIND(1, save_state_slot3, RARCH_SAVE_STATE_SLOT3_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT3_KEY), + DECLARE_META_BIND(1, save_state_slot4, RARCH_SAVE_STATE_SLOT4_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT4_KEY), + DECLARE_META_BIND(1, save_state_slot5, RARCH_SAVE_STATE_SLOT5_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT5_KEY), + DECLARE_META_BIND(1, save_state_slot6, RARCH_SAVE_STATE_SLOT6_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT6_KEY), + DECLARE_META_BIND(1, save_state_slot7, RARCH_SAVE_STATE_SLOT7_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT7_KEY), + DECLARE_META_BIND(1, save_state_slot8, RARCH_SAVE_STATE_SLOT8_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT8_KEY), + DECLARE_META_BIND(1, save_state_slot9, RARCH_SAVE_STATE_SLOT9_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT9_KEY), + DECLARE_META_BIND(2, state_slot_increase, RARCH_STATE_SLOT_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS), DECLARE_META_BIND(2, state_slot_decrease, RARCH_STATE_SLOT_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS), @@ -2775,6 +2799,7 @@ static struct config_int_setting *populate_settings_int( return NULL; SETTING_INT("content_favorites_size", &settings->ints.content_favorites_size, true, DEFAULT_CONTENT_FAVORITES_SIZE, false); + SETTING_INT("savestate_max_direct_slot", &settings->ints.savestate_max_direct_slot, true, DEFAULT_SAVESTATE_MAX_DIRECT_SLOT, false); SETTING_INT("state_slot", &settings->ints.state_slot, false, 0, false); SETTING_INT("replay_slot", &settings->ints.replay_slot, false, 0, false); diff --git a/configuration.h b/configuration.h index 71d02a785954..955bd66ea0e7 100644 --- a/configuration.h +++ b/configuration.h @@ -118,6 +118,7 @@ typedef struct settings int netplay_check_frames; int location_update_interval_ms; int location_update_interval_distance; + int savestate_max_direct_slot; int state_slot; int replay_slot; int crt_switch_center_adjust; diff --git a/input/input_defines.h b/input/input_defines.h index 6bcaa0bf62ce..e582f455c3b0 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -143,7 +143,27 @@ enum RARCH_VOLUME_DOWN, RARCH_LOAD_STATE_KEY, + RARCH_LOAD_STATE_SLOT0_KEY, + RARCH_LOAD_STATE_SLOT1_KEY, + RARCH_LOAD_STATE_SLOT2_KEY, + RARCH_LOAD_STATE_SLOT3_KEY, + RARCH_LOAD_STATE_SLOT4_KEY, + RARCH_LOAD_STATE_SLOT5_KEY, + RARCH_LOAD_STATE_SLOT6_KEY, + RARCH_LOAD_STATE_SLOT7_KEY, + RARCH_LOAD_STATE_SLOT8_KEY, + RARCH_LOAD_STATE_SLOT9_KEY, RARCH_SAVE_STATE_KEY, + RARCH_SAVE_STATE_SLOT0_KEY, + RARCH_SAVE_STATE_SLOT1_KEY, + RARCH_SAVE_STATE_SLOT2_KEY, + RARCH_SAVE_STATE_SLOT3_KEY, + RARCH_SAVE_STATE_SLOT4_KEY, + RARCH_SAVE_STATE_SLOT5_KEY, + RARCH_SAVE_STATE_SLOT6_KEY, + RARCH_SAVE_STATE_SLOT7_KEY, + RARCH_SAVE_STATE_SLOT8_KEY, + RARCH_SAVE_STATE_SLOT9_KEY, RARCH_STATE_SLOT_PLUS, RARCH_STATE_SLOT_MINUS, diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a4419efd1869..92e80dd520e8 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -3388,6 +3388,10 @@ MSG_HASH( MENU_ENUM_LABEL_SAVEFILE_DIRECTORY, MENU_ENUM_LABEL_SAVEFILE_DIRECTORY_STR ) +MSG_HASH( + MENU_ENUM_LABEL_SAVESTATE_MAX_DIRECT_SLOT, + MENU_ENUM_LABEL_SAVESTATE_MAX_DIRECT_SLOT_STR + ) MSG_HASH( MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX, MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX_STR diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 693597e85918..7b6527567964 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -88,6 +88,9 @@ int msg_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) case MENU_ENUM_LABEL_CORE_INFO_SAVESTATE_BYPASS: strlcpy(s, msg_hash_to_str(MENU_ENUM_SUBLABEL_CORE_INFO_SAVESTATE_BYPASS), len); break; + case MENU_ENUM_LABEL_SAVESTATE_MAX_DIRECT_SLOT: + strlcpy(s, msg_hash_to_str(MENU_ENUM_SUBLABEL_SAVESTATE_MAX_DIRECT_SLOT), len); + break; case MENU_ENUM_LABEL_PARENT_DIRECTORY: strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_HELP_PARENT_DIRECTORY), len); break; diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 239be309ed8c..6349eb738cf4 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3865,6 +3865,86 @@ MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_KEY, "Loads saved state from the currently selected slot." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT0_KEY, + "Load State 0" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT0_KEY, + "Loads a saved state from slot 0." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT1_KEY, + "Load State 1" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT1_KEY, + "Loads a saved state from slot 1." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT2_KEY, + "Load State 2" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT2_KEY, + "Loads a saved state from slot 2." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT3_KEY, + "Load State 3" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT3_KEY, + "Loads a saved state from slot 3." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT4_KEY, + "Load State 4" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT4_KEY, + "Loads a saved state from slot 4." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT5_KEY, + "Load State 5" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT5_KEY, + "Loads a saved state from slot 5." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT6_KEY, + "Load State 6" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT6_KEY, + "Loads a saved state from slot 6." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT7_KEY, + "Load State 7" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT7_KEY, + "Loads a saved state from slot 7." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT8_KEY, + "Load State 8" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT8_KEY, + "Loads a saved state from slot 8." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT9_KEY, + "Load State 9" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT9_KEY, + "Loads a saved state from slot 9." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, "Save State" @@ -3873,6 +3953,86 @@ MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_KEY, "Saves state to the currently selected slot." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT0_KEY, + "Save State 0" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT0_KEY, + "Saves a state to slot 0." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT1_KEY, + "Save State 1" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT1_KEY, + "Saves a state to slot 1." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT2_KEY, + "Save State 2" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT2_KEY, + "Saves a state to slot 2." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT3_KEY, + "Save State 3" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT3_KEY, + "Saves a state to slot 3." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT4_KEY, + "Save State 4" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT4_KEY, + "Saves a state to slot 4." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT5_KEY, + "Save State 5" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT5_KEY, + "Saves a state to slot 5." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT6_KEY, + "Save State 6" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT6_KEY, + "Saves a state to slot 6." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT7_KEY, + "Save State 7" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT7_KEY, + "Saves a state to slot 7." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT8_KEY, + "Save State 8" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT8_KEY, + "Saves a state to slot 8." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT9_KEY, + "Save State 9" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT9_KEY, + "Saves a state to slot 9." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, "Next Save State Slot" @@ -4767,6 +4927,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, "Block SaveRAM from being overwritten when loading save states. Might potentially lead to buggy games." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SAVESTATE_MAX_DIRECT_SLOT, + "Maximum Direct Save State Slot Available" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_MAX_DIRECT_SLOT, + "The maximum save state slot that can be directly saved into and loaded from. 'OFF' means no direct save state slots will be available." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, "Save File: SaveRAM Autosave Interval" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index de8c0eec36b6..d4817f6303a5 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -446,7 +446,27 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_volume_up, ME DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_volume_down, MENU_ENUM_SUBLABEL_INPUT_META_VOLUME_DOWN) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot0_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT0_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot1_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT1_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot2_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT2_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot3_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT3_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot4_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT4_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot5_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT5_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot6_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT6_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot7_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT7_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot8_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT8_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_load_state_slot9_key, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT9_KEY) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot0_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT0_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot1_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT1_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot2_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT2_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot3_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT3_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot4_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT4_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot5_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT5_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot6_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT6_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot7_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT7_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot8_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT8_KEY) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_save_state_slot9_key, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT9_KEY) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_state_slot_plus, MENU_ENUM_SUBLABEL_INPUT_META_STATE_SLOT_PLUS) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_state_slot_minus, MENU_ENUM_SUBLABEL_INPUT_META_STATE_SLOT_MINUS) @@ -760,6 +780,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_windowed_fullscreen, MENU_ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_autoswitch_refresh_rate, MENU_ENUM_SUBLABEL_VIDEO_AUTOSWITCH_REFRESH_RATE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_autoswitch_pal_threshold,MENU_ENUM_SUBLABEL_VIDEO_AUTOSWITCH_PAL_THRESHOLD) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_gpu_record, MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_max_direct_slot, MENU_ENUM_SUBLABEL_SAVESTATE_MAX_DIRECT_SLOT) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_auto_index, MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_auto_index, MENU_ENUM_SUBLABEL_REPLAY_AUTO_INDEX) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_block_sram_overwrite, MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE) @@ -2356,9 +2377,69 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case RARCH_LOAD_STATE_KEY: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_key); return 0; + case RARCH_LOAD_STATE_SLOT0_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot0_key); + return 0; + case RARCH_LOAD_STATE_SLOT1_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot1_key); + return 0; + case RARCH_LOAD_STATE_SLOT2_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot2_key); + return 0; + case RARCH_LOAD_STATE_SLOT3_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot3_key); + return 0; + case RARCH_LOAD_STATE_SLOT4_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot4_key); + return 0; + case RARCH_LOAD_STATE_SLOT5_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot5_key); + return 0; + case RARCH_LOAD_STATE_SLOT6_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot6_key); + return 0; + case RARCH_LOAD_STATE_SLOT7_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot7_key); + return 0; + case RARCH_LOAD_STATE_SLOT8_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot8_key); + return 0; + case RARCH_LOAD_STATE_SLOT9_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_load_state_slot9_key); + return 0; case RARCH_SAVE_STATE_KEY: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_key); return 0; + case RARCH_SAVE_STATE_SLOT0_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot0_key); + return 0; + case RARCH_SAVE_STATE_SLOT1_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot1_key); + return 0; + case RARCH_SAVE_STATE_SLOT2_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot2_key); + return 0; + case RARCH_SAVE_STATE_SLOT3_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot3_key); + return 0; + case RARCH_SAVE_STATE_SLOT4_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot4_key); + return 0; + case RARCH_SAVE_STATE_SLOT5_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot5_key); + return 0; + case RARCH_SAVE_STATE_SLOT6_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot6_key); + return 0; + case RARCH_SAVE_STATE_SLOT7_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot7_key); + return 0; + case RARCH_SAVE_STATE_SLOT8_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot8_key); + return 0; + case RARCH_SAVE_STATE_SLOT9_KEY: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_save_state_slot9_key); + return 0; case RARCH_STATE_SLOT_PLUS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_state_slot_plus); return 0; @@ -4324,6 +4405,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_block_sram_overwrite); break; + case MENU_ENUM_LABEL_SAVESTATE_MAX_DIRECT_SLOT: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_savestate_max_direct_slot); + break; case MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_savestate_auto_index); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 78c185b58b3e..05aa0fa1a743 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -7482,6 +7482,61 @@ unsigned menu_displaylist_build_list( count++; } + /* Skip direct savestate hotkeys higher than the max direct slot available */ + switch (i) + { + case RARCH_LOAD_STATE_SLOT0_KEY: + case RARCH_SAVE_STATE_SLOT0_KEY: + if (settings->ints.savestate_max_direct_slot < 0) + continue; + break; + case RARCH_LOAD_STATE_SLOT1_KEY: + case RARCH_SAVE_STATE_SLOT1_KEY: + if (settings->ints.savestate_max_direct_slot < 1) + continue; + break; + case RARCH_LOAD_STATE_SLOT2_KEY: + case RARCH_SAVE_STATE_SLOT2_KEY: + if (settings->ints.savestate_max_direct_slot < 2) + continue; + break; + case RARCH_LOAD_STATE_SLOT3_KEY: + case RARCH_SAVE_STATE_SLOT3_KEY: + if (settings->ints.savestate_max_direct_slot < 3) + continue; + break; + case RARCH_LOAD_STATE_SLOT4_KEY: + case RARCH_SAVE_STATE_SLOT4_KEY: + if (settings->ints.savestate_max_direct_slot < 4) + continue; + break; + case RARCH_LOAD_STATE_SLOT5_KEY: + case RARCH_SAVE_STATE_SLOT5_KEY: + if (settings->ints.savestate_max_direct_slot < 5) + continue; + break; + case RARCH_LOAD_STATE_SLOT6_KEY: + case RARCH_SAVE_STATE_SLOT6_KEY: + if (settings->ints.savestate_max_direct_slot < 6) + continue; + break; + case RARCH_LOAD_STATE_SLOT7_KEY: + case RARCH_SAVE_STATE_SLOT7_KEY: + if (settings->ints.savestate_max_direct_slot < 7) + continue; + break; + case RARCH_LOAD_STATE_SLOT8_KEY: + case RARCH_SAVE_STATE_SLOT8_KEY: + if (settings->ints.savestate_max_direct_slot < 8) + continue; + break; + case RARCH_LOAD_STATE_SLOT9_KEY: + case RARCH_SAVE_STATE_SLOT9_KEY: + if (settings->ints.savestate_max_direct_slot < 9) + continue; + break; + } + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, (enum msg_hash_enums)( MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i), @@ -11151,6 +11206,7 @@ unsigned menu_displaylist_build_list( #if defined(HAVE_ZLIB) {MENU_ENUM_LABEL_SAVESTATE_FILE_COMPRESSION, PARSE_ONLY_BOOL, true}, #endif + {MENU_ENUM_LABEL_SAVESTATE_MAX_DIRECT_SLOT, PARSE_ONLY_INT, true}, {MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX, PARSE_ONLY_BOOL, true}, {MENU_ENUM_LABEL_SAVESTATE_MAX_KEEP, PARSE_ONLY_UINT, false}, {MENU_ENUM_LABEL_REPLAY_AUTO_INDEX, PARSE_ONLY_BOOL, true}, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 1fc6a6401d8e..dd0e7b82a5f6 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -6980,6 +6980,19 @@ static size_t setting_get_string_representation_uint_input_remap_port( return 0; } +static size_t setting_get_string_representation_int_savestate_direct_max_slot( + rarch_setting_t *setting, char *s, size_t len) +{ + if (setting) + { + if (*setting->value.target.integer >= 0) + return snprintf(s, len, "%d", *setting->value.target.integer); + else + return strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF), len); + } + return 0; +} + #ifdef HAVE_THREADS static size_t setting_get_string_representation_uint_autosave_interval( rarch_setting_t *setting, char *s, size_t len) @@ -12006,6 +12019,22 @@ static bool setting_append_list( (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_autosave_interval; #endif + + CONFIG_INT( + list, list_info, + &settings->ints.savestate_max_direct_slot, + MENU_ENUM_LABEL_SAVESTATE_MAX_DIRECT_SLOT, + MENU_ENUM_LABEL_VALUE_SAVESTATE_MAX_DIRECT_SLOT, + DEFAULT_SAVESTATE_MAX_DIRECT_SLOT, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].get_string_representation = + &setting_get_string_representation_int_savestate_direct_max_slot; + menu_settings_list_current_add_range(list, list_info, -1, 9, 1, true, true); + CONFIG_BOOL( list, list_info, &settings->bools.savestate_auto_index, diff --git a/msg_hash.h b/msg_hash.h index 1bfe9e830f03..f081643949da 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1137,7 +1137,27 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT0_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT1_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT2_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT3_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT4_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT5_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT6_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT7_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT8_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_SLOT9_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT0_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT1_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT2_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT3_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT4_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT5_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT6_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT7_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT8_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_SLOT9_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, @@ -1240,7 +1260,27 @@ enum msg_hash_enums MENU_ENUM_SUBLABEL_INPUT_META_VOLUME_DOWN, MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT0_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT1_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT2_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT3_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT4_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT5_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT6_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT7_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT8_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_LOAD_STATE_SLOT9_KEY, MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT0_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT1_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT2_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT3_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT4_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT5_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT6_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT7_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT8_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_SAVE_STATE_SLOT9_KEY, MENU_ENUM_SUBLABEL_INPUT_META_STATE_SLOT_PLUS, MENU_ENUM_SUBLABEL_INPUT_META_STATE_SLOT_MINUS, @@ -2424,6 +2464,7 @@ enum msg_hash_enums MSG_SCREEN_RESOLUTION_RESETTING_NO_DESC, MSG_SCREEN_RESOLUTION_RESETTING_DESC, + MENU_LABEL(SAVESTATE_MAX_DIRECT_SLOT), MENU_LABEL(SAVESTATE_AUTO_INDEX), MENU_LABEL(SAVESTATE_MAX_KEEP), MENU_LABEL(REPLAY_AUTO_INDEX), diff --git a/msg_hash_lbl_str.h b/msg_hash_lbl_str.h index 304770c572b8..2b32d98a7987 100644 --- a/msg_hash_lbl_str.h +++ b/msg_hash_lbl_str.h @@ -847,6 +847,7 @@ #define MENU_ENUM_LABEL_RUN_MUSIC_STR "collection_music" #define MENU_ENUM_LABEL_SAMBA_ENABLE_STR "samba_enable" #define MENU_ENUM_LABEL_SAVEFILE_DIRECTORY_STR "savefile_directory" +#define MENU_ENUM_LABEL_SAVESTATE_MAX_DIRECT_SLOT_STR "savestate_max_direct_slot" #define MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX_STR "savestate_auto_index" #define MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD_STR "savestate_auto_load" #define MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE_STR "savestate_thumbnails" diff --git a/retroarch.c b/retroarch.c index 2eac0d7f9ab2..d3ee51108ab3 100644 --- a/retroarch.c +++ b/retroarch.c @@ -3112,6 +3112,43 @@ bool is_accessibility_enabled(bool accessibility_enable, bool accessibility_enab } #endif +/** + * Handles a load state command event. + * + * Returns: true (1) on success, otherwise false (0). + **/ +bool handle_load_state_command_event() +{ + runloop_state_t *runloop_st = runloop_state_get_ptr(); + +#ifdef HAVE_CHEEVOS + if (rcheevos_hardcore_active()) + { + const char *_msg = msg_hash_to_str(MSG_CHEEVOS_LOAD_STATE_PREVENTED_BY_HARDCORE_MODE); + runloop_msg_queue_push(_msg, strlen(_msg), 0, 180, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_WARNING); + return false; + } +#endif +#ifdef HAVE_NETWORKING + if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_TIMESKIP, NULL)) + return false; +#endif + if (!command_event_main_state(CMD_EVENT_LOAD_STATE)) + return false; + /* Run next frame to see the core output while paused */ + else if (runloop_st->flags & RUNLOOP_FLAG_PAUSED) + { + runloop_st->flags &= ~RUNLOOP_FLAG_PAUSED; + runloop_st->run_frames_and_pause = 1; + } + +#if HAVE_RUNAHEAD + command_event(CMD_EVENT_PREEMPT_RESET_BUFFER, NULL); +#endif + return true; +} + /** * command_event: * @cmd : Event command index. @@ -3504,33 +3541,14 @@ bool command_event(enum event_command cmd, void *data) break; #endif case CMD_EVENT_LOAD_STATE: - { -#ifdef HAVE_CHEEVOS - if (rcheevos_hardcore_active()) - { - const char *_msg = msg_hash_to_str(MSG_CHEEVOS_LOAD_STATE_PREVENTED_BY_HARDCORE_MODE); - runloop_msg_queue_push(_msg, strlen(_msg), 0, 180, true, NULL, - MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_WARNING); - return false; - } -#endif -#ifdef HAVE_NETWORKING - if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_TIMESKIP, NULL)) - return false; -#endif - if (!command_event_main_state(cmd)) - return false; - /* Run next frame to see the core output while paused */ - else if (runloop_st->flags & RUNLOOP_FLAG_PAUSED) - { - runloop_st->flags &= ~RUNLOOP_FLAG_PAUSED; - runloop_st->run_frames_and_pause = 1; - } + if (!handle_load_state_command_event()) + return false; + break; + case CMD_EVENT_LOAD_STATE_SLOT: + configuration_set_int(settings, settings->ints.state_slot, (int)data); -#if HAVE_RUNAHEAD - command_event(CMD_EVENT_PREEMPT_RESET_BUFFER, NULL); -#endif - } + if (!handle_load_state_command_event()) + return false; break; case CMD_EVENT_UNDO_LOAD_STATE: case CMD_EVENT_UNDO_SAVE_STATE: @@ -3668,6 +3686,12 @@ bool command_event(enum event_command cmd, void *data) if (!command_event_main_state(cmd)) return false; break; + case CMD_EVENT_SAVE_STATE_SLOT: + configuration_set_int(settings, settings->ints.state_slot, (int)data); + + if (!command_event_main_state(CMD_EVENT_SAVE_STATE)) + return false; + break; case CMD_EVENT_SAVE_STATE_DECREMENT: { int state_slot = settings->ints.state_slot; @@ -4361,7 +4385,7 @@ bool command_event(enum event_command cmd, void *data) video_driver_state_t *video_st = video_state_get_ptr(); rarch_system_info_t *sys_info = &runloop_st->system; - + /* Restore unpaused state */ runloop_st->paused_hotkey = false; command_event(CMD_EVENT_UNPAUSE, NULL); diff --git a/runloop.c b/runloop.c index 034214ee68ad..8e51a4d83c14 100644 --- a/runloop.c +++ b/runloop.c @@ -5510,6 +5510,15 @@ static bool display_menu_libretro( } #endif +#define DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(num) \ + { \ + if (settings->ints.savestate_max_direct_slot >= num) \ + { \ + HOTKEY_CHECK(RARCH_SAVE_STATE_SLOT ## num ## _KEY, CMD_EVENT_SAVE_STATE_SLOT, true, (void*)num); \ + HOTKEY_CHECK(RARCH_LOAD_STATE_SLOT ## num ## _KEY, CMD_EVENT_LOAD_STATE_SLOT, true, (void*)num); \ + } \ + } \ + #define HOTKEY_CHECK(cmd1, cmd2, cond, cond2) \ { \ static bool old_pressed = false; \ @@ -7053,6 +7062,18 @@ static enum runloop_state_enum runloop_check_state( HOTKEY_CHECK(RARCH_SAVE_STATE_KEY, CMD_EVENT_SAVE_STATE, true, NULL); HOTKEY_CHECK(RARCH_LOAD_STATE_KEY, CMD_EVENT_LOAD_STATE, true, NULL); + /* There may be a better way to do this - fix it up if so */ + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(0); + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(1); + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(2); + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(3); + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(4); + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(5); + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(6); + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(7); + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(8); + DIRECT_SAVESTATE_SLOT_HOTKEY_CHECKS(9); + /* Check VRR runloop hotkey */ HOTKEY_CHECK(RARCH_VRR_RUNLOOP_TOGGLE, CMD_EVENT_VRR_RUNLOOP_TOGGLE, true, NULL); diff --git a/ui/drivers/ui_qt_widgets.cpp b/ui/drivers/ui_qt_widgets.cpp index 5e53ef1c5949..f3606ca9bd6a 100644 --- a/ui/drivers/ui_qt_widgets.cpp +++ b/ui/drivers/ui_qt_widgets.cpp @@ -6251,6 +6251,7 @@ QWidget *SavingPage::widget() savesGroup->add(MENU_ENUM_LABEL_SORT_SAVEFILES_BY_CONTENT_ENABLE); savesGroup->add(MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE); + savestatesGroup->add(MENU_ENUM_LABEL_SAVESTATE_MAX_DIRECT_SLOT); savestatesGroup->add(MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX); autoSavestatesGroup->add(MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD);