Skip to content

fix(gui): stop discarding presses made during a screen transition - #292

Merged
NathanNeurotic merged 1 commit into
masterfrom
claude/transition-input-blackout
Jul 29, 2026
Merged

fix(gui): stop discarding presses made during a screen transition#292
NathanNeurotic merged 1 commit into
masterfrom
claude/transition-input-blackout

Conversation

@NathanNeurotic

@NathanNeurotic NathanNeurotic commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Press a direction right after switching screens and nothing happens.

Found while investigating #271, verified in code, and separate from that report — it can only fire during a screen fade, which continuous same-screen scrolling never hits.

The bug

guiMainLoop() polls the pads every frame (gui.c:2448) but only runs screenHandler->handleInput() when no transition is in flight (gui.c:2468). A fade is 26 frames — ~430 ms at 60 Hz — and every poll during it still advanced the key-on baseline. The edge gets consumed by a poll with nothing listening behind it, and the press is simply gone.

Fix

padFreezeEdgeBaseline() holds the edge baseline while a transition runs, so a key-on raised during the fade is still pending when the new screen takes over.

Freezing the baseline rather than skipping the poll is deliberate. readPads() also expires rumble taps, drives the pad state machine and detects (dis)connects — not calling it during a transition would leave a motor spinning and a replug unnoticed.

Scope

Armed only while screenHandlerTarget is set. Ordinary same-screen navigation is untouched, deliberately: the #271/#272 read-miss work is on hardware test right now and this must not perturb what's being measured.

Residual

A press that is also released inside the fade is still lost, because the edge view reflects the current sample by then. Fixing that needs a sticky pending-press latch — which is the correct long-term design for this input layer, and would also fix the "tap falls entirely between two polls" half of zackcage6's hang — but it changes edge consumption everywhere and should not land mid-test.

Verification

  • make clean && make opl.elf green on ps2dev:latest; clang-format clean
  • padFreezeEdgeBaseline confirmed linked into opl.elf via nm
  • Not hardware-tested. Reproduce by pressing a direction immediately after a screen switch.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Preserved button presses made during screen transitions.
    • Prevented input from being missed or consumed before the next screen appears.
    • Improved key press and release detection across transition effects.

Press a direction right after switching screens and nothing happens. Found while
investigating #271; verified in code, and separate from that report.

guiMainLoop() polls the pads EVERY frame (gui.c) but only runs
screenHandler->handleInput() when no transition is in flight. A fade is 26
frames -- about 430 ms at 60 Hz -- and every poll during it still advanced the
key-on baseline, so the edge was consumed by a poll with nothing listening
behind it. The press is simply gone.

FIX. padFreezeEdgeBaseline() holds the edge baseline while a transition is
running, so a key-on raised during the fade is still pending when the new screen
takes over.

Freezing the BASELINE rather than skipping the poll is deliberate: readPads()
also expires rumble taps, drives the pad state machine and detects
(dis)connects, so not calling it during a transition would leave a motor
spinning and a replug unnoticed.

Scope: armed ONLY while screenHandlerTarget is set. Ordinary same-screen
navigation is untouched, deliberately -- the #271/#272 read-miss work is on
hardware test right now and this must not perturb what is being measured.

Residual: a press that is also RELEASED inside the fade is still lost, since the
edge view reflects the current sample by then. Fixing that needs a sticky
pending-press latch, which is the correct long-term design for this input layer
but changes edge consumption everywhere and should not land mid-test.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0aac55c4-eaf7-463b-9d02-1427aef93328

📥 Commits

Reviewing files that changed from the base of the PR and between 4994a33 and 08cf5a8.

📒 Files selected for processing (3)
  • include/pad.h
  • src/gui.c
  • src/pad.c
📜 Recent review details
⏰ Context from checks skipped due to timeout. (11)
  • GitHub Check: github-advanced-security
  • GitHub Check: build-debug (eesio_debug, @sha256:c64ae69c9817865ed98ff054e4ae5360b9e280ed952c97946bca95d9d35be995)
  • GitHub Check: build-debug (ingame_debug, @sha256:c64ae69c9817865ed98ff054e4ae5360b9e280ed952c97946bca95d9d35be995)
  • GitHub Check: build-debug (iopcore_ppctty_debug, @sha256:c64ae69c9817865ed98ff054e4ae5360b9e280ed952c97946bca95...
  • GitHub Check: build-variants (EXTRA_FEATURES=0, PADEMU=0)
  • GitHub Check: check-format
  • GitHub Check: Analyze (actions)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (c-cpp)
  • GitHub Check: check-format
  • GitHub Check: build-lang
🧰 Additional context used
🪛 Cppcheck (2.21.0)
src/pad.c

[style] 209-209: The function 'padFreezeEdgeBaseline' is never used.

(unusedFunction)

🔇 Additional comments (3)
include/pad.h (1)

25-28: LGTM!

src/pad.c (2)

189-212: LGTM!


993-996: 🎯 Functional Correctness

Preserve the frozen sample until the first active input handler.

The current handoff only works if the new screen handles input using the final frozen readPads() result. Otherwise, the first unfrozen poll advances oldedgedata to the already-sampled button state and suppresses getKeyOn().

  • src/pad.c#L993-L996: Defer the baseline snapshot or otherwise preserve the pre-transition baseline until the first handleInput() call.
  • src/gui.c#L2342-L2345: Ensure guiMainLoop() delivers the final frozen sample before releasing the baseline.

📝 Walkthrough

Walkthrough

Adds a pad edge-baseline freeze API, applies it during GUI screen transitions, and prevents readPads() from advancing oldedgedata while frozen so key-on edges remain available to the next screen.

Changes

Pad edge transition handling

Layer / File(s) Summary
Edge baseline control
include/pad.h, src/pad.c
Adds padFreezeEdgeBaseline(int freeze) and the internal edgeBaselineFrozen state.
Transition input preservation
src/gui.c, src/pad.c
guiReadPads() freezes the baseline while a screen transition target exists, and readPads() conditionally updates oldedgedata.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main fix: preserving presses during screen transitions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/transition-input-blackout

Comment @coderabbitai help to get the list of available commands.

@NathanNeurotic
NathanNeurotic merged commit c0fa7eb into master Jul 29, 2026
66 checks passed
@NathanNeurotic
NathanNeurotic deleted the claude/transition-input-blackout branch July 29, 2026 04:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant