Skip to content

GameCube / Wii Output Interface

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.

Protocol

  • Wire protocol: Single-wire bidirectional joybus at ~250kHz bit rate
  • PIO program: joybus.pio (from lib/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.

GameCube Controller Cable Pinout

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.

Poll Modes

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.

Player Support

  • Max players: 4
  • Routing: Typically MERGE mode (all inputs merged to a single controller output)
  • Multitap: Each adapter instance emulates one controller port

Button Mapping

The default mapping uses GC_BUTTON_* aliases defined in gamecube_buttons.h. Profile-based remapping is applied before the final GC report is built.

Default JP to GC Mapping

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

Analog 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.

Feedback

Rumble

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.

Keyboard LED

In keyboard mode, the adapter reports an LED state (Scroll Lock indicator) that can be read by input controllers.

Adaptive Triggers (DualSense)

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.

Keyboard Mode

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

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: 1. Hold Select for 2 seconds 2. Press D-Pad Up to cycle forward, D-Pad Down to cycle backward 3. Controller rumbles and LED flashes to confirm 4. Profile saves to flash (persists across power cycles)

See the usb2gc app for specific profile definitions (Default, SNES, SSBM, MKWii, Fighting).

Apps Using This Output

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)