Input Interfaces¶
An input interface reads controller data from a specific source and normalizes it into the common input_event_t format. Once normalized, input events are submitted to the router for delivery to outputs.
Every input -- whether a USB gamepad, a Bluetooth controller, a SNES pad wired directly to GPIO, or a phone connected over WiFi -- produces the same event structure. This is what makes Joypad OS universal: any input can drive any output.
All Input Interfaces¶
| Input | Protocol | Location | Method | Notes |
|---|---|---|---|---|
| USB HID | USB 2.0 | src/usb/usbh/hid/ |
TinyUSB host stack | Gamepads, keyboards, mice, hubs. Vendor-specific drivers for Xbox, PlayStation, Nintendo, 8BitDo, HORI, Logitech, Sega, Raphnet, and more. |
| XInput | USB 2.0 | src/usb/usbh/xinput/ |
TinyUSB host stack | Xbox 360, Xbox One, Xbox Series controllers via XInput protocol. |
| Bluetooth | BT Classic + BLE | src/bt/ |
BTstack | Wireless controllers via USB BT dongle (RP2040), built-in radio (Pico W), or BLE (ESP32-S3, nRF52840). Per-vendor drivers mirror USB HID structure. |
| WiFi (JOCP) | UDP/TCP over WiFi | src/wifi/jocp/ |
LWIP | Joypad Open Controller Protocol. Adapter runs as WiFi AP on Pico W. UDP port 30100 for input, TCP port 30101 for control. |
| SNES | Shift register (GPIO) | src/native/host/snes/ |
GPIO polling | SNES and NES controllers, SNES mouse, Xband keyboard. Also used for NES via compatible shift register protocol. |
| N64 | Joybus (PIO) | src/native/host/n64/ |
PIO state machine | N64 controllers. Supports rumble pak. Y-axis inverted during normalization. |
| GameCube | Joybus (PIO) | src/native/host/gc/ |
PIO state machine | GameCube controllers. Supports rumble. Y-axis inverted during normalization. Polls at 125Hz. |
| NES | PIO | src/native/host/nes/ |
PIO state machine | NES controllers via dedicated PIO program. |
| Neo Geo | GPIO (active-low) | src/native/host/arcade/ |
GPIO polling | Neo Geo arcade sticks. Internal pull-ups, active-low button reads. |
| LodgeNet | PIO | src/native/host/lodgenet/ |
PIO state machine | LodgeNet hotel system controllers. Supports N64, GameCube, and SNES controller types on the LodgeNet bus. |
| 3DO Host | PIO | src/native/host/3do/ |
PIO state machine | Reads 3DO controllers directly. |
| Nuon Host | Polyface (PIO) | (experimental) | PIO state machine | Reads Nuon controllers. Experimental support. |
| GPIO | GPIO pins | src/native/device/gpio/ |
GPIO polling | Custom-wired buttons and analog sticks for bespoke controller builds (Fisher Price, Alpakka, etc.). |
| UART | Serial | src/native/host/uart/ |
UART RX | Input bridge from external microcontrollers (e.g., ESP32 Bluetooth bridge). |
How Input Interfaces Work¶
Each input interface implements the InputInterface struct:
typedef struct {
const char* name;
input_source_t source;
void (*init)(void);
void (*task)(void);
bool (*is_connected)(void);
uint8_t (*get_device_count)(void);
} InputInterface;
init()is called once during startup to configure hardware (USB host, PIO programs, GPIO pins, etc.).task()is called every iteration of the Core 0 main loop. It polls for new data and callsrouter_submit_input()when a controller reports.is_connected()andget_device_count()let the system track active controllers.
Normalization Rules¶
All input drivers follow these rules when building input_event_t:
- Buttons use
JP_BUTTON_*constants in W3C Gamepad API order. See the Glossary for the full mapping. - Analog axes are normalized to 0-255 with 128 as center. 0 = up/left, 255 = down/right (HID convention).
- Y-axis: Drivers for Nintendo-convention controllers (N64, GameCube) must invert the Y axis during normalization.
- Device address: USB devices use TinyUSB's
dev_addr. Bluetooth uses addresses assigned by BTstack. Native controllers use the 0xD0+ range.
Supported Controllers¶
USB and Bluetooth inputs support a wide range of controllers through vendor-specific drivers. Generic HID parsing handles any standard-compliant gamepad automatically. Vendor-specific drivers provide enhanced support (rumble, LEDs, analog triggers) for:
- Microsoft: Xbox 360, Xbox One, Xbox Series, Xbox Adaptive Controller
- Sony: DualShock 3, DualShock 4, DualSense, DualSense Edge
- Nintendo: Switch Pro, Joy-Con, GameCube adapter, NES/SNES Online
- 8BitDo: Pro 2, Ultimate, Lite, Zero, M30, SN30, and more
- HORI: Fighting Commander, RAP, HORIPAD
- Logitech: F310, F710
- Sega: Saturn/Genesis USB pads
- Raphnet: N64/GC to USB adapters
- Many more via generic HID
See the controllers list for the full compatibility table.
Next Steps¶
- Architecture -- Where inputs fit in the system
- Data Flow -- How input events travel to outputs
- Output Interfaces -- The other side of the pipeline
- Apps -- How apps select which inputs to use