mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-20 04:31:09 +02:00
feat(nx-mods): fire display hotkeys from Select+face chords
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,6 +9,7 @@ local Renderer = require("src.render.Renderer")
|
|||||||
local SaveData = require("src.core.SaveData")
|
local SaveData = require("src.core.SaveData")
|
||||||
local StateStack = require("src.core.StateStack")
|
local StateStack = require("src.core.StateStack")
|
||||||
local TouchControls = require("src.core.TouchControls")
|
local TouchControls = require("src.core.TouchControls")
|
||||||
|
local GamepadMap = require("src.core.GamepadMap")
|
||||||
local ModLoader = require("src.mods.Loader")
|
local ModLoader = require("src.mods.Loader")
|
||||||
local ModRuntime = require("src.mods.Runtime")
|
local ModRuntime = require("src.mods.Runtime")
|
||||||
local Screens = require("src.ui.Screens")
|
local Screens = require("src.ui.Screens")
|
||||||
@@ -489,6 +490,23 @@ function Game:gamepadpressed(joystick, button)
|
|||||||
top:onGamepadPressed(button)
|
top:onGamepadPressed(button)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
-- Select+face display chords → same digit path as Game:keypressed
|
||||||
|
-- (COLORS/TILT/pipelines). Intercept before Input so face does not
|
||||||
|
-- also fire GB A/B. Dual-path: raw already ignored when isGamepad().
|
||||||
|
local selectHeld = Input:isDown("select")
|
||||||
|
if not selectHeld and joystick and joystick.isGamepadDown then
|
||||||
|
local ok, down = pcall(function()
|
||||||
|
return joystick:isGamepadDown("back")
|
||||||
|
end)
|
||||||
|
selectHeld = ok and down == true
|
||||||
|
end
|
||||||
|
if selectHeld then
|
||||||
|
local digit = GamepadMap.displayChordDigit(button)
|
||||||
|
if digit then
|
||||||
|
self:keypressed(digit)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
Input:gamepadpressed(joystick, button)
|
Input:gamepadpressed(joystick, button)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
-- Select+face chords fire Game:keypressed digits (NXMOD-06..10).
|
||||||
|
-- Spec: Select held + A/B/Y/X/L → keys 2/3/5/6/7; without Select, face stays GB.
|
||||||
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||||
|
if not _G.love then _G.love = require("tests.love_stub") end
|
||||||
|
|
||||||
|
local T = require("tests.harness")
|
||||||
|
local check = T.check
|
||||||
|
local eq = T.eq
|
||||||
|
|
||||||
|
local Game = require("src.core.Game")
|
||||||
|
local Input = require("src.core.Input")
|
||||||
|
local GamepadMap = require("src.core.GamepadMap")
|
||||||
|
|
||||||
|
local joy = {
|
||||||
|
isGamepad = function() return true end,
|
||||||
|
isGamepadDown = function(_, button) return false end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local digits = {}
|
||||||
|
local padForwarded = {}
|
||||||
|
local wroteOptions = false
|
||||||
|
|
||||||
|
local origKeypressed = Game.keypressed
|
||||||
|
local origPad = Input.gamepadpressed
|
||||||
|
local origWrite = Game.writeOptions
|
||||||
|
|
||||||
|
function Game:keypressed(key)
|
||||||
|
digits[#digits + 1] = key
|
||||||
|
-- Mimic digit persistence side-effect for keys that write options.
|
||||||
|
if key == "2" or key == "3" or key == "5" or key == "6" or key == "7" then
|
||||||
|
wroteOptions = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Input:gamepadpressed(joystick, button)
|
||||||
|
padForwarded[#padForwarded + 1] = button
|
||||||
|
return origPad(self, joystick, button)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function resetSpies()
|
||||||
|
digits = {}
|
||||||
|
padForwarded = {}
|
||||||
|
wroteOptions = false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function holdSelect()
|
||||||
|
Input:init()
|
||||||
|
-- Press Select (SDL back) into Input so isDown("select") is true.
|
||||||
|
origPad(Input, joy, "back")
|
||||||
|
Input:step()
|
||||||
|
check(Input:isDown("select"), "Select held via Input")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- --- Without Select: face buttons keep normal GB path (NXMOD-09) ---
|
||||||
|
GamepadMap._setForceNXForTests(false)
|
||||||
|
Input:init()
|
||||||
|
resetSpies()
|
||||||
|
Game:gamepadpressed(joy, "a")
|
||||||
|
eq(#digits, 0, "no digit without Select")
|
||||||
|
eq(#padForwarded, 1, "face reaches Input without Select")
|
||||||
|
eq(padForwarded[1], "a", "Input receives face a")
|
||||||
|
check(not wroteOptions, "no options write without Select chord")
|
||||||
|
|
||||||
|
-- --- Select + face → same digit path as PC keys (NXMOD-06..08, NXMOD-10) ---
|
||||||
|
local chordCases = {
|
||||||
|
{ button = "a", digit = "2", label = "Select+A -> 2" },
|
||||||
|
{ button = "b", digit = "3", label = "Select+B -> 3" },
|
||||||
|
{ button = "y", digit = "5", label = "Select+Y -> 5" },
|
||||||
|
{ button = "x", digit = "6", label = "Select+X -> 6" },
|
||||||
|
{ button = "leftshoulder", digit = "7", label = "Select+L -> 7" },
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, case in ipairs(chordCases) do
|
||||||
|
holdSelect()
|
||||||
|
resetSpies()
|
||||||
|
Game:gamepadpressed(joy, case.button)
|
||||||
|
eq(#digits, 1, case.label .. " fires keypressed once")
|
||||||
|
eq(digits[1], case.digit, case.label)
|
||||||
|
eq(#padForwarded, 0, case.label .. " does not forward face to Input")
|
||||||
|
check(wroteOptions, case.label .. " uses digit options path")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- --- NX Nintendo UX: physical A (SDL b) → 2, physical B (SDL a) → 3 ---
|
||||||
|
GamepadMap._setForceNXForTests(true)
|
||||||
|
holdSelect()
|
||||||
|
resetSpies()
|
||||||
|
Game:gamepadpressed(joy, "b") -- physical Nintendo A
|
||||||
|
eq(digits[1], "2", "NX Select+physical A (SDL b) -> key 2")
|
||||||
|
eq(#padForwarded, 0, "NX chord A does not forward face")
|
||||||
|
check(wroteOptions, "NX chord A options path")
|
||||||
|
|
||||||
|
holdSelect()
|
||||||
|
resetSpies()
|
||||||
|
Game:gamepadpressed(joy, "a") -- physical Nintendo B
|
||||||
|
eq(digits[1], "3", "NX Select+physical B (SDL a) -> key 3")
|
||||||
|
eq(#padForwarded, 0, "NX chord B does not forward face")
|
||||||
|
|
||||||
|
-- Without Select on NX, face still goes to Input (no accidental cycle).
|
||||||
|
Input:init()
|
||||||
|
resetSpies()
|
||||||
|
Game:gamepadpressed(joy, "b")
|
||||||
|
eq(#digits, 0, "NX no digit without Select")
|
||||||
|
eq(#padForwarded, 1, "NX face reaches Input without Select")
|
||||||
|
|
||||||
|
-- Dual-path Select: joystick isGamepadDown("back") also counts as held.
|
||||||
|
GamepadMap._setForceNXForTests(false)
|
||||||
|
Input:init()
|
||||||
|
resetSpies()
|
||||||
|
local joySelectDown = {
|
||||||
|
isGamepad = function() return true end,
|
||||||
|
isGamepadDown = function(_, button) return button == "back" end,
|
||||||
|
}
|
||||||
|
Game:gamepadpressed(joySelectDown, "y")
|
||||||
|
eq(digits[1], "5", "Select via isGamepadDown(back) + Y -> 5")
|
||||||
|
eq(#padForwarded, 0, "isGamepadDown Select chord does not forward face")
|
||||||
|
|
||||||
|
GamepadMap._setForceNXForTests(false)
|
||||||
|
Game.keypressed = origKeypressed
|
||||||
|
Input.gamepadpressed = origPad
|
||||||
|
Game.writeOptions = origWrite
|
||||||
|
|
||||||
|
T.finish()
|
||||||
Reference in New Issue
Block a user