mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
fix(switch): restore pad cursor in Touch Controls and launcher overlays
Opening Touch Controls dropped the launcher virtual cursor and swallowed gamepad input while touch still worked. Share PadCursor with the save editor, forward pad events, and centralize overlay handoff/resume so both hosts park and re-arm the pointer cleanly. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -156,6 +156,41 @@ do
|
||||
check(desk._padCursorActive, "desktop parkNxPointerForHost is a no-op")
|
||||
end
|
||||
|
||||
-- ------- Overlay handoff / resume (Edit Save + Touch Controls)
|
||||
|
||||
do
|
||||
mouseX, mouseY = 9, 10
|
||||
local imp = freshImporter(true)
|
||||
imp.launcher = true
|
||||
stickRight(imp, 3)
|
||||
check(imp._padCursorActive, "pad active before overlay handoff")
|
||||
check(imp._nxPointerBridge, "bridge on before overlay handoff")
|
||||
imp:prepareOverlayHandoff()
|
||||
check(not imp._padCursorActive, "prepareOverlayHandoff clears pad")
|
||||
check(not imp._nxPointerBridge, "prepareOverlayHandoff clears NX bridge")
|
||||
check(imp._flex == nil, "prepareOverlayHandoff clears flex without FlexLove")
|
||||
local gx, gy = love.mouse.getPosition()
|
||||
eq(gx, 9, "after overlay handoff getPosition is real mouse X")
|
||||
eq(gy, 10, "after overlay handoff getPosition is real mouse Y")
|
||||
|
||||
local prevCount = love.joystick and love.joystick.getJoystickCount
|
||||
love.joystick = love.joystick or {}
|
||||
love.joystick.getJoystickCount = function() return 1 end
|
||||
imp:resumeAfterOverlay()
|
||||
check(imp._padCursorActive, "NX resumeAfterOverlay re-arms pad with a stick")
|
||||
love.joystick.getJoystickCount = function() return 0 end
|
||||
imp._padCursorActive = false
|
||||
imp:resumeAfterOverlay()
|
||||
check(not imp._padCursorActive, "resumeAfterOverlay stays latent with no stick")
|
||||
love.joystick.getJoystickCount = prevCount
|
||||
|
||||
local desk = freshImporter(false)
|
||||
desk.launcher = true
|
||||
desk._padCursorActive = true
|
||||
desk:prepareOverlayHandoff()
|
||||
check(not desk._padCursorActive, "desktop prepareOverlayHandoff clears pad too")
|
||||
end
|
||||
|
||||
-- ------- Desktop: setPosition still warps (unchanged path)
|
||||
|
||||
do
|
||||
@@ -228,6 +263,10 @@ do
|
||||
"RomImporter owns NX getPosition bridge")
|
||||
check(impSrc:find("function RomImporter:parkNxPointerForHost", 1, true) ~= nil,
|
||||
"RomImporter exports parkNxPointerForHost")
|
||||
check(impSrc:find("function RomImporter:prepareOverlayHandoff", 1, true) ~= nil,
|
||||
"RomImporter exports prepareOverlayHandoff")
|
||||
check(impSrc:find("function RomImporter:resumeAfterOverlay", 1, true) ~= nil,
|
||||
"RomImporter exports resumeAfterOverlay")
|
||||
check(impSrc:find("if not self.isNX then", 1, true) ~= nil,
|
||||
"NX skips desktop mouse-yield path")
|
||||
check(impSrc:find("if not self.isNX and love.mouse.setPosition", 1, true) ~= nil,
|
||||
@@ -236,8 +275,10 @@ do
|
||||
"NX clamps pad cursor dt")
|
||||
|
||||
local mainSrc = read("main.lua")
|
||||
check(mainSrc:find("parkNxPointerForHost", 1, true) ~= nil,
|
||||
"openEditor parks NX pointer before save editor")
|
||||
check(mainSrc:find("prepareOverlayHandoff", 1, true) ~= nil,
|
||||
"openEditor / Touch Controls use prepareOverlayHandoff")
|
||||
check(mainSrc:find("resumeAfterOverlay", 1, true) ~= nil,
|
||||
"close paths resume the launcher pad cursor")
|
||||
|
||||
check(view:find("math.floor(x + 0.5)", 1, true) ~= nil,
|
||||
"NX pad cursor draw is pixel-snapped")
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
-- Touch-controls editor pad / Joy-Con cursor (same class as save-editor soft-lock).
|
||||
-- Opening Touch Controls parked the launcher cursor and dropped all gamepad
|
||||
-- input; touch still worked. PadCursor + main.lua forwarding restore the
|
||||
-- virtual pointer.
|
||||
-- luajit tests/engine/touch_controls_pad_cursor_test.lua
|
||||
|
||||
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, eq = T.check, T.eq
|
||||
|
||||
local PadCursor = require("src.ui.PadCursor")
|
||||
local GamepadMap = require("src.core.GamepadMap")
|
||||
|
||||
PadCursor.reset()
|
||||
PadCursor.gamepadaxis(nil, "leftx", 1)
|
||||
PadCursor.update(0.05)
|
||||
check(PadCursor.isActive(), "left stick activates pad cursor")
|
||||
local x0 = select(1, PadCursor.pointer())
|
||||
PadCursor.update(0.05)
|
||||
check(select(1, PadCursor.pointer()) > x0, "left stick moves cursor right")
|
||||
|
||||
eq(PadCursor.gamepadpressed(nil, "a"), "a", "gamepad a → click")
|
||||
eq(PadCursor.gamepadpressed(nil, "b"), "b", "gamepad b → close")
|
||||
eq(PadCursor.gamepadpressed(nil, "leftshoulder"), "tab_prev", "L → size down")
|
||||
eq(PadCursor.gamepadpressed(nil, "rightshoulder"), "tab_next", "R → size up")
|
||||
|
||||
GamepadMap._setForceNXForTests(true)
|
||||
eq(PadCursor.gamepadpressed(nil, "a"), "b", "NX SDL a (south) → close (GB b)")
|
||||
eq(PadCursor.gamepadpressed(nil, "b"), "a", "NX SDL b (east) → click (GB a)")
|
||||
GamepadMap._setForceNXForTests(false)
|
||||
|
||||
PadCursor.yieldToPointer()
|
||||
check(not PadCursor.isActive(), "yieldToPointer drops the virtual cursor")
|
||||
|
||||
-- Compat: tools/save-editor/PadInput.lua re-exports the shared module.
|
||||
package.path = package.path .. ";./tools/save-editor/?.lua"
|
||||
local PadInput = require("PadInput")
|
||||
eq(PadInput, PadCursor, "PadInput shim is PadCursor")
|
||||
|
||||
local function read(path)
|
||||
local f = assert(io.open(path, "r"))
|
||||
local src = f:read("*a")
|
||||
f:close()
|
||||
return src
|
||||
end
|
||||
|
||||
local mainSrc = read("main.lua")
|
||||
check(mainSrc:find("prepareOverlayHandoff", 1, true) ~= nil
|
||||
and mainSrc:find("openTouchControlsEditor", 1, true) ~= nil,
|
||||
"main.lua mentions prepareOverlayHandoff + touch editor")
|
||||
-- prepare must run inside openTouchControlsEditor, not only openEditor
|
||||
local touchOpen = mainSrc:match("local function openTouchControlsEditor%(%)(.-)\nend")
|
||||
check(touchOpen ~= nil, "openTouchControlsEditor body found")
|
||||
check(touchOpen:find("prepareOverlayHandoff", 1, true) ~= nil,
|
||||
"openTouchControlsEditor prepares overlay handoff like the save editor")
|
||||
local touchClose = mainSrc:match("function closeTouchControlsEditor%(%)(.-)\nend")
|
||||
check(touchClose ~= nil, "closeTouchControlsEditor body found")
|
||||
check(touchClose:find("resumeAfterOverlay", 1, true) ~= nil,
|
||||
"closeTouchControlsEditor resumes the launcher pad cursor")
|
||||
check(mainSrc:find("TouchEditor.gamepadpressed", 1, true) ~= nil,
|
||||
"main.lua forwards gamepadpressed to TouchEditor")
|
||||
check(mainSrc:find("TouchEditor.gamepadaxis", 1, true) ~= nil,
|
||||
"main.lua forwards gamepadaxis to TouchEditor")
|
||||
|
||||
local edSrc = read("src/ui/TouchControlsEditor.lua")
|
||||
check(edSrc:find('require("src.ui.PadCursor")', 1, true) ~= nil,
|
||||
"TouchControlsEditor loads PadCursor")
|
||||
check(edSrc:find("function Editor.gamepadpressed", 1, true) ~= nil,
|
||||
"TouchControlsEditor exposes gamepadpressed")
|
||||
check(edSrc:find("PadCursor.draw()", 1, true) ~= nil,
|
||||
"TouchControlsEditor draws the pad cursor")
|
||||
check(edSrc:find("PadCursor.yieldToPointer()", 1, true) ~= nil,
|
||||
"touch/mouse yields the pad so taps use event coords")
|
||||
check(edSrc:find('beginDrag("pad"', 1, true) ~= nil,
|
||||
"A begins a pad drag at the virtual cursor")
|
||||
check(edSrc:find('endDrag("pad")', 1, true) ~= nil,
|
||||
"A release ends a pad drag")
|
||||
|
||||
local packSrc = read("scripts/pack_love.sh")
|
||||
check(packSrc:find("tools/save-editor/PadInput.lua", 1, true) ~= nil,
|
||||
"pack still requires PadInput path (compat shim)")
|
||||
|
||||
T.finish("touch_controls_pad_cursor")
|
||||
Reference in New Issue
Block a user