Skip to content

Add portable mod.input tap, press and release controls - #143

Closed
Roxas2712 wants to merge 17 commits into
UNDERdecoded:mainfrom
Roxas2712:codex/portable-mod-input
Closed

Roxas2712 wants to merge 17 commits into
UNDERdecoded:mainfrom
Roxas2712:codex/portable-mod-input

Conversation

@Roxas2712

@Roxas2712 Roxas2712 commented Oct 23, 2026 •

Copy link
Copy Markdown

Mods ported from Gen1Recomp currently have no public way to request logical input on Gen2Recomped. Add mod.input:tap(game, button), mod.input:press(game, button) and mod.input:release(token) with the shared eight-button GB contract, for native API 1/2, unified API 2 and API 3.

Depends on #142 and its public-API prerequisites. Merge those first and rebase before merging. The new work is isolated in one commit: implementation-only diff. It does not require the rendering or shader PRs.

A tap queues an edge for the next fixed step without retaining its own held source. Press returns an opaque token; only its owning mod can release it, once. Separate tokens preserve keyboard, gamepad, overlay and other mod holds, and logical buttons ignore keyboard rebinding. The existing fixed-step Input loop is unchanged; these calls bypass raw input hooks and engine hotkeys.

Per-loader ownership handles rollback, reload, launcher teardown and every native Input reset. Reset retires tokens only for the affected Input instance while allowing new input afterward. Retired handles cannot issue new presses. Session-specific sources prevent old tokens from releasing replacement-session holds; outstanding holds remain available for teardown even if their caller loses its token/loader references. Reading the facade requires no Game/Input construction or graphics.

Includes general portability documentation, a shared example and a dedicated ROM-free workflow pinned to unmodified Gen1Recomp 79ea62f45fb2ea8f65d081a109431e4eb1bbdb36.

Validation:

  • 2,651 focused checks pass: all eight buttons, fixed-step edge lifetime/coalescing, multiple and foreign tokens, physical-source isolation, rebinding, malformed calls, source/session isolation, rollback, native focus/visibility/controller recovery, hot reload, teardown and orphan-hold cleanup after GC.
  • Lifecycle matrix covers all 15 Gen2Recomped host versions in API 1, native/unified API 2 and API 3. The headless suite also tests the facade with the development permission shim active.
  • Both engines load the exact same consumer entry chunk for two independent mods on Red, Gold, FireRed and Emerald. Native API 2, unified API 2 and API 3 pass on the feature and full integration heads: 48 isolated runs / 456 matching held/edge-state observations.
  • Combined previous-PR integration: 135/135 engine suites, SDK 3/3 and B30 pass.
  • Feature: 81/91 engine suites, versus dependency Add portable keyboard, gamepad and wheel input hooks #142's 78/88. The same 10 failing suites and 17 failed assertions are unchanged; no new failures. SDK 3/3 and B30 pass. The existing baseline-fix PRs are included in the green integration.
  • Existing input-hold regression: 26/26 checks. Formatting, workflow lint and diff checks pass.

Integration retains the existing world-action cancellation and viewport cleanup when combining the three Loader lifecycle insertion points. Already queued edges retain the normal Input semantics after release/owner cleanup; Input reset clears them. ROM-dependent tiers were skipped without imported data. These are headless contract/routing checks, with no physical-controller or OS-event-delivery claim.

Hosted workflows currently require maintainer approval (action_required): portable logical mod input contract, API 3 contracts, portable input hook contract, ci. No hosted pass is claimed.

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