WIP: fix(input): stop automatic title presses after manual takeover #659
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
beanstalk: approved @ 1697603
beanstalk: approved @ 2c5a62e
beanstalk: approved @ 4fd82b7
beanstalk: approved @ 64d6d09
beanstalk: approved @ 6f91fae
beanstalk: approved @ 70a78f9
beanstalk: approved @ 8d361dc
beanstalk: approved @ 9d8356e
beanstalk: approved @ abf2227
beanstalk: approved @ d82f202
beanstalk: approved @ e5f1e40
beanstalk: approved @ ee8ab5f
ci: approved
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/macos
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
regression
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
ci: approved
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!659
Loading…
Reference in a new issue
No description provided.
Delete branch "NitnekLeBorgne/Longshot-contributions:fix/autoload-physical-takeover-20261115"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type: fix · Risk: medium · Tested on: Linux, native game-free C fixtures with synthetic devices · Needs: complete game-free suite, Windows host validation and manual gameplay check
Why
With Skip title screen enabled, an automatic A press can arrive after the player has started navigating manually. A physical button at the scheduling poll can also lose the race: the old shared tap queue already contains the automatic press for a later poll.
This addresses the manual-takeover part of #587. It does not accelerate loading, shorten the initial 20-second delay or claim that the game is ready earlier. See #587; the broader startup-speed request remains open.
How to reproduce
Seen on: Linux, game-free C fixtures compiling real input/scheduler code with explicit synthetic device callbacks and a synthetic save marker, not a user's save.
Settings and switches: Skip title screen On in the fixture; no game, GPU or external input injection.
Steps: begin controller polling, provide an accepted physical button at 15 seconds, release it, then poll beyond 20 seconds. Also exercise physical input at the exact scheduling poll and while an automatic pulse is already held.
Expected: manual takeover cancels only automatic title-screen input for the session.
Actual: on main a later automatic A is still delivered. The fixture reproduces the unwanted press; no new in-game reproduction or startup timing measurement is claimed.
What changed
Stop automatic title-screen button presses when accepted physical game input takes over. Keep scripted input and the existing automatic-navigation safeguards intact.
host/oot_autoload.c/.h: keep automatic title presses on their own channel instead of the shared host/script tap queue. Expose cancellation and query behavior while retaining reset and the existing scheduler safeguards.host/nn_hid.c: accepted physical input cancels that channel before the final input merge. Queued script, bridge and other host input are not purged. Input excluded by the existing routing rules does not count as takeover.tests/test_skip_title.pyand newtests/test_autoload_takeover_587.py: scheduler/channel, same-poll takeover, held pulse, scripted-input controls and reset/option/player/menu/timeout cases.tests/test_walk_key.py: maintain the Walk-only extraction boundary for the new cancel/merge helpers, without changing Walk product logic or assertions.The original first-press delay of 20,000 ms, repeat interval of 2,000 ms, hold of 200 ms and give-up time of 120,000 ms are preserved. Automatic input is merged after physical-input classification, rather than being confused with the shared queue. Reset rearms the channel; an already-cancelled session is not silently rearmed by ordinary polling.
Settings scope: No new flag or setting. With Skip title screen enabled, accepted physical game input now takes over and stops the automatic channel. Existing option-Off, no-save, player-seen, menu-pause and timeout safeguards remain covered.
Measurements
Verdict: real-source synthetic fixtures reproduce unwanted automatic A presses on the original source and pass with the corrected channel. The same-poll and active-hold cases are covered, rather than only checking an earlier activity timestamp.
Hardware: Linux game-free fixtures; no GPU/driver used; CPU and RAM not reported in these receipts.
Scene: Synthetic regression/control inputs, not a game scene.
Method: Functional outcomes from the adopted receipts below, not timing benchmarks; no fabricated repetitions or medians.
How to reproduce: Replay the named focused tests described below on the pinned baseline and candidate with identical fixtures.
6c9edffe5d97e53e1b6fBaseline: main
6c9edffe5da1f5b5383977aeab3f544c0de25d4c. Focused native coverage is reported by family, not by mixing assertion/method/replay totals:A private broken-Walk control compiles successfully, then fails the retained speed/diagonal assertions. Fixture-link failures are recorded separately from behavioral REDs: main's old missing scheduler stand-in and the candidate's newly required mock dependencies are not presented as new gameplay bugs. Source/test snapshots, complete native streams, hashes, commands and exits were retained.
No FPS, loading-time, real-device or wall-clock performance benefit is claimed.
Flags and settings
None
Testing
Tested: Linux, game-free C fixtures with authored keyboard/pad/mouse spies. Cases cover early/same-poll/held takeover, accepted versus ignored/exclusive/background input, script/host queue preservation, no-save, reset, option changes, player state, menu pause, timeout and dead-zone controls. Source-contract and Walk assertions are preserved. Clean application reproduces the six candidate files and Git modes. Independent SPEC and QUALITY reviewed the exact final patch statically, without claiming replays.
Not tested: complete
python -I -B tests/run_all.py, full host build, native Windows build/link/run, a real game, physical controllers, direct native mouse-camera behavior or performance. Mouse-motion fixture coverage demonstrates accepted as-stick routing through a spy, not native camera behavior. This PR remains WIP.Must be tested:
python -I -B tests/run_all.py --jobs 1, recording missing tools and named baseline failures (by hand), expecting the full suite to pass or each shared main failure to be named (by hand: an equipped contributor/tester inspects diagnostics and the stated outcomes before merge; not executed by this documentation edit).Integration notes: existing Walk fixture work
The pre-existing empty
hos_oot_autoload_input()stand-in is already the subject of PR #497 and is also carried by PR #537. That old scheduler-only repair is not an independently discovered fix here and is not a separate contribution or quota item.This patch retains that stand-in as necessary support for the coherent Walk-only fixture boundary and additionally supplies the new
hos_hid_autoload_cancel/autoload_mergestand-ins introduced by this feature. The existing Walk assertions, extraction and behavior are unchanged. Please preserve the existing PR497/537 work when integrating these common lines; this is not a competing Walk feature. Other open keyboard/control changes are not claimed tested in combination with this patch.Risks
What could break: intentional physical input during automatic navigation now cancels the automatic channel for that session. Device acceptance/background/exclusive routing remains the boundary; this is not a concurrency stress qualification or an earlier-ready detector.
Turning it off: disable Skip title screen, or revert the commit.
Compatibility: no save contents, ini schema, shader/pipeline cache or renderer ABI changes. Only the private host autoload interface and its extraction fixtures change.
Issues
See #587.
Checklist
Everyone
type(scope): description) of the status line's type.main.python -I -B tests/run_all.pypasses (any failure that also fails onmainis named).third_party/untouched (a new folder with aPROVENANCE.mdinstead).When it applies
Assisted-by:/Co-Authored-By:trailers.mainand passing here.tests/that reads changed source updated in this PR, not weakened.Related open restart/resume work
PR #61 changes the same scheduler/HID integration for restart-in-place continuation. Its forced continuation intentionally isolates player input until the restart completes; its ordinary Skip title path is described separately. This manual-takeover patch is qualified only on the named main baseline, not on a combined branch with PR61. Preserve that forced-continuation contract when integrating the two; do not blindly apply ordinary Skip title cancellation to the restart-only sequence.
The exact neighboring head inspected was
2d90704de1410e9bae7e3bf99fd191231088bb61. The API reported current main as its base, while its actual Git merge-base with the named main was1be60eae813865b0845fb8bb05b1d7cb9b39e51f; those are retained as distinct provenance. No combined build, conflict resolution or gameplay behavior is claimed. This additional integration limitation is one more reason to keep the PR WIP.#61
Readiness provenance and checklist notes
Current main in the frozen public readback is
aa95d35f3d021b27328b6d68109666a46c340aee; this PR head is97e53e1b6f889cc466174cc5c2bffe5646bb38ed. The current-main box is unchecked: historical publication/base checks are not proof of current ancestry. Current-main updating and revalidation are needed before ready, but rebase/force-push/merge are not authorized; no such operation is promised or performed. The full runner box remains unchecked; no full-suite run or Windows/host qualification is claimed by this description edit. The normal project pr ready remains blocked and must not be forced. Manual pre-merge plans are future work, not completed evidence.Historical checklist explanations (not current-main qualification):
type(scope): description) of the status line's type, after the WIP prefix.main(exact unchanged base checked before publication).python -I -B tests/run_all.pypasses (not run; WIP, focused results only).third_party/untouched.@NitnekLeBorgne Thanks for your attention to my issue this is a great commit that removes user confusion.
May I ask is there any technical blocker to implementing a fast “A” press to enter the title screen quickly, followed by an auto-click to start faster?
Thanks! The current autoload is timer-driven: it starts A presses 20 seconds after the first controller read, retries every 2 seconds, and stops when the player is running or after 120 seconds. It does not detect when the title screen/file list is ready for each press.
A reliable faster sequence would need earlier timings or screen-readiness detection to be validated, rather than assuming the fixed delays can simply be reduced. I have not tested shorter timings, so I cannot claim either that reducing those delays is safe or that there is a fundamental blocker. This PR deliberately only fixes manual takeover/cancellation; a fast-start change should stay separate and preserve that cancellation behavior.
97e53e1b6fb45ba4f8a4@NitnekLeBorgne Thanks for the reply! You're right — other implementations are out of scope here, and keeping this PR focused makes sense. Still, I'd love it if you could revisit the direct-loading vs. auto-click approach down the road; it would make a real difference for the gaming experience. Thanks again!
Rebased onto
main@bbe6fdf: no conflicts. No tests were run here; the test boxes stay yours.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.