The Open-Source Firmware Platform for Game Controllers and Adapters
Build controller adapters, custom controllers, and assistive input devices —
on microcontrollers, not computers.
This fork of Joypad OS adds support for PlayStation 4 (DS4) Emulation with Local Authentication.
Unlike the main repository which only supports PS4 without authentication (which makes it work for 8 minutes only), this version allows for Local RSA Authentication. This means you can use your adapter on a PS4 by using cryptographic keys extracted from a real DualShock 4.
- Buttons: Some games may have trouble recognizing the L2 and Options buttons (e.g., tested and confirmed issues in FC26).
- Fighting Games: This fork has been extensively tested and works perfectly with fighting games, including Street Fighter and various Capcom Collections.
- Setup: To enable local authentication, you must upload your own controller keys.
For controllers that lack a dedicated touchpad button (like many Bluetooth controllers), you can use the following shortcuts:
- R1 + Options/Start: Simulates a Touchpad click.
- Touchpad (or R1 + Options/Start) + D-Pad Left: Simulates a Left Touchpad click.
- Touchpad (or R1 + Options/Start) + D-Pad Right: Simulates a Right Touchpad click.
This allows full compatibility with games that require specific touchpad interactions (left/right side clicks).
To use local authentication, you need to upload three specific files from a genuine DualShock 4 controller:
key.prm(Private Key)serial.txt(Controller Serial Number)sig.bin(Sony Device Signature)
Use the provided web tool located at:
lucasleal.dev/joypad-os-ds4/tools/ps4-auth-upload/ps4_auth_upload.html
Simply open this link in a WebHID-compatible browser (like Chrome or Edge), connect your Joypad OS device via USB, and follow the instructions to upload your keys to the device's flash memory.
Joypad OS is firmware that runs on small microcontroller boards (RP2040, ESP32-S3, nRF52840) — the kind you'd find inside a controller or adapter, not on a PC. You flash it onto a chip and it handles everything: reading controllers, translating protocols, routing inputs to outputs, and managing button remapping.
What you can build with it:
- Controller adapters — Use any modern USB or Bluetooth controller on retro consoles (GameCube, Dreamcast, PCEngine, 3DO, and more) or convert retro controllers to USB
- Custom controllers — Wire up buttons, sticks, and sensors to a microcontroller and get a USB gamepad that works everywhere
- Assistive gaming setups — Merge multiple input devices (switches, joysticks, eye trackers) into a single controller output using flexible input routing
- Wireless adapters — Turn any Bluetooth controller into a wired USB gamepad for low-latency play
Under the hood, Joypad OS normalizes every input source into a common format, routes it through configurable player slots, and translates it into whatever output protocol the target needs — from retro console protocols bit-banged via PIO to modern USB HID and XInput.
Formerly known as USBRetro.
- Download the latest
.uf2for your adapter from Releases - Enter bootloader: Hold BOOT + connect USB-C (or double-tap reset)
- Drag the
.uf2file onto theRPI-RP2drive that appears - Done — the drive ejects and your adapter is running the new firmware
Full installation guide — troubleshooting, LED status codes, profile switching
# Install ARM toolchain (macOS)
brew install --cask gcc-arm-embedded cmake git
# Clone and initialize
git clone https://github.com/joypad-ai/joypad-os.git
cd joypad-os && make init
# Build an adapter
make usb2gc_kb2040 # USB/BT → GameCube
make usb2usb_feather # USB/BT → USB HID
make bt2usb_pico_w # Bluetooth → USB
make snes2usb_kb2040 # SNES controller → USBmake init-esp # One-time ESP-IDF setup
make bt2usb_esp32s3 # Build
make flash-bt2usb_esp32s3 # Flashmake init-nrf # One-time NCS setup
make bt2usb_seeed_xiao_nrf52840 # Build
make flash-bt2usb_seeed_xiao_nrf52840 # FlashOutput: releases/joypad_<commit>_<app>_<board>.uf2
Full build guide — prerequisites, all targets, ESP32/nRF setup, troubleshooting
Use any USB or Bluetooth controller on retro consoles:
| Console | Apps | Highlights | Build | Docs |
|---|---|---|---|---|
| PlayStation 4 | usb2usb | Local RSA auth, passthrough, rumble | DIY | Guide |
| PCEngine / TurboGrafx-16 | usb2pce | Multitap (5 players), mouse, 2/3/6-button | DIY | Guide |
| GameCube / Wii | usb2gc, bt2gc | Profiles, rumble, keyboard mode | Build | Guide |
| Sega Dreamcast | usb2dc | Rumble, analog triggers, 4 players | DIY | Guide |
| N64 | bt2n64 | Rumble pak emulation, profiles, BT | DIY | Guide |
| Nuon DVD Players | usb2nuon, bt2nuon | Controller, spinner (Tempest 3000), IGR | DIY | Guide |
| 3DO Interactive Multiplayer | usb23do | 8 players, mouse, extension passthrough | DIY | Guide |
| Neo Geo / SuperGun | usb2neogeo | 7 profiles, 1L6B arcade layouts | DIY | Guide |
| Casio Loopy | usb2loopy | 4 players (experimental) | DIY | Guide |
| Adapter | What It Does | Platforms | Build | Docs |
|---|---|---|---|---|
| USB2USB | USB/BT controller → USB gamepad (XInput, PS3/4, Switch, etc.) | RP2040, nRF52840 | DIY | Guide |
| BT2USB | Bluetooth controller → wired USB gamepad | Pico W, ESP32-S3, nRF52840 | Pico W | Guide |
| WiFi2USB | WiFi controller (JOCP) → USB gamepad | Pico W | DIY | Guide |
Convert retro controllers to USB or bridge them to other consoles:
| Adapter | From → To | Build | Docs |
|---|---|---|---|
| SNES2USB | SNES/NES → USB | KB2040 | Guide |
| NES2USB | NES → USB | DIY | Guide |
| N642USB | N64 → USB | DIY | Guide |
| GC2USB | GameCube → USB | DIY | Guide |
| NEOGEO2USB | Neo Geo arcade stick → USB | DIY | Guide |
| LodgeNet2USB | LodgeNet hotel controllers → USB | Pico | Guide |
| N642DC | N64 → Dreamcast | KB2040 | Guide |
| N642Nuon | N64 → Nuon | DIY | Guide |
| SNES23DO | SNES → 3DO | DIY | Guide |
| LodgeNet2N64 | LodgeNet → N64 | DIY | Guide |
| LodgeNet2GC | LodgeNet → GameCube | DIY | Guide |
Wire up GPIO buttons and analog sticks to build your own USB gamepad:
make controller_fisherprice_v1_kb2040 # Digital buttons → USB HID
make controller_fisherprice_v2_kb2040 # Buttons + analog stick → USB HID
make controller_macropad # Adafruit MacroPad → USB HID
make controller_btusb_pico_w # GPIO+JoyWing → BLE+USB HID (Pico W)
make controller_btusb_rp2040_abb # GPIO+USB Host → USB HID (ABB Passthrough)- Xbox — OG, 360, One, Series X|S (USB + Bluetooth)
- PlayStation — Classic, DS3, DS4, DualSense (USB + Bluetooth)
- Nintendo — Switch Pro, Switch 2 Pro, Joy-Con, NSO GameCube, GameCube adapter (USB + Bluetooth)
- 8BitDo — PCE 2.4g, M30, NeoGeo, BT adapters
- Other — Hori, Logitech, Google Stadia, Sega Astro City, generic HID
- Peripherals — USB keyboards, mice, hubs, Bluetooth dongles
- Native — SNES, N64, GameCube, Neo Geo, LodgeNet hotel controllers (directly wired)
Full controller compatibility list
Any Input Router Any Output
───────── ────── ──────────
USB controllers ──┐ ┌──→ Retro consoles
Bluetooth ────────┤ ├──→ USB gamepad
WiFi ─────────────┼──→ normalize → route → translate ──┼──→ XInput / PS4 / Switch
SNES / N64 / GC ──┤ ↓ ├──→ Keyboard + mouse
GPIO buttons ─────┘ profile_apply() └──→ Custom outputs
(button remapping)
- Router — SIMPLE (1:1), MERGE (all→one), or BROADCAST (all→all) modes
- Profiles — Per-app button remapping, cycled via SELECT + D-pad
- Dual-Core — Core 0 handles input, Core 1 handles timing-critical output (RP2040)
- PIO — Programmable I/O for console protocols (GameCube joybus, Dreamcast maple, etc.)
Architecture overview | Data flow
| Platform | Chip | What Runs On It | Bluetooth | Build System |
|---|---|---|---|---|
| RP2040 | ARM Cortex-M0+ (dual-core) | All console adapters, USB output, custom controllers | Classic BT + BLE (Pico W) or via dongle | pico-sdk |
| ESP32-S3 | Xtensa LX7 (dual-core) | bt2usb | BLE only | ESP-IDF |
| nRF52840 | ARM Cortex-M4 | bt2usb, usb2usb | BLE only | nRF Connect SDK |
| Section | What's There |
|---|---|
| Installation Guide | Flashing firmware, troubleshooting, LED codes |
| Build Guide | Dev setup for macOS/Linux/Windows, all build targets |
| Supported Controllers | USB, Bluetooth, keyboards, mice, dongles |
| Supported Boards | RP2040, ESP32-S3, nRF52840 board comparison |
| Wiring Guide | USB host port + console connector pinouts |
| DIY Builds | Build your own, where to buy parts |
| ESP32-S3 | ESP-IDF setup, TinyUF2, architecture |
| nRF52840 | nRF Connect SDK setup, debugging |
| Architecture | How it works — data flow, router, I/O layers |
| Data Flow | Input-to-output pipeline walkthrough |
| Protocol Reference | 3DO PBus, GameCube Joybus, Nuon Polyface, PCEngine |
- Discord: community.joypad.ai - Community chat
- Issues: GitHub Issues - Bug reports
- Email: support@controlleradapter.com - Product support
- Ha Thach - TinyUSB
- David Shadoff - PCEMouse foundation
- FCare - USBTo3DO 3DO protocol implementation
- mackieks - MaplePad Dreamcast Maple Bus implementation
- Ryzee119 - tusb_xinput
- SelvinPL - lufa-hid-parser
- JonnyHaystack - joybus-pio
- OpenStickCommunity - GP2040-CE USB device output modes
Joypad OS is licensed under the Apache-2.0 License.
The Joypad name and branding are trademarks of Joypad Inc.