diff --git a/systems/input/controls_manager.gd b/systems/input/controls_manager.gd index 8e1a7ea..4e4d3fe 100644 --- a/systems/input/controls_manager.gd +++ b/systems/input/controls_manager.gd @@ -22,10 +22,26 @@ const REBINDABLE_ACTIONS: PackedStringArray = [ func _ready() -> void: + _ensure_gamepad_confirm_binding() load_saved() _install_web_fullscreen_hook() +## Godot's built-in ui_accept (menu/button confirm) ships with zero joypad bindings — +## checked directly: only Enter/Kp Enter/Space. ui_left/right/up/down, by contrast, do +## default to the D-pad and stick, which is why gamepad focus navigation on a menu works out +## of the box while "confirming" the focused button does nothing. Bind both the Xbox-style +## bottom face button (A, index 0) and the right-hand one (B, index 1 — physically labelled +## "A" on a Nintendo-layout pad, since SDL/browser gamepad mapping normalizes to Xbox +## *position*, not the printed label) so either the common "confirm" button works. +func _ensure_gamepad_confirm_binding() -> void: + for button_index in [JOY_BUTTON_A, JOY_BUTTON_B]: + var alt := InputEventJoypadButton.new() + alt.button_index = button_index + if not InputMap.action_has_event(&"ui_accept", alt): + InputMap.action_add_event(&"ui_accept", alt) + + # ── Web fullscreen + landscape lock ───────────────────────────────────────────── # The reliable way to force fullscreen on the web: install a NATIVE DOM listener that calls # requestFullscreen() synchronously inside the real user-gesture event — the same thing