mirror of
https://github.com/safijari/openpuck.git
synced 2026-11-03 22:30:22 +00:00
[PR #309] Add on-controller paddle profiles and paddle-assign mode #278
Labels
No labels
pull-request
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
safijari/openpuck#278
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
📋 Pull Request Information
Original PR: https://github.com/safijari/openpuck/pull/309
Author: @cadenabelcannon-ctrl
Created: 10/9/2026
Status: 🔄 Open
Base:
main← Head:paddle-profiles📝 Commits (1)
2f078e0Add on-controller paddle profiles and paddle-assign mode📊 Changes
7 files changed (+497 additions, -2 deletions)
View changed files
📝
OpenPuck/OpenPuck.ino(+4 -0)📝
OpenPuck/config.cpp(+3 -0)📝
OpenPuck/haptics.cpp(+15 -2)📝
OpenPuck/haptics.h(+3 -0)➕
OpenPuck/paddle_profiles.cpp(+434 -0)➕
OpenPuck/paddle_profiles.h(+32 -0)📝
OpenPuck/rf_link.cpp(+6 -0)📄 Description
Adds back-paddle profiles and a paddle-assign mode that work entirely from the controller, so remapping the paddles on a console no longer needs the board plugged into a computer for the WebUSB panel.
What it does
In the emulated modes (Xbox, Switch, DS4, DS5, and their variants):
Paddle-assign mode: no input reaches the host. Tap a paddle (1 buzz), then tap the button it should act as (2 buzzes = saved). Tapping the same paddle twice turns it off (3 buzzes). The mode closes itself after 30 s of no input. Any button can be a target, including LT/RT. QAM maps to Capture on Switch and Touchpad Click on PlayStation.
Steam, Lizard, DirectInput and SInput are untouched: the gesture code returns early when
g_etype == ET_NONE.How it's stored
g_type[et].back(cfg.bin), so every mode builder and the WebUSB panel work unchanged. The panel simply edits whichever profile is active./paddles.bin, which leaves theCfglayout alone. Older firmware still readscfg.binfine.saveCfg()also flushes/paddles.bin, so a mode switch or panel save inside that window still keeps the two files in step.Changes to existing code
rf_link.cpp: one call topaddleProfilesOnInput()just before the existing back-4 chord masking. While back-4 is held, it masks LB/RB/Start fromg_inand the raw report. In assign mode it blanks all buttons and triggers.haptics.cpp: splits the tail ofhapticSteamRumble()into a staticrumbleRelay(), and addshapticFeedback(). This buzzes at a fixed strength, bypassing rumble style/strength and the per-type rumble toggle, so the confirmation is felt even with game rumble off.hapticSteamRumble()behavior is unchanged.config.cpp:saveCfg()callspaddleProfilesSaveIfDirty().OpenPuck.ino: loads profiles afterloadCfg()and callspaddleProfilesTask()fromloop().The existing back-4 + face/D-pad mode chords are unaffected.
Testing
millis/LittleFS/haptics. This covered gesture debounce, wraparound, assign-mode taps (including trigger targets and the same-paddle-twice off), the timeout, persistence across a simulated reboot, and panel edits surviving a profile switch. It also checked that Steam mode is untouched and that nothing fires while the host is suspended.make checkpasses, andmake buildadds about 3 KB of flash and 128 B of RAM.Possible follow-ups
The panel doesn't show which profile is active or let you edit the non-active profiles yet. Happy to add that if you'd like the feature.
Like the rest of the project, this was written with an LLM (Claude).
🤖 Generated with Claude Code
https://claude.ai/code/session_01C5Vr8e7sDDjZ2byXQ7fQMY
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.