Emulates a GameCube controller connected to a GameCube or Wii console via the single-wire joybus protocol. Supports up to 4 players, analog triggers, rumble feedback, keyboard mode (for Phantasy Star Online), and app-defined button remapping profiles.
- Wire protocol: Single-wire bidirectional joybus at ~250kHz bit rate
- PIO program:
joybus.pio(fromlib/joybus-pio) - Clock requirement: 130MHz overclock (
set_sys_clock_khz(130000, true)) -- required for joybus timing accuracy - Data pin: GPIO 7 (KB2040 default)
- Core: Runs on Core 1 in a tight loop via
__not_in_flash_func
The console polls the controller, the adapter responds with a gc_report_t containing digital buttons, two analog sticks, and two analog trigger values. The poll command includes a rumble motor byte that the adapter reads back.
| Pin | Signal | Description |
|---|---|---|
| 1 | VCC | 5V power |
| 2 | Data | Bidirectional data line |
| 3 | GND | Ground |
| 4 | GND | Ground |
| 5 | (unused) | |
| 6 | 3.3V | Optional, some boards |
See GameCube Joybus Protocol for wire-level details.
The GameCube/Wii console can request different report formats:
| Mode | Constant | Description |
|---|---|---|
| 0 | BUTTON_MODE_0 |
Standard controller mode |
| 1 | BUTTON_MODE_1 |
Alternate report format |
| 2 | BUTTON_MODE_2 |
Alternate report format |
| 3 | BUTTON_MODE_3 |
Default gamepad mode (most common) |
| 4 | BUTTON_MODE_4 |
Alternate report format |
| KB | BUTTON_MODE_KB |
Keyboard mode (3 keypresses + checksum) |
The adapter starts in Mode 3 and switches to KB mode when toggled by the user.
- Max players: 4
- Routing: Typically MERGE mode (all inputs merged to a single controller output)
- Multitap: Each adapter instance emulates one controller port
The default mapping uses GC_BUTTON_* aliases defined in gamecube_buttons.h. Profile-based remapping is applied before the final GC report is built.
| JP_BUTTON_* | GC Button | Notes |
|---|---|---|
JP_BUTTON_B1 |
B | Small red button |
JP_BUTTON_B2 |
A | Large green button |
JP_BUTTON_B3 |
Y | Above A |
JP_BUTTON_B4 |
X | Right of A |
JP_BUTTON_L1 |
(disabled) | Not mapped in default profile |
JP_BUTTON_R1 |
Z | Digital, above R trigger |
JP_BUTTON_L2 |
L | Analog + digital trigger |
JP_BUTTON_R2 |
R | Analog + digital trigger |
JP_BUTTON_S1 |
(profile switch) | Hold 2s then D-pad to cycle |
JP_BUTTON_S2 |
Start | Start button |
JP_BUTTON_DU/DD/DL/DR |
D-pad | Direct mapping |
| Input | GC Output | Notes |
|---|---|---|
| Left stick X/Y | Control Stick | Y-axis inverted (HID 0=up to GC 0=down). Clamped to 1-255 (some games reject 0). |
| Right stick X/Y | C-Stick | Same inversion and clamping. |
| L2 analog | L trigger analog (0-255) | Threshold-configurable per profile for digital L press. |
| R2 analog | R trigger analog (0-255) | Threshold-configurable per profile for digital R press. |
Keyboard input applies a 0.61x scale factor to analog values (78/128 range) to match the smaller travel expected by games.
The GameCube console sends a rumble byte with each poll. When active, the adapter returns 255 to the player manager, which routes it to the connected USB/BT controller's vibration motor.
In keyboard mode, the adapter reports an LED state (Scroll Lock indicator) that can be read by input controllers.
Per-profile L2/R2 thresholds control when analog trigger values trigger the digital L/R press. A threshold of 0 disables analog-to-digital conversion.
Toggle keyboard mode by pressing Scroll Lock or F14 on a connected USB keyboard:
- All standard HID keys are mapped to GameCube keyboard scancodes via a 256-entry lookup table
- Reports contain 3 keypresses + checksum + counter
- Works with Phantasy Star Online and other keyboard-compatible games
- LED indicator shows when keyboard mode is active
- A1 (Home/Guide) sends the gc-swiss IGR combo (Select+D-down+B+R)
Profiles are defined at the app level (e.g., src/apps/usb2gc/profiles.h). The output interface exposes profile count, active index, set/get, and name accessors through the OutputInterface struct.
Switching profiles:
- Hold Select for 2 seconds
- Press D-Pad Up to cycle forward, D-Pad Down to cycle backward
- Controller rumbles and LED flashes to confirm
- Profile saves to flash (persists across power cycles)
See the usb2gc app for specific profile definitions (Default, SNES, SSBM, MKWii, Fighting).
| App | Description |
|---|---|
usb2gc |
USB/BT controllers to GameCube |
bt2gc |
Bluetooth controllers to GameCube (Pico W) |
lodgenet2gc |
LodgeNet hotel controllers to GameCube (Pico) |
n642gc |
N64 controllers to GameCube (planned) |