The browser's Gamepad API works in Electron, so any standard XInput / DirectInput controller can drive XOSC.
How it works
XOSC polls all connected gamepads at 60 Hz. When a button transitions from "not pressed" to "pressed", it fires a binding event keyed by gpad:<padIndex>:btn:<buttonIndex>. Releases fire too — Hold mode uses them.
Axes (analog sticks, triggers) aren't bound as on/off triggers in this build. They're forwarded raw in the debug log so you can see what the hardware is doing.
Multiple pads
Two of the same gamepad model show up as Gamepad 1 and Gamepad 2, distinguishable by their pad index. Bindings are per-pad, so you can wire pad 1 button A to one OSC address and pad 2 button A to a different one.
Latency
Polling at 60 Hz means worst-case input latency before XOSC even sees the event is ~16 ms — well under perceptual threshold for stage triggering.