mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-20 12:11:28 -07:00
111 lines
4.4 KiB
Markdown
111 lines
4.4 KiB
Markdown
# Overlay Controller Support Design
|
|
|
|
**Date:** 2026-03-11
|
|
**Backlog:** `TASK-159`
|
|
|
|
## Goal
|
|
|
|
Add controller support to the visible overlay through the Chrome Gamepad API without replacing the existing keyboard-only workflow. Controller input should only supplement keyboard-only mode, preserve existing behavior, and expose controller selection plus raw-input debugging in overlay-local modals.
|
|
|
|
## Scope
|
|
|
|
- Poll connected gamepads from the visible overlay renderer.
|
|
- Default to the first connected controller unless config specifies a preferred controller.
|
|
- Add logical controller bindings and tuning knobs to config.
|
|
- Add `Alt+C` controller selection modal.
|
|
- Add `Alt+Shift+C` controller debug modal.
|
|
- Map controller actions onto existing keyboard-only/Yomitan behaviors.
|
|
- Fix stale selected-token highlight cleanup when keyboard-only mode turns off or popup closes.
|
|
|
|
Out of scope for this pass:
|
|
|
|
- Raw arbitrary axis/button index remapping in config.
|
|
- Controller support outside the visible overlay renderer.
|
|
- Haptics or vibration.
|
|
|
|
## Architecture
|
|
|
|
Use a renderer-local controller runtime. The overlay already owns keyboard-only token selection, Yomitan popup integration, and modal UX, and the Gamepad API is browser-native. A renderer module can poll `navigator.getGamepads()` on animation frames, normalize sticks/buttons into logical actions, and call the same helpers used by keyboard-only mode.
|
|
|
|
Avoid synthetic keyboard events as the primary implementation. Analog sticks need deadzones, continuous smooth scrolling, and per-action repeat behavior that do not fit cleanly into key event emulation. Direct logical actions keep tests clear and make the debug modal show the exact values the runtime uses.
|
|
|
|
## Behavior
|
|
|
|
Controller actions are active only while keyboard-only mode is enabled, except the controller action that toggles keyboard-only mode can always fire so the user can enter the mode from the controller.
|
|
|
|
Default logical mappings:
|
|
|
|
- left stick vertical: smooth Yomitan popup/window scroll when popup is open
|
|
- left stick horizontal: move token selection left/right
|
|
- right stick vertical: smooth Yomitan popup/window scroll
|
|
- right stick horizontal: jump horizontally inside Yomitan popup/window
|
|
- `A`: toggle lookup
|
|
- `B`: close lookup
|
|
- `Y`: toggle keyboard-only mode
|
|
- `X`: mine card
|
|
- `L1` / `R1`: previous / next Yomitan audio
|
|
- `R2`: activate current Yomitan audio button
|
|
- `L2`: toggle mpv play/pause
|
|
|
|
Selection-highlight cleanup:
|
|
|
|
- disabling keyboard-only mode clears the selected token class immediately
|
|
- closing the Yomitan popup also clears the selected token class if keyboard-only mode is no longer active
|
|
- helper ownership should live in the shared keyboard-only selection sync path so keyboard and controller exits stay consistent
|
|
|
|
## Config
|
|
|
|
Add a top-level `controller` block in resolved config with:
|
|
|
|
- `enabled`
|
|
- `preferredGamepadId`
|
|
- `preferredGamepadLabel`
|
|
- `smoothScroll`
|
|
- `scrollPixelsPerSecond`
|
|
- `horizontalJumpPixels`
|
|
- `stickDeadzone`
|
|
- `triggerDeadzone`
|
|
- `repeatDelayMs`
|
|
- `repeatIntervalMs`
|
|
- `bindings` logical fields for the named actions/sticks
|
|
|
|
Persist the preferred controller by stable browser-exposed `id` when possible, with label stored as a diagnostic/display fallback.
|
|
|
|
## UI
|
|
|
|
Controller selection modal:
|
|
|
|
- overlay-hosted modal in the visible renderer
|
|
- lists currently connected controllers
|
|
- highlights current active choice
|
|
- selecting one persists config and makes it the active controller immediately if connected
|
|
|
|
Controller debug modal:
|
|
|
|
- overlay-hosted modal
|
|
- shows selected controller and all connected controllers
|
|
- live raw axis array values
|
|
- live raw button values, pressed flags, and touched flags if available
|
|
|
|
## Testing
|
|
|
|
Test first:
|
|
|
|
- controller gating outside keyboard-only mode
|
|
- logical mapping to existing helpers
|
|
- continuous stick scroll and repeat behavior
|
|
- modal open shortcuts
|
|
- preferred-controller selection persistence
|
|
- highlight cleanup on keyboard-only disable and popup close
|
|
- config defaults/parse/template generation coverage
|
|
|
|
## Risks
|
|
|
|
- Browser gamepad identity strings can differ across OS/browser/runtime versions.
|
|
Mitigation: match by exact preferred id first; fall back to first connected controller.
|
|
- Continuous stick input can spam actions.
|
|
Mitigation: deadzones plus repeat throttling and frame-time-based smooth scroll.
|
|
- Popup DOM/audio controls may vary.
|
|
Mitigation: target stable Yomitan popup/document selectors and cover with focused renderer tests.
|
|
|