mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
runtime: controller host shortcut for fast-forward ([hotkeys] fast_forward_pad)
Turbo was keyboard-only ([KeyMap] Turbo, Tab). Add a third host shortcut the launcher can bind to a pad button or chord, next to Rewind and Save states: - main.cpp: PSX_ASSIST_BIND_FAST_FORWARD + "Fast-forward" label; default chord select+L1 (PSX_HOTKEY_PAD_SELECT_L1 = 1528); the manual fast-forward block now runs while either the keyboard key or the pad binding is held, through the same hotkey_pad_binding_down() matcher the other two use. Threaded through every settings hop (settings.toml -> globals -> launcher seed -> LauncherSettings -> back), mirroring save_state_menu_pad. - config_loader: [hotkeys] fast_forward_pad read/write, same pad_bind_value_ok bound as the siblings. - test_rewind_toggle_combo.py guards the new sites; README documents the chord. Launcher side: recomp-ui draws every advertised host shortcut instead of the first two (companion PR). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -755,7 +755,10 @@ The runtime models **authentic 1× CD-ROM timing by default** — the same read
|
||||
seek delays as real hardware. On top of that faithful baseline, load-time
|
||||
acceleration is **opt-in**, per game, so the accurate path is never compromised:
|
||||
|
||||
- **Turbo** — a hold-to-fast-forward key that compresses loads on demand.
|
||||
- **Turbo** — a hold-to-fast-forward key that compresses loads on demand
|
||||
(keyboard `[KeyMap] Turbo`, default Tab; controller `[hotkeys]
|
||||
fast_forward_pad`, default Select+L1, rebindable under the launcher's
|
||||
Controller → Host Shortcuts alongside Rewind and Save states).
|
||||
- **The "Fast Loading (host pacing)" and "CD Speed" mods** — automatic
|
||||
acceleration during load waits, shipped with every title and **off by
|
||||
default**, with `turbo_audio_sink` keeping the SPU timeline coherent through
|
||||
|
||||
@@ -2429,6 +2429,13 @@ UserSettings load_user_settings(const fs::path& path) {
|
||||
s.has_hotkey_pad_save_state_menu = true;
|
||||
}
|
||||
});
|
||||
if (h.contains("fast_forward_pad")) try_get([&]{
|
||||
const auto n = toml::find<int64_t>(h, "fast_forward_pad");
|
||||
if (pad_bind_value_ok(n)) {
|
||||
s.hotkey_pad_fast_forward = (int)n;
|
||||
s.has_hotkey_pad_fast_forward = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (doc.contains("launcher")) {
|
||||
const toml::value& l = toml::find(doc, "launcher");
|
||||
@@ -2672,13 +2679,16 @@ bool save_user_settings(const fs::path& path, const UserSettings& s) {
|
||||
f << "frequency = " << s.audio_freq << "\n";
|
||||
if (s.has_spu_hq)
|
||||
f << "spu_hq = " << (s.spu_hq ? "true" : "false") << "\n";
|
||||
if (s.has_hotkey_pad_rewind || s.has_hotkey_pad_save_state_menu) {
|
||||
if (s.has_hotkey_pad_rewind || s.has_hotkey_pad_save_state_menu ||
|
||||
s.has_hotkey_pad_fast_forward) {
|
||||
f << "\n[hotkeys]\n";
|
||||
if (s.has_hotkey_pad_rewind)
|
||||
f << "rewind_pad = " << s.hotkey_pad_rewind << "\n";
|
||||
if (s.has_hotkey_pad_save_state_menu)
|
||||
f << "save_state_menu_pad = "
|
||||
<< s.hotkey_pad_save_state_menu << "\n";
|
||||
if (s.has_hotkey_pad_fast_forward)
|
||||
f << "fast_forward_pad = " << s.hotkey_pad_fast_forward << "\n";
|
||||
}
|
||||
if (s.has_skip_launcher)
|
||||
f << "\n[launcher]\nskip_launcher = " << (s.skip_launcher ? "true" : "false") << "\n";
|
||||
|
||||
@@ -1262,6 +1262,9 @@ struct UserSettings {
|
||||
// RECOMP_LAUNCHER_PAD_* encoding (0 = unbound, 1+button, 100+axis).
|
||||
bool has_hotkey_pad_rewind = false; int hotkey_pad_rewind = 1272; /* select+r3 */
|
||||
bool has_hotkey_pad_save_state_menu = false; int hotkey_pad_save_state_menu = 2040; /* select+r1 */
|
||||
// fast_forward_pad: hold-to-fast-forward, the controller twin of the
|
||||
// keyboard [KeyMap] Turbo (Tab). 0 = unbound.
|
||||
bool has_hotkey_pad_fast_forward = false; int hotkey_pad_fast_forward = 1528; /* select+l1 */
|
||||
// [audio]
|
||||
bool has_spu_hq = false; bool spu_hq = false;
|
||||
bool has_audio_freq = false; int audio_freq = 44100;
|
||||
|
||||
+40
-2
@@ -1217,6 +1217,7 @@ static int g_rewind_depth = 50; /* local rewind snap count (50/100/1
|
||||
static int g_rewind_interval = 15; /* frames between snaps (1/4/8/12/15) */
|
||||
static int g_hotkey_pad_rewind = 1272; /* select + r3 */
|
||||
static int g_hotkey_pad_save_state_menu = 2040;/* select + r1 */
|
||||
static int g_hotkey_pad_fast_forward = 1528; /* select + l1 (hold) */
|
||||
static uint32_t g_savestate_input_guard_min_until = 0;
|
||||
static uint32_t g_savestate_input_guard_max_until = 0;
|
||||
static int g_headless = 0; /* debug/CI frontend: no SDL window/audio */
|
||||
@@ -5968,6 +5969,7 @@ static void depth24_stage_scanout(const GpuDisplayInfo *di, uint32_t *buf,
|
||||
enum {
|
||||
PSX_ASSIST_BIND_REWIND = 0,
|
||||
PSX_ASSIST_BIND_SAVE_STATE_MENU,
|
||||
PSX_ASSIST_BIND_FAST_FORWARD, /* hold-to-fast-forward; pad twin of [KeyMap] Turbo */
|
||||
PSX_ASSIST_BIND_COUNT
|
||||
};
|
||||
|
||||
@@ -5986,6 +5988,9 @@ enum {
|
||||
#define PSX_HOTKEY_PAD_SELECT_R1 \
|
||||
PSX_HOTKEY_PAD_BUTTON_COMBO(((uint32_t)1u << SDL_CONTROLLER_BUTTON_BACK) | \
|
||||
((uint32_t)1u << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER))
|
||||
#define PSX_HOTKEY_PAD_SELECT_L1 \
|
||||
PSX_HOTKEY_PAD_BUTTON_COMBO(((uint32_t)1u << SDL_CONTROLLER_BUTTON_BACK) | \
|
||||
((uint32_t)1u << SDL_CONTROLLER_BUTTON_LEFTSHOULDER))
|
||||
|
||||
static int normalize_hotkey_pad_binding(int binding, int fallback) {
|
||||
if (PSX_HOTKEY_PAD_IS_BUTTON(binding)) {
|
||||
@@ -6859,8 +6864,13 @@ static NetplayVblankEpilogue sdl_vblank_present_body(void) {
|
||||
const Uint8* keys = SDL_GetKeyboardState(NULL);
|
||||
static int turbo_skip = 0;
|
||||
static int turbo_was_down = 0;
|
||||
if (host_hotkey_input_focused() &&
|
||||
host_keymap_down(HOST_KEYMAP_TURBO, keys, (int)SDL_GetModState())) {
|
||||
/* Keyboard ([KeyMap] Turbo, default Tab) or the controller host
|
||||
* shortcut ([hotkeys] fast_forward_pad, default select+L1). Both are
|
||||
* hold-to-run; the pad chord goes through the same combo matcher as
|
||||
* Rewind / Save states so the launcher's binding editor covers it. */
|
||||
const bool kb_turbo = host_hotkey_input_focused() &&
|
||||
host_keymap_down(HOST_KEYMAP_TURBO, keys, (int)SDL_GetModState());
|
||||
if (kb_turbo || hotkey_pad_binding_down(g_hotkey_pad_fast_forward)) {
|
||||
const int mult = manual_fast_forward_multiplier();
|
||||
const int present_every = (mult < 0) ? 4 : (mult <= 4 ? 2 : 4);
|
||||
manual_turbo_active = true;
|
||||
@@ -10850,6 +10860,7 @@ namespace {
|
||||
static const char* const kPsxHostShortcutLabels[] = {
|
||||
"Rewind",
|
||||
"Save states",
|
||||
"Fast-forward",
|
||||
};
|
||||
|
||||
void ae_rui_set_sidecar_paths(const char* argv0) {
|
||||
@@ -11784,6 +11795,10 @@ int main(int argc, char** argv) {
|
||||
g_hotkey_pad_save_state_menu = normalize_hotkey_pad_binding(
|
||||
us.hotkey_pad_save_state_menu,
|
||||
PSX_HOTKEY_PAD_SELECT_R1);
|
||||
if (us.has_hotkey_pad_fast_forward)
|
||||
g_hotkey_pad_fast_forward = normalize_hotkey_pad_binding(
|
||||
us.hotkey_pad_fast_forward,
|
||||
PSX_HOTKEY_PAD_SELECT_L1);
|
||||
if (us.has_bios_path && !bios_from_cli && !us.bios_path.empty()) {
|
||||
settings_bios_storage = us.bios_path.string();
|
||||
bios_path = settings_bios_storage.c_str();
|
||||
@@ -12272,6 +12287,8 @@ int main(int argc, char** argv) {
|
||||
seed.has_hotkey_pad_rewind = true;
|
||||
seed.hotkey_pad_save_state_menu = g_hotkey_pad_save_state_menu;
|
||||
seed.has_hotkey_pad_save_state_menu = true;
|
||||
seed.hotkey_pad_fast_forward = g_hotkey_pad_fast_forward;
|
||||
seed.has_hotkey_pad_fast_forward = true;
|
||||
seed.skip_launcher = skip_launcher_setting; seed.has_skip_launcher = true;
|
||||
if (has_netplay_player_name) {
|
||||
seed.netplay_player_name = netplay_player_name;
|
||||
@@ -12452,6 +12469,9 @@ int main(int argc, char** argv) {
|
||||
ls.assist_pad_bind[PSX_ASSIST_BIND_SAVE_STATE_MENU] =
|
||||
normalize_hotkey_pad_binding(seed.hotkey_pad_save_state_menu,
|
||||
PSX_HOTKEY_PAD_SELECT_R1);
|
||||
ls.assist_pad_bind[PSX_ASSIST_BIND_FAST_FORWARD] =
|
||||
normalize_hotkey_pad_binding(seed.hotkey_pad_fast_forward,
|
||||
PSX_HOTKEY_PAD_SELECT_L1);
|
||||
ls.auto_skip_fmv = seed.auto_skip_fmv ? 1 : 0;
|
||||
ls.turbo_loads = seed.turbo_loads ? 1 : 0;
|
||||
/* Localization: index of resolved_language within lang_menu_options
|
||||
@@ -12741,6 +12761,10 @@ int main(int argc, char** argv) {
|
||||
ls.assist_pad_bind[PSX_ASSIST_BIND_SAVE_STATE_MENU],
|
||||
PSX_HOTKEY_PAD_SELECT_R1);
|
||||
seed.has_hotkey_pad_save_state_menu = true;
|
||||
seed.hotkey_pad_fast_forward = normalize_hotkey_pad_binding(
|
||||
ls.assist_pad_bind[PSX_ASSIST_BIND_FAST_FORWARD],
|
||||
PSX_HOTKEY_PAD_SELECT_L1);
|
||||
seed.has_hotkey_pad_fast_forward = true;
|
||||
seed.auto_skip_fmv = ls.auto_skip_fmv != 0;
|
||||
seed.has_auto_skip_fmv = skip_fmv_offered;
|
||||
seed.turbo_loads = ls.turbo_loads != 0;
|
||||
@@ -12958,6 +12982,9 @@ int main(int argc, char** argv) {
|
||||
g_hotkey_pad_save_state_menu = seed.has_hotkey_pad_save_state_menu
|
||||
? seed.hotkey_pad_save_state_menu
|
||||
: PSX_HOTKEY_PAD_SELECT_R1;
|
||||
g_hotkey_pad_fast_forward = seed.has_hotkey_pad_fast_forward
|
||||
? seed.hotkey_pad_fast_forward
|
||||
: PSX_HOTKEY_PAD_SELECT_L1;
|
||||
skip_launcher_setting = seed.skip_launcher;
|
||||
if (seed.has_bios_path) {
|
||||
settings_bios_storage = seed.bios_path.string();
|
||||
@@ -14444,6 +14471,10 @@ soft_return_lobby:
|
||||
normalize_hotkey_pad_binding(
|
||||
g_hotkey_pad_save_state_menu,
|
||||
PSX_HOTKEY_PAD_SELECT_R1);
|
||||
ls.assist_pad_bind[PSX_ASSIST_BIND_FAST_FORWARD] =
|
||||
normalize_hotkey_pad_binding(
|
||||
g_hotkey_pad_fast_forward,
|
||||
PSX_HOTKEY_PAD_SELECT_L1);
|
||||
ls.aspect_index = (g_video_aspect_num * 9 == g_video_aspect_den * 21) ? 2
|
||||
: (g_video_aspect_num == 16 && g_video_aspect_den == 9) ? 1 : 0;
|
||||
ls.language_index = 0;
|
||||
@@ -14737,6 +14768,10 @@ soft_return_lobby:
|
||||
ls.assist_pad_bind[PSX_ASSIST_BIND_SAVE_STATE_MENU],
|
||||
PSX_HOTKEY_PAD_SELECT_R1);
|
||||
us.has_hotkey_pad_save_state_menu = true;
|
||||
us.hotkey_pad_fast_forward = normalize_hotkey_pad_binding(
|
||||
ls.assist_pad_bind[PSX_ASSIST_BIND_FAST_FORWARD],
|
||||
PSX_HOTKEY_PAD_SELECT_L1);
|
||||
us.has_hotkey_pad_fast_forward = true;
|
||||
us.auto_skip_fmv = ls.auto_skip_fmv != 0;
|
||||
us.has_auto_skip_fmv = skip_fmv_offered;
|
||||
us.turbo_loads = ls.turbo_loads != 0;
|
||||
@@ -14817,6 +14852,9 @@ soft_return_lobby:
|
||||
g_hotkey_pad_save_state_menu = normalize_hotkey_pad_binding(
|
||||
ls.assist_pad_bind[PSX_ASSIST_BIND_SAVE_STATE_MENU],
|
||||
PSX_HOTKEY_PAD_SELECT_R1);
|
||||
g_hotkey_pad_fast_forward = normalize_hotkey_pad_binding(
|
||||
ls.assist_pad_bind[PSX_ASSIST_BIND_FAST_FORWARD],
|
||||
PSX_HOTKEY_PAD_SELECT_L1);
|
||||
switch (ls.aspect_index) {
|
||||
case 2: g_video_aspect_num = 21; g_video_aspect_den = 9; break;
|
||||
case 1: g_video_aspect_num = 16; g_video_aspect_den = 9; break;
|
||||
|
||||
@@ -40,4 +40,19 @@ assert "bool manual_turbo_active = false;" in MAIN
|
||||
assert "Fast forward: %dx" in MAIN
|
||||
assert "g_frame_period_ms / (double)mult" in MAIN
|
||||
|
||||
# Fast-forward has a controller host shortcut alongside the keyboard Turbo key:
|
||||
# a select+L1 chord by default, routed through the same combo matcher, offered
|
||||
# to the launcher as the third host-shortcut row, and persisted as
|
||||
# [hotkeys] fast_forward_pad.
|
||||
assert "static int g_hotkey_pad_fast_forward = 1528;" in MAIN
|
||||
assert "PSX_HOTKEY_PAD_SELECT_L1" in MAIN
|
||||
assert "PSX_ASSIST_BIND_FAST_FORWARD" in MAIN
|
||||
assert "if (kb_turbo || hotkey_pad_binding_down(g_hotkey_pad_fast_forward)) {" in MAIN
|
||||
assert MAIN.count("ls.assist_pad_bind[PSX_ASSIST_BIND_FAST_FORWARD]") == \
|
||||
MAIN.count("ls.assist_pad_bind[PSX_ASSIST_BIND_SAVE_STATE_MENU]")
|
||||
assert '"Fast-forward",' in MAIN
|
||||
CFG = (ROOT / "recompiler" / "src" / "config_loader.cpp").read_text(encoding="utf-8")
|
||||
assert 'h.contains("fast_forward_pad")' in CFG # settings.toml read
|
||||
assert 'f << "fast_forward_pad = "' in CFG # settings.toml write
|
||||
|
||||
print("host shortcut guard passed")
|
||||
|
||||
Reference in New Issue
Block a user