fix(input): Nintendo A/B face map on NX

SDL labels south as a and east as b; on Switch remap so physical A
confirms and physical B cancels in launcher and NamingScreen.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Andrew Quenehen
2026-08-01 04:24:57 -03:00
parent efd81d8e34
commit 2699c9a2f9
6 changed files with 63 additions and 29 deletions
+23 -5
View File
@@ -1,4 +1,5 @@
-- When isGamepad(), raw face presses must not stack on gamepad* (NamingScreen a+b).
-- On NX, SDL face labels are swapped so physical A confirms / B cancels.
package.path = "./?.lua;./?/init.lua;" .. package.path
if not _G.love then _G.love = require("tests.love_stub") end
@@ -20,23 +21,40 @@ check(GamepadMap.ignoreRawForJoystick(gamepadJoy), "ignore raw when isGamepad")
check(not GamepadMap.ignoreRawForJoystick(rawJoy), "allow raw when not gamepad")
check(not GamepadMap.ignoreRawForJoystick(nil), "nil joystick does not ignore raw")
-- Desktop: SDL a → GB A (unchanged).
eq(GamepadMap.mapGamepadButton("a"), "a", "desktop SDL a -> GB A")
eq(GamepadMap.mapGamepadButton("b"), "b", "desktop SDL b -> GB B")
GamepadMap._setForceNXForTests(true)
eq(GamepadMap.mapRawButton(3), "a", "NX raw Y (#3) -> GB A")
eq(GamepadMap.mapRawButton(4), "b", "NX raw X (#4) -> GB B")
eq(GamepadMap.mapGamepadButton("a"), "b", "NX SDL south (a) -> GB B (Nintendo B)")
eq(GamepadMap.mapGamepadButton("b"), "a", "NX SDL east (b) -> GB A (Nintendo A)")
eq(GamepadMap.mapRawButton(1), "b", "NX raw #1 Nintendo B -> GB B")
eq(GamepadMap.mapRawButton(2), "a", "NX raw #2 Nintendo A -> GB A")
eq(GamepadMap.mapRawButton(3), nil, "NX raw Y (#3) not mapped as confirm")
eq(GamepadMap.mapRawButton(4), nil, "NX raw X (#4) not mapped as confirm")
GamepadMap._setForceNXForTests(false)
Input:init()
Input:gamepadpressed(gamepadJoy, "a")
Input:joystickpressed(gamepadJoy, 1) -- must no-op
Input:joystickpressed(gamepadJoy, 2) -- must no-op (would have set b)
Input:joystickpressed(gamepadJoy, 2) -- must no-op
Input:step()
check(Input:wasPressed("a"), "gamepad A edge present")
check(Input:wasPressed("a"), "desktop gamepad A edge present")
check(not Input:wasPressed("b"), "raw must not add B alongside gamepad A")
check(Input:isDown("a"), "A held from pad source only")
-- NX: physical A arrives as SDL "b" → GB A.
GamepadMap._setForceNXForTests(true)
Input:init()
Input:gamepadpressed(gamepadJoy, "b")
Input:step()
check(Input:wasPressed("a"), "NX physical A (SDL b) confirms as GB A")
check(not Input:wasPressed("b"), "NX physical A must not also erase")
GamepadMap._setForceNXForTests(false)
Input:init()
Input:joystickpressed(rawJoy, 1)
Input:step()
check(Input:wasPressed("a"), "non-gamepad raw #1 still maps to A")
check(Input:wasPressed("a"), "non-gamepad raw #1 still maps to A on desktop")
T.finish()
+7 -6
View File
@@ -1,4 +1,4 @@
-- NX raw fallback indices measured on OLED hardware (SWNX-11).
-- NX raw fallback + Nintendo face remap (SWNX-11).
package.path = "./?.lua;./?/init.lua;" .. package.path
if not _G.love then _G.love = require("tests.love_stub") end
@@ -9,11 +9,12 @@ local GamepadMap = require("src.core.GamepadMap")
GamepadMap._setForceNXForTests(true)
-- Phase 0 / naming diagnosis: Y→#3→a, X→#4→b; Nintendo B/A at #1/#2.
eq(GamepadMap.mapRawButton(3), "a", "NX raw Y (#3) maps to GB A")
eq(GamepadMap.mapRawButton(4), "b", "NX raw X (#4) maps to GB B")
eq(GamepadMap.mapRawToGamepadButton(3), "a", "NX raw #3 routes to gamepad a")
eq(GamepadMap.mapRawToGamepadButton(4), "b", "NX raw #4 routes to gamepad b")
eq(GamepadMap.mapGamepadButton("b"), "a", "NX physical A (SDL b) -> GB A")
eq(GamepadMap.mapGamepadButton("a"), "b", "NX physical B (SDL a) -> GB B")
eq(GamepadMap.mapRawButton(1), "b", "NX raw #1 Nintendo B -> GB B")
eq(GamepadMap.mapRawButton(2), "a", "NX raw #2 Nintendo A -> GB A")
eq(GamepadMap.mapRawToGamepadButton(1), "a", "NX raw #1 routes as SDL south name")
eq(GamepadMap.mapRawToGamepadButton(2), "b", "NX raw #2 routes as SDL east name")
eq(GamepadMap.mapRawButton(9), "select", "NX minus (#9) -> select")
eq(GamepadMap.mapRawButton(10), "start", "NX plus (#10) -> start")