Add configurable analog-trigger → stick mapping (closes #1006)#1110
Add configurable analog-trigger → stick mapping (closes #1006)#1110jonnylitten wants to merge 5 commits into
Conversation
Adds a TriggerMapper module that runs after each emulated controller's ProcessInputData, with a rstick_y_split mode that drives the right-stick Y axis from the analog triggers (RT -> +Y, LT -> -Y). Per-controller opt-in via a base-class flag so controllers without analog triggers aren't affected. DS4 is wired up; other controllers can opt in by populating m_left/right_trigger_raw and setting m_supports_trigger_map. The digital ZL/ZR thresholds default to "off" because in this mode the trigger is exclusively an analog-stick input — Grid Autosport and Mario Sunshine read the analog axis, not ZR/ZL — but they remain configurable for users who want e.g. a near-full pull to also fire the digital button. Configuration lives in a new [trigger_map] section of missioncontrol.ini. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends TriggerMapper with per-title and per-controller overrides on top of the global default. Profiles live in: sdmc:/config/MissionControl/controllers/<lowercase-mac>.ini sdmc:/config/MissionControl/titles/<16-hex-program-id>.ini each containing the same [trigger_map] section the global config supports. Resolution is profile-level (not field-merged): per-title beats per-controller beats global, and the first match is used wholesale. The active title is read from the existing mcmitm_process_monitor (no new event subscription needed), so per-title profiles take effect on the next packet after the title switch. Files in the override directories are scanned eagerly at boot during LoadConfiguration, with malformed names or unparseable .ini files silently skipped. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In rstick_y_split mode the Y axis of the right stick is overwritten every packet by the trigger-derived value, so the physical stick's up/down motion is otherwise dead input. New stick_y_to_buttons_threshold field captures the physical Y *before* the overwrite and fires ZR (up past threshold) / ZL (down) digitally. Defaults off so existing profiles are unaffected; useful in racing games where you want the same thumb that's holding the throttle stick to also do gear shifts via stick taps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…title switch LoadDirectoryProfiles previously ran only at boot, so a new /config/MissionControl/titles/<program-id>.ini dropped onto the SD card after the sysmodule was already running had no effect until the next reboot. This commit adds a dedicated low-priority background thread that waits on the existing mcmitm_process_monitor process-switch event and re-runs LoadDirectoryProfiles on each title transition. All filesystem I/O happens on that thread; the bluetooth input path (TriggerMapper::Apply) only takes the mutex and reads the resolved profile. State is protected by os::SdkMutex (matching the rest of the mc.mitm sysmodule's mutex convention). Hardware-verified on DS4 — clean cold boot, stable operation, and new ini files dropped onto the SD card while the sysmodule is running are picked up on the next title switch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… overrides Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
d7c80f5 to
185680c
Compare
|
Force-pushed an updated commit for the hot-reload feature — the previous version was buggy, and I want to be thorough about it: The original hot-reload commit ( The replacement (
Hardware-verified on DS4 (the same setup as the rest of the PR): clean cold boot, stable through gameplay, and a freshly-dropped Apologies for the churn during your review window. Rest of the PR (slices 1 / 2 / 2.5 + the README docs commit) is unchanged. |
Generalises the proof-of-concept analog-trigger remap discussed in #1006 into a fully configurable feature with per-game and per-controller overrides.
What it does
The existing per-controller HID conversion converts analog triggers into the digital ZR/ZL bits and discards the analog value. Games like Grid Autosport read throttle / brake off the right-stick analog Y axis rather than ZR/ZL, so handing them the digital bit gives on/off throttle with no graduated control. This PR adds an opt-in post-hook to
EmulatedSwitchController::UpdateControllerStatethat maps a controller's raw analog trigger value back onto the right-stick Y axis before the report is dispatched.Configuration
New
[trigger_map]section inmissioncontrol.ini:Per-game overrides:
/config/MissionControl/titles/<16-hex-program-id>.ini. Per-controller:/config/MissionControl/controllers/<lowercase-MAC>.ini. Both directories are re-scanned on every title switch (using the existingmcmitm_process_monitorAPI) so adding a game profile takes effect on next launch without a sysmodule restart. Precedence: per-title > per-controller > global, profile-level (no field merging).Architecture
A new
TriggerMapper(mc_mitm/source/controllers/trigger_mapper.{hpp,cpp}) holds the resolved-profile state and runs afterProcessInputDatainEmulatedSwitchController::UpdateControllerState. Per-controller subclasses opt in by (1) settingm_supports_trigger_map = truein their constructor orInitialize, and (2) populatingm_left_trigger_raw/m_right_trigger_raw(u16, 0–0xFFFF) in theirMapInputReportXxxfrom the controller's native trigger format. Subclasses that don't opt in are unaffected —Applyearly-returns and the existing ZR/ZL threshold path is unchanged.Testing status
Hardware-verified on DualShock 4 (via a GameSir G8 Galileo Plus emulating a DS4, in handheld mode). The
[trigger_map]section parses correctly and the directory hot-reload behaves correctly across title switches.Only DS4 is opted in in this PR — happy to fan out to other controllers in a follow-up once the foundation lands, with your preference on which to enable.
Commits
Structured as five reviewable commits: (1) core feature + DS4 wiring + global config, (2) layered per-title/per-controller profiles, (3) stick-Y → digital ZR/ZL repurposing, (4) hot-reload on title switch, (5) README docs.
If you'd prefer narrower scope (e.g. just the core feature for now, follow-ups for layered config and stick-Y), happy to split.