Skip to content

Repository files navigation

libjoybus

An implementation of the Joybus protocol used by N64 and GameCube controllers, for 32-bit microcontrollers.

Logic Analyzer Capture of a GameCube Controller Read

Features

  • C implementation, no external dependencies (besides backend-specific SDKs)
  • Provides both host mode and target mode functionality
  • Host mode allows communication with N64/GameCube controllers from a microcontroller
  • Target mode allows you to build custom N64/GameCube controllers using a microcontroller
  • Near-ASIC timing accuracy for reliable communication
  • Pre-built targets for N64 controllers and GameCube controllers

Supported Platforms

  • Raspberry Pi Pico and Pico 2 (and other RP2xxx-based boards)
  • Silicon Labs EFR32 Series 1 and Series 2 MCUs
  • Espressif ESP32 (ESP32-C3, ESP32-C6, ESP32-S3, ESP32-H2)

Examples

libjoybus is a key part of WavePhoenix, my open source implementation of a GameCube WaveBird receiver.

libjoybus is also used in my open-source 4-port USB GameCube controller adapter project.

You can find a number of additonal examples in the examples/ directory.

Please let me know if you build something with libjoybus! I love seeing my projects used in the wild, and I'll consider adding it to the examples list!

Usage

You can find the full API documentation here, but here are some basic examples to get you started.

Initializing the Joybus

Before using libjoybus, you need to initialize the Joybus interface for your platform. Here's an example for the RP2040:

#include<joybus/joybus.h>#include<joybus/backend/rp2xxx.h>structjoybus_rp2xxxrp2xxx_bus;
structjoybus*bus=JOYBUS(&rp2xxx_bus);
intmain() {
// Initialize the Joybus on a specific GPIO pin and PIO instancejoybus_rp2xxx_init(&rp2xxx_bus, joybus_rp2xxx_config_default(JOYBUS_GPIO));
// ...your code herereturn0;
}

Communicating with Controllers

In host mode, libjoybus allows a microcontroller to communicate with N64 and GameCube controllers. This allows you to use input data from N64 and GameCube controllers in your projects.

#include<joybus/joybus.h>structjoybus_rp2xxxrp2xxx_bus;
structjoybus*bus=JOYBUS(&rp2xxx_bus);
voidread_controller() {
// Read a GameCube controller in analog mode 3 with the rumble motor offstructjoybus_gcn_controller_stateinput;
intrc=joybus_gcn_read(bus, JOYBUS_GCN_ANALOG_MODE_3, JOYBUS_GCN_MOTOR_STOP, &input);
if (rc<0) {
// ...handle read errorreturn;
}
// Do something with the input stateif (input.buttons&JOYBUS_GCN_BUTTON_A) {
// The A button is pressed
}
}
voidmain() {
// Initialize the Joybus and enable it in host modejoybus_rp2xxx_init(&rp2xxx_bus, joybus_rp2xxx_config_default(MY_GPIO));
joybus_enable(bus, JOYBUS_MODE_HOST);
// Read the controller state in a loopwhile (1) {
read_controller();
sleep_ms(10);
}
}

Emulating a Controller

In target mode, libjoybus allows a microcontroller to act as an N64 or GameCube controller. This allows you to create custom controllers that can interface with N64, GameCube, and Wii consoles.

I've provided built-in targets for N64 controllers and GameCube controllers so you can just populate the input state and let libjoybus handle the rest.

#include<joybus/joybus.h>structjoybus_rp2xxxrp2xxx_bus;
structjoybus*bus=JOYBUS(&rp2xxx_bus);
structjoybus_target_gcn_controllercontroller;
voidmain() {
// Initialize the Joybusjoybus_rp2xxx_init(&rp2xxx_bus, joybus_rp2xxx_config_default(MY_GPIO));
// Initialize a GameCube controller target and attach it to the busjoybus_target_gcn_controller_init(&controller);
joybus_attach_target(bus, JOYBUS_TARGET(&controller));
// Enable the Joybus in target modejoybus_enable(bus, JOYBUS_MODE_TARGET);
// At this point the target will respond to commands from a connected console!// Modify the input state as needed, for example based on GPIO or ADC readingswhile (1) {
// Clear previous button statecontroller.input.buttons &= ~JOYBUS_GCN_BUTTON_MASK;
// Simulate pressing the A buttoncontroller.input.buttons |= JOYBUS_GCN_BUTTON_A;
// Simulate setting the analog stick positioncontroller.input.stick_x=200;
controller.input.stick_y=200;
sleep_ms(10);
}
}

License

This project is licensed under the MIT License. See the LICENSE file for details.

About

An implementation of the Joybus protocol used by N64 and GameCube controllers, for 32-bit microcontrollers

Resources

Contributing

Stars

33 stars

Watchers

2 watching

Forks

Releases

Contributors

Languages