fix(input): ignore raw face presses when Joy-Con is gamepad

love-nx emits gamepad+raw on one press; NamingScreen saw a+b and always
erased. Skip raw when isGamepad(); align NX Y→a/X→b; prefer A if both.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Andrew Quenehen
2026-08-01 04:15:47 -03:00
parent 925b224eda
commit efd81d8e34
6 changed files with 89 additions and 24 deletions
+16 -4
View File
@@ -16,11 +16,13 @@ GamepadMap.RAW_BUTTON_BINDINGS = {
[7] = "select", [8] = "start", [9] = "select", [10] = "start",
}
-- Switch OLED probe 2026-08-01: love.joystickpressed indices (1-based).
-- Gamepad path still preferred when isGamepad(); raw covers the rest.
-- Switch OLED: love.joystickpressed indices (1-based). Used only when the
-- device is NOT a gamepad — love-nx also emits gamepadpressed for Joy-Con,
-- and applying both face paths in one frame breaks NamingScreen (a+b).
-- Y→a / X→b matches operator OLED naming diagnosis (2026-08-01).
GamepadMap.NX_RAW_BUTTON_BINDINGS = {
[1] = "a", [2] = "b",
[3] = "b", [4] = "a",
[3] = "a", [4] = "b",
[9] = "select", [10] = "start",
}
@@ -32,7 +34,7 @@ GamepadMap.RAW_TO_GAMEPAD_BUTTON = {
GamepadMap.NX_RAW_TO_GAMEPAD_BUTTON = {
[1] = "a", [2] = "b",
[3] = "y", [4] = "x",
[3] = "a", [4] = "b",
[9] = "back", [10] = "start",
}
@@ -54,6 +56,16 @@ function GamepadMap.mapGamepadButton(button)
return GamepadMap.DEFAULT_GAMEPAD_BINDINGS[button]
end
-- love-nx / SDL: when isGamepad(), face+menu already arrive via gamepad*.
-- Applying joystickpressed raw on top double-fires GB A/B in one frame.
function GamepadMap.ignoreRawForJoystick(joystick)
if not joystick then return false end
local ok, isPad = pcall(function()
return joystick.isGamepad and joystick:isGamepad()
end)
return ok and isPad == true
end
function GamepadMap.mapRawButton(index)
if nxActive() then
local nx = GamepadMap.NX_RAW_BUTTON_BINDINGS[index]
+2
View File
@@ -180,11 +180,13 @@ function Input:gamepadreleased(joystick, button)
end
function Input:joystickpressed(joystick, button)
if GamepadMap.ignoreRawForJoystick(joystick) then return end
local btn = GamepadMap.mapRawButton(button)
if btn then press(self, btn, "joy:" .. button) end
end
function Input:joystickreleased(joystick, button)
if GamepadMap.ignoreRawForJoystick(joystick) then return end
local btn = GamepadMap.mapRawButton(button)
if btn then release(self, btn, "joy:" .. button) end
end
+2
View File
@@ -1548,11 +1548,13 @@ function RomImporter:gamepadaxis(_, axis, value)
end
function RomImporter:joystickpressed(joystick, button)
if GamepadMap.ignoreRawForJoystick(joystick) then return end
local padButton = GamepadMap.mapRawToGamepadButton(button)
if padButton then self:gamepadpressed(joystick, padButton) end
end
function RomImporter:joystickreleased(joystick, button)
if GamepadMap.ignoreRawForJoystick(joystick) then return end
local padButton = GamepadMap.mapRawToGamepadButton(button)
if padButton then self:gamepadreleased(joystick, padButton) end
end
+22 -15
View File
@@ -153,21 +153,28 @@ function NamingScreen:update(dt)
if self.row ~= caseRow then
self.col = self.col < #GRID[self.row] and self.col + 1 or 1
end
elseif input:wasPressed("b") then
table.remove(self.glyphs)
elseif input:wasPressed("a") then
if self.row == edRow and self.col == edCol then
self:confirm()
return
end
if self.row == caseRow then
self.lower = not self.lower
return
end
if #self.glyphs < self.maxLen then
Sound.play(self.game.data, "Press_AB")
table.insert(self.glyphs, GRID[self.row][self.col])
if #self.glyphs >= self.maxLen then self:jumpToEnd() end
else
-- Prefer A over B when both edges fire in one frame (love-nx dual
-- gamepad+raw path historically set both; erase must not win).
local pressedA = input:wasPressed("a")
local pressedB = input:wasPressed("b")
if pressedA and pressedB then pressedB = false end
if pressedB then
table.remove(self.glyphs)
elseif pressedA then
if self.row == edRow and self.col == edCol then
self:confirm()
return
end
if self.row == caseRow then
self.lower = not self.lower
return
end
if #self.glyphs < self.maxLen then
Sound.play(self.game.data, "Press_AB")
table.insert(self.glyphs, GRID[self.row][self.col])
if #self.glyphs >= self.maxLen then self:jumpToEnd() end
end
end
end
end