libdragon
Loading...
Searching...
No Matches
Files | Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
Joypad Subsystem

Joypad abstraction interface. More...

Files

file  joypad.c
 Joypad Subsystem.
 
file  joypad_accessory.c
 Joypad accessory helpers.
 
file  joypad_accessory.h
 Joypad accessory helpers.
 
file  joypad_internal.h
 Joypad internal.
 
file  joypad.h
 Joypad Subsystem.
 

Data Structures

struct  joypad_accessory_io_t
 Joypad Accessory I/O operation state. More...
 
struct  joypad_transfer_pak_io_t
 Joypad N64 Transfer Pak I/O operation state. More...
 
struct  joypad_accessory_t
 Joypad accessory structure. More...
 
struct  joypad_gcn_origin_t
 Joypad GameCube controller origins structure. More...
 
struct  joypad_device_cold_t
 "Cold" (non-volatile) Joypad device structure. More...
 
struct  joypad_device_hot_t
 "Hot" (interrupt-driven) Joypad device structure. More...
 
union  joypad_buttons_t
 Joypad Buttons. More...
 
struct  joypad_inputs_t
 Joypad Inputs Unified State Structure. More...
 

Macros

#define JOYPAD_IDENTIFY_INTERVAL_TICKS   TICKS_PER_SECOND
 Number of ticks between Joybus identify commands.
 
#define ASSERT_JOYPAD_INITIALIZED()    assertf(joypad_init_refcount > 0, "joypad_init() was not called")
 Convenience macro to ensure Joypad subsystem is initialized.
 
#define BB_HACK_FLAGS_SWAP_PORT1   ((*(uint32_t *)0x8000038c) & 3)
 BBPlayer "Hack Flags" register value.
 
#define JOYPAD_ACCESSORY_RETRY_LIMIT   2
 Number of times to retry accessory commands.
 
#define joypad_accessory_state_is_detecting(state)
 Is Joypad accessory currently in detection state?
 
#define joypad_accessory_state_is_transfer_enabling(state)
 Is Joypad accessory currently in Transfer Pak enabling state?
 
#define joypad_accessory_state_is_transfer_loading(state)
 Is Joypad accessory currently in Transfer Pak loading state?
 
#define joypad_accessory_state_is_transfer_storing(state)
 Is Joypad accessory currently in Transfer Pak storing state?
 
#define JOYPAD_CONTROLLER_PAK_BANK_SWITCH_ADDRESS   0x8000
 Controller pak address to perform bank switching.
 
#define ASSERT_JOYPAD_PORT_VALID(port)    assert((port) >= 0 && (port) < JOYPAD_PORT_COUNT)
 Convenience macro to validate a Joypad port number.
 
#define JOYPAD_GCN_ORIGIN_INIT    ((joypad_gcn_origin_t){ 127, 127, 127, 127, 0, 0 })
 Initial state for GameCube controller origins.
 
#define CLAMP_ANALOG_STICK(value)   CLAMP((int)(value), -127, 127)
 Ensure value is in range of an analog stick axis.
 
#define CLAMP_ANALOG_TRIGGER(value)   CLAMP((int)(value), 0, 255)
 Ensure value is in range of an analog trigger.
 
#define JOYPAD_PORT_COUNT   4
 Count of Joypad ports.
 
#define JOYPAD_PORT_FOREACH(iterator_token)
 Convenience macro to iterate through all Joypad ports.
 

Typedefs

typedef void(* joypad_accessory_io_callback_t) (joypad_accessory_error_t error, void *ctx)
 Callback function signature for joypad_accessory_xfer_async.
 

Enumerations

enum  joypad_accessory_state_t {
  JOYPAD_ACCESSORY_STATE_IDLE = 0 , JOYPAD_ACCESSORY_STATE_DETECT_INIT , JOYPAD_ACCESSORY_STATE_DETECT_CPAK_BANK_WRITE , JOYPAD_ACCESSORY_STATE_DETECT_CPAK_LABEL_BACKUP ,
  JOYPAD_ACCESSORY_STATE_DETECT_CPAK_LABEL_WRITE , JOYPAD_ACCESSORY_STATE_DETECT_CPAK_LABEL_READ , JOYPAD_ACCESSORY_STATE_DETECT_CPAK_LABEL_RESTORE , JOYPAD_ACCESSORY_STATE_DETECT_RUMBLE_PROBE_WRITE ,
  JOYPAD_ACCESSORY_STATE_DETECT_RUMBLE_PROBE_READ , JOYPAD_ACCESSORY_STATE_DETECT_TRANSFER_PROBE_ON , JOYPAD_ACCESSORY_STATE_DETECT_TRANSFER_PROBE_READ , JOYPAD_ACCESSORY_STATE_DETECT_TRANSFER_PROBE_OFF ,
  JOYPAD_ACCESSORY_STATE_DETECT_SNAP_PROBE_WRITE , JOYPAD_ACCESSORY_STATE_DETECT_SNAP_PROBE_READ , JOYPAD_ACCESSORY_STATE_READ , JOYPAD_ACCESSORY_STATE_WRITE ,
  JOYPAD_ACCESSORY_STATE_RUMBLE_WRITE , JOYPAD_ACCESSORY_STATE_TRANSFER_ENABLE_PROBE_WRITE , JOYPAD_ACCESSORY_STATE_TRANSFER_ENABLE_PROBE_WAIT , JOYPAD_ACCESSORY_STATE_TRANSFER_ENABLE_STATUS_WRITE ,
  JOYPAD_ACCESSORY_STATE_TRANSFER_ENABLE_STATUS_WAIT , JOYPAD_ACCESSORY_STATE_TRANSFER_ENABLE_STATUS_READ , JOYPAD_ACCESSORY_STATE_TRANSFER_LOAD_STATUS_READ , JOYPAD_ACCESSORY_STATE_TRANSFER_LOAD_BANK_WRITE ,
  JOYPAD_ACCESSORY_STATE_TRANSFER_LOAD_DATA_READ , JOYPAD_ACCESSORY_STATE_TRANSFER_STORE_STATUS_READ , JOYPAD_ACCESSORY_STATE_TRANSFER_STORE_BANK_WRITE , JOYPAD_ACCESSORY_STATE_TRANSFER_STORE_DATA_WRITE
}
 Joypad accessory states enumeration.
 
enum  joypad_accessory_error_t {
  JOYPAD_ACCESSORY_ERROR_PENDING = -1 , JOYPAD_ACCESSORY_ERROR_NONE = 0 , JOYPAD_ACCESSORY_ERROR_ABSENT , JOYPAD_ACCESSORY_ERROR_CHECKSUM ,
  JOYPAD_ACCESSORY_ERROR_TRANSFER_PAK_STATUS_CHANGE , JOYPAD_ACCESSORY_ERROR_UNKNOWN
}
 Joypad accessory error codes. More...
 
enum  joypad_accessory_xfer_t { JOYPAD_ACCESSORY_XFER_READ , JOYPAD_ACCESSORY_XFER_WRITE }
 Type of transfer performed by joypad_accessory_xfer_async. More...
 
enum  joypad_rumble_method_t { JOYPAD_RUMBLE_METHOD_NONE = 0 , JOYPAD_RUMBLE_METHOD_N64_RUMBLE_PAK , JOYPAD_RUMBLE_METHOD_GCN_CONTROLLER }
 Joypad rumble methods enumeration. More...
 
enum  joypad_port_t { JOYPAD_PORT_1 = 0 , JOYPAD_PORT_2 = 1 , JOYPAD_PORT_3 = 2 , JOYPAD_PORT_4 = 3 }
 Joypad Port Numbers. More...
 
enum  joypad_style_t { JOYPAD_STYLE_NONE = 0 , JOYPAD_STYLE_N64 , JOYPAD_STYLE_GCN , JOYPAD_STYLE_MOUSE }
 Joypad Styles enumeration. More...
 
enum  joypad_accessory_type_t {
  JOYPAD_ACCESSORY_TYPE_NONE = 0 , JOYPAD_ACCESSORY_TYPE_UNKNOWN , JOYPAD_ACCESSORY_TYPE_CONTROLLER_PAK , JOYPAD_ACCESSORY_TYPE_RUMBLE_PAK ,
  JOYPAD_ACCESSORY_TYPE_TRANSFER_PAK , JOYPAD_ACCESSORY_TYPE_BIO_SENSOR , JOYPAD_ACCESSORY_TYPE_SNAP_STATION
}
 Joypad Accessories enumeration. More...
 
enum  joypad_axis_t {
  JOYPAD_AXIS_STICK_X = offsetof(joypad_inputs_t, stick_x) , JOYPAD_AXIS_STICK_Y = offsetof(joypad_inputs_t, stick_y) , JOYPAD_AXIS_CSTICK_X = offsetof(joypad_inputs_t, cstick_x) , JOYPAD_AXIS_CSTICK_Y = offsetof(joypad_inputs_t, cstick_y) ,
  JOYPAD_AXIS_ANALOG_L = offsetof(joypad_inputs_t, analog_l) , JOYPAD_AXIS_ANALOG_R = offsetof(joypad_inputs_t, analog_r)
}
 Joypad Axis enumeration values. More...
 
enum  joypad_2d_t {
  JOYPAD_2D_STICK = (1 << 0) , JOYPAD_2D_DPAD = (1 << 1) , JOYPAD_2D_C = (1 << 2) , JOYPAD_2D_LH = (JOYPAD_2D_STICK | JOYPAD_2D_DPAD) ,
  JOYPAD_2D_RH = (JOYPAD_2D_STICK | JOYPAD_2D_C) , JOYPAD_2D_ANY = (JOYPAD_2D_STICK | JOYPAD_2D_DPAD | JOYPAD_2D_C)
}
 Joypad 2D axes enumeration. More...
 
enum  joypad_8way_t {
  JOYPAD_8WAY_NONE = -1 , JOYPAD_8WAY_RIGHT = 0 , JOYPAD_8WAY_UP_RIGHT = 1 , JOYPAD_8WAY_UP = 2 ,
  JOYPAD_8WAY_UP_LEFT = 3 , JOYPAD_8WAY_LEFT = 4 , JOYPAD_8WAY_DOWN_LEFT = 5 , JOYPAD_8WAY_DOWN = 6 ,
  JOYPAD_8WAY_DOWN_RIGHT = 7
}
 Joypad 8-way directional enumeration. More...
 

Functions

joypad_inputs_t joypad_read_n64_inputs (joypad_port_t port)
 Read the inputs from a Nintendo 64 controller synchronously.
 
void joypad_init (void)
 Initialize the Joypad subsystem.
 
void joypad_close (void)
 Close the Joypad subsystem.
 
void joypad_poll (void)
 Fetch the current Joypad input state.
 
bool joypad_is_connected (joypad_port_t port)
 Whether a Joybus device is plugged in to a Joypad port.
 
joybus_identifier_t joypad_get_identifier (joypad_port_t port)
 Get the Joybus device identifier for a Joypad port.
 
joypad_style_t joypad_get_style (joypad_port_t port)
 Get the Joypad style for a Joypad port.
 
joypad_accessory_type_t joypad_get_accessory_type (joypad_port_t port)
 Get the Joypad accessory type for a Joypad port.
 
int joypad_get_accessory_state (joypad_port_t port)
 Get the Joypad accessory state for a Joypad port.
 
int joypad_get_accessory_error (joypad_port_t port)
 Get the Joypad accessory error for a Joypad port.
 
uint8_t joypad_get_transfer_pak_status (joypad_port_t port)
 Get the Transfer Pak status byte for a Joypad port.
 
bool joypad_get_rumble_supported (joypad_port_t port)
 Is rumble supported for a Joypad port?
 
bool joypad_get_rumble_active (joypad_port_t port)
 Is rumble active for a Joypad port?
 
void joypad_set_rumble_active (joypad_port_t port, bool active)
 Activate or deactivate rumble on a Joypad port.
 
joypad_inputs_t joypad_get_inputs (joypad_port_t port)
 Get the current Joypad inputs state for a Joypad port.
 
joypad_buttons_t joypad_get_buttons (joypad_port_t port)
 Get the current Joypad buttons state for a Joypad port.
 
joypad_buttons_t joypad_get_buttons_pressed (joypad_port_t port)
 Get the Joypad buttons that were pressed since the last time Joypads were read for a Joypad port.
 
joypad_buttons_t joypad_get_buttons_released (joypad_port_t port)
 Get the Joypad buttons that were released since the last time Joypads were read for a Joypad port.
 
joypad_buttons_t joypad_get_buttons_held (joypad_port_t port)
 Get the Joypad buttons that are held down since the last time Joypads were read for a Joypad port.
 
int joypad_get_axis_pressed (joypad_port_t port, joypad_axis_t axis)
 Get the direction of a "press" of an axis on a Joypad port.
 
int joypad_get_axis_released (joypad_port_t port, joypad_axis_t axis)
 Get the direction of a "release" of an axis on a Joypad port.
 
int joypad_get_axis_held (joypad_port_t port, joypad_axis_t axis)
 Get the direction that an axis is held on a Joypad port.
 
joypad_8way_t joypad_get_direction (joypad_port_t port, joypad_2d_t axes)
 Get the 8-way direction for a Joypad port's directional axes.
 
void joypad_accessory_reset (joypad_port_t port)
 Reset the accessory state for a Joypad port.
 
void joypad_transfer_pak_wait_timer_init (joypad_port_t port)
 Initialize the Transfer Pak wait timer if necessary.
 
void joypad_accessory_detect_async (joypad_port_t port)
 Detect which accessory is inserted in an N64 controller.
 
void joypad_rumble_pak_toggle_async (joypad_port_t port, bool active)
 Turn the Rumble Pak motor on or off for a Joypad port.
 
void joypad_accessory_xfer_async (joypad_port_t port, joypad_accessory_xfer_t xfer, uint16_t start_addr, void *dst, size_t len, joypad_accessory_io_callback_t callback, void *ctx)
 Read or write data from a Joypad accessory asynchronously.
 
joypad_accessory_error_t joypad_accessory_xfer (joypad_port_t port, joypad_accessory_xfer_t xfer, uint16_t start_addr, void *dst, size_t len)
 Read or write data from a joypad accessory.
 
joypad_accessory_error_t joypad_controller_pak_set_bank (joypad_port_t port, uint8_t bank)
 Select the active bank for a Controller Pak.
 
void joypad_transfer_pak_enable_async (joypad_port_t port, bool enabled)
 Enable or disable the Transfer Pak for a Joypad port.
 
void joypad_transfer_pak_load_async (joypad_port_t port, uint16_t cart_addr, void *dst, size_t len)
 Load data from the GB cartridge inserted in a Transfer Pak.
 
void joypad_transfer_pak_store_async (joypad_port_t port, uint16_t cart_addr, void *src, size_t len)
 Store data on the GB cartridge inserted in a Transfer Pak.
 

Variables

volatile joybus_identifier_t joypad_identifiers_hot [JOYPAD_PORT_COUNT]
 Joypad identifiers for each port.
 
volatile joypad_device_hot_t joypad_devices_hot [JOYPAD_PORT_COUNT]
 Joypad "hot" devices for each port.
 
volatile joypad_gcn_origin_t joypad_origins_hot [JOYPAD_PORT_COUNT]
 Joypad origins for each port.
 
volatile joypad_accessory_t joypad_accessories_hot [JOYPAD_PORT_COUNT]
 Joypad accessories for each port.
 

"Hot" (interrupt-driven) global state

volatile joybus_identifier_t joypad_identifiers_hot [JOYPAD_PORT_COUNT] = {0}
 Joypad identifiers for each port.
 
volatile joypad_device_hot_t joypad_devices_hot [JOYPAD_PORT_COUNT] = {0}
 Joypad "hot" devices for each port.
 
volatile joypad_gcn_origin_t joypad_origins_hot [JOYPAD_PORT_COUNT] = {0}
 Joypad origins for each port.
 
volatile joypad_accessory_t joypad_accessories_hot [JOYPAD_PORT_COUNT] = {0}
 Joypad accessories for each port.
 

Joypad raw 2D byte bitmasks

#define JOYPAD_RAW_2D_RIGHT   (1<<0)
 Joypad raw 2D right bitmask.
 
#define JOYPAD_RAW_2D_LEFT   (1<<1)
 Joypad raw 2D left bitmask.
 
#define JOYPAD_RAW_2D_DOWN   (1<<2)
 Joypad raw 2D down bitmask.
 
#define JOYPAD_RAW_2D_UP   (1<<3)
 Joypad raw 2D up bitmask.
 

Joybus analog value ranges

#define JOYPAD_RANGE_N64_STICK_MAX   90
 Maximum range of a Nintendo 64 controller analog stick.
 
#define JOYPAD_RANGE_GCN_STICK_MAX   100
 Maximum range of a GameCube controller analog stick.
 
#define JOYPAD_RANGE_GCN_CSTICK_MAX   76
 Maximum range of a GameCube controller analog C-stick.
 
#define JOYPAD_RANGE_GCN_TRIGGER_MAX   200
 Maximum range of a GameCube controller analog trigger.
 

Detailed Description

Joypad abstraction interface.

The Joypad subsystem is in charge of communication with the controller ports and provides a common interface to support a variety of input devices:

To use a Joypad, the developer must first call joypad_init. Once initialized, The Joypad subsystem will automatically identify and read all connected input devices once per frame.

To refer to individual ports, use the joypad_port_t enumeration values. To iterate across all ports, use the JOYPAD_PORT_FOREACH macro.

To read the controllers, first call joypad_poll once per frame to process the input data. joypad_get_style will return which "style" of device is connected to a port (joypad_style_t). joypad_get_inputs will return the buttons and analog input state for a given controller port.

Developers can determine whether the input device is capable of rumble by calling joypad_get_rumble_supported and then starting/stopping the rumble motor by calling joypad_set_rumble_active.

The Joypad subsystem will automatically detect which accessory is connected to Nintendo 64 controllers. Call joypad_get_accessory_type to determine which accessory was detected.

For advanced use-cases, a developer can determine exactly which type of input device is connected by calling joypad_get_identifier, which will return the 16-bit device identifier value from the Joybus "Info" response.

To read digital button state for a Joypad device:

To read 8-way directional state for a Joypad device:

To read analog directions as digital inputs for a Joypad device:


Data Structure Documentation

◆ joypad_accessory_io_t

struct joypad_accessory_io_t

Joypad Accessory I/O operation state.

Data Fields
uint8_t * start
uint8_t * end
uint8_t * cursor
uint16_t cart_addr
joypad_accessory_io_callback_t callback
void * ctx

◆ joypad_transfer_pak_io_t

struct joypad_transfer_pak_io_t

Joypad N64 Transfer Pak I/O operation state.

Data Fields
uint8_t * start
uint8_t * end
uint8_t * cursor
uint8_t bank
uint16_t cart_addr
uint16_t tpak_addr

◆ joypad_accessory_t

struct joypad_accessory_t

Joypad accessory structure.

Data Fields
uint8_t status
joypad_accessory_type_t type
joypad_accessory_state_t state
joypad_accessory_error_t error
unsigned retries
uint8_t cpak_label_backup[JOYBUS_ACCESSORY_DATA_SIZE]
joypad_accessory_io_t io
timer_link_t * transfer_pak_wait_timer
joybus_transfer_pak_status_t transfer_pak_status
joypad_transfer_pak_io_t transfer_pak_io

◆ joypad_gcn_origin_t

struct joypad_gcn_origin_t

Joypad GameCube controller origins structure.

Data Fields
uint8_t stick_x Analog stick X-axis.
uint8_t stick_y Analog stick Y-axis.
uint8_t cstick_x Analog C-stick X-axis.
uint8_t cstick_y Analog C-stick Y-axis.
uint8_t analog_l Analog L-trigger.
uint8_t analog_r Analog R-trigger.

◆ joypad_device_cold_t

struct joypad_device_cold_t

"Cold" (non-volatile) Joypad device structure.

Data Fields
joybus_identifier_t identifier Joybus device type identifier.
joypad_style_t style Joypad style.
joypad_inputs_t current Joypad inputs for current frame.
joypad_inputs_t previous Joypad inputs for previous frame.

◆ joypad_device_hot_t

struct joypad_device_hot_t

"Hot" (interrupt-driven) Joypad device structure.

Data Fields
joypad_style_t style Joypad style.
joypad_rumble_method_t rumble_method Joypad rumble method.
bool rumble_active Is the Joypad currently rumbling?

◆ joypad_buttons_t

union joypad_buttons_t

Joypad Buttons.

Data Fields
uint16_t raw Raw button data as a 16-bit value.
unsigned a: 1 State of the A button.
unsigned b: 1 State of the B button.
unsigned z: 1 State of the Z button.
unsigned start: 1 State of the Start button.
unsigned d_up: 1 State of the D-Pad Up button.
unsigned d_down: 1 State of the D-Pad Down button.
unsigned d_left: 1 State of the D-Pad Left button.
unsigned d_right: 1 State of the D-Pad Right button.
unsigned y: 1 State of the Y button.

This input only exists on GameCube controllers.

unsigned x: 1 State of the X button.

This input only exists on GameCube controllers.

unsigned l: 1 State of the digital L trigger.
unsigned r: 1 State of the digital R trigger.
unsigned c_up: 1 State of the C-Up button.

For GameCube controllers, the value will be emulated based on the C-Stick Y axis position.

unsigned c_down: 1 State of the C-Down button.

For GameCube controllers, the value will be emulated based on the C-Stick Y axis position.

unsigned c_left: 1 State of the C-Left button.

For GameCube controllers, the value will be emulated based on the C-Stick X axis position.

unsigned c_right: 1 State of the C-Right button.

For GameCube controllers, the value will be emulated based on the C-Stick X axis position.

◆ joypad_inputs_t

struct joypad_inputs_t

Joypad Inputs Unified State Structure.

Data Fields
joypad_buttons_t btn Structure containing digital button inputs state.
int8_t stick_x Position of the analog joystick X axis. (-127, +127)

On OEM N64 controllers with analog sticks in good condition, the range of this axis is roughly (-85, +85).

On well-worn N64 controllers, the range may be as low as (-60, +60).

On real GameCube controllers, the range is roughly (-100, +100).

On startup, an N64 controller will report its current stick position as (0, 0). To reset the origin on an N64 controller, hold the L & R shoulder buttons and the start button for several seconds with the analog stick in a neutral position.

For GameCube controllers, this value will be relative to its origin. The Joypad subsystem will automatically read the origins of GameCube controllers and account for them when resolving the analog inputs. To reset the origin on a GameCube controller, hold the X & Y buttons and the start button for several seconds with the analog inputs in neutral positions.

int8_t stick_y Position of the analog joystick Y axis. (-127, +127)

On OEM N64 controllers with analog sticks in good condition, the range of this axis is roughly (-85, +85).

On well-worn N64 controllers, the range may be as low as (-60, +60).

On real GameCube controllers, the range is roughly (-100, +100).

On startup, an N64 controller will report its current stick position as (0, 0). To reset the origin on an N64 controller, hold the L & R shoulder buttons and the start button for several seconds with the analog stick in a neutral position.

For GameCube controllers, this value will be relative to its origin. The Joypad subsystem will automatically read the origins of GameCube controllers and account for them when resolving the analog inputs. To reset the origin on a GameCube controller, hold the X & Y buttons and the start button for several seconds with the analog inputs in neutral positions.

int8_t cstick_x Position of the analog "C-Stick" X axis. (-127, +127)

On real controllers, the range of this axis is roughly (-76, +76).

For N64 controllers, this value will be emulated based on the digital C-Left and C-Right button values (-76=C-Left, +76=C-Right).

For GameCube controllers, this value will be relative to its origin. The Joypad subsystem will automatically read the origins of GameCube controllers and account for them when resolving the analog inputs. To reset the origin on a GameCube controller, hold the X & Y buttons and the start button for several seconds with the analog inputs in neutral positions.

int8_t cstick_y Position of the analog "C-Stick" Y axis. (-127, +127)

On real controllers, the range of this axis is roughly (-76, +76).

For N64 controllers, this value will be emulated based on the digital C-Up and C-Down button values (-76=C-Down, +76=C-Up).

For GameCube controllers, this value will be relative to its origin. The Joypad subsystem will automatically read the origins of GameCube controllers and account for them when resolving the analog inputs. To reset the origin on a GameCube controller, hold the X & Y buttons and the start button for several seconds with the analog inputs in neutral positions.

uint8_t analog_l Position of the analog L trigger. (0, 255)

This value will be close to zero when no pressure is applied, and close to 200 when full pressure is applied.

For N64 controllers, this value will be emulated based on the digital L trigger button value (0=unpressed, 200=pressed).

For GameCube controllers, this value will be relative to its origin. The Joypad subsystem will automatically read the origins of GameCube controllers and account for them when resolving the analog inputs. To reset the origin on a GameCube controller, hold the X & Y buttons and the start button for several seconds with the analog inputs in neutral positions.

uint8_t analog_r Position of the analog R trigger. (0, 255)

This value will be close to zero when no pressure is applied, and close to 200 when full pressure is applied.

For N64 controllers, this value will be emulated based on the digital R trigger button value (0=unpressed, 200=pressed).

For GameCube controllers, this value will be relative to its origin. The Joypad subsystem will automatically read the origins of GameCube controllers and account for them when resolving the analog inputs. To reset the origin on a GameCube controller, hold the X & Y buttons and the start button for several seconds with the analog inputs in neutral positions.

Macro Definition Documentation

◆ JOYPAD_IDENTIFY_INTERVAL_TICKS

#define JOYPAD_IDENTIFY_INTERVAL_TICKS   TICKS_PER_SECOND

Number of ticks between Joybus identify commands.

During VI interrupt, the Joypad subsystem will periodically re-identify the connected devices to check if the identifier has changed or if any accessories have been connected/disconnected.

◆ BB_HACK_FLAGS_SWAP_PORT1

#define BB_HACK_FLAGS_SWAP_PORT1   ((*(uint32_t *)0x8000038c) & 3)

BBPlayer "Hack Flags" register value.

The only known purpose of this register is to hold the iQue menu configuration setting for swapping the first controller with another port.

The value of the register is the controller to swap with (0-indexed).

◆ joypad_accessory_state_is_detecting

#define joypad_accessory_state_is_detecting (   state)
Value:
((state) >= JOYPAD_ACCESSORY_STATE_DETECT_INIT && \
(state) <= JOYPAD_ACCESSORY_STATE_DETECT_SNAP_PROBE_READ)

Is Joypad accessory currently in detection state?

◆ joypad_accessory_state_is_transfer_enabling

#define joypad_accessory_state_is_transfer_enabling (   state)
Value:
((state) >= JOYPAD_ACCESSORY_STATE_TRANSFER_ENABLE_PROBE_WRITE && \
(state) <= JOYPAD_ACCESSORY_STATE_TRANSFER_ENABLE_STATUS_READ)

Is Joypad accessory currently in Transfer Pak enabling state?

◆ joypad_accessory_state_is_transfer_loading

#define joypad_accessory_state_is_transfer_loading (   state)
Value:
((state) >= JOYPAD_ACCESSORY_STATE_TRANSFER_LOAD_STATUS_READ && \
(state) <= JOYPAD_ACCESSORY_STATE_TRANSFER_LOAD_DATA_READ)

Is Joypad accessory currently in Transfer Pak loading state?

◆ joypad_accessory_state_is_transfer_storing

#define joypad_accessory_state_is_transfer_storing (   state)
Value:
((state) >= JOYPAD_ACCESSORY_STATE_TRANSFER_STORE_STATUS_READ && \
(state) <= JOYPAD_ACCESSORY_STATE_TRANSFER_STORE_DATA_WRITE)

Is Joypad accessory currently in Transfer Pak storing state?

◆ JOYPAD_PORT_FOREACH

#define JOYPAD_PORT_FOREACH (   iterator_token)
Value:
for (\
joypad_port_t iterator_token = JOYPAD_PORT_1; \
iterator_token < JOYPAD_PORT_COUNT; \
iterator_token += 1 \
)
#define JOYPAD_PORT_COUNT
Count of Joypad ports.
Definition joypad.h:86
joypad_port_t
Joypad Port Numbers.
Definition joypad.h:74
@ JOYPAD_PORT_1
Joypad Port 1.
Definition joypad.h:76

Convenience macro to iterate through all Joypad ports.

Enumeration Type Documentation

◆ joypad_accessory_error_t

Joypad accessory error codes.

Enumerator
JOYPAD_ACCESSORY_ERROR_PENDING 

Operation is pending

JOYPAD_ACCESSORY_ERROR_NONE 

No error.

JOYPAD_ACCESSORY_ERROR_ABSENT 

Accessory is absent.

JOYPAD_ACCESSORY_ERROR_CHECKSUM 

Checksum error.

JOYPAD_ACCESSORY_ERROR_TRANSFER_PAK_STATUS_CHANGE 

Transfer Pak status changed.

JOYPAD_ACCESSORY_ERROR_UNKNOWN 

Unknown error.

◆ joypad_accessory_xfer_t

Type of transfer performed by joypad_accessory_xfer_async.

Enumerator
JOYPAD_ACCESSORY_XFER_READ 

Read operation.

JOYPAD_ACCESSORY_XFER_WRITE 

Write operation.

◆ joypad_rumble_method_t

Joypad rumble methods enumeration.

Enumerator
JOYPAD_RUMBLE_METHOD_NONE 

Rumble not supported.

JOYPAD_RUMBLE_METHOD_N64_RUMBLE_PAK 

Nintendo 64 controller with Rumble Pak.

JOYPAD_RUMBLE_METHOD_GCN_CONTROLLER 

GameCube controller with rumble motors.

◆ joypad_port_t

Joypad Port Numbers.

Enumerator
JOYPAD_PORT_1 

Joypad Port 1.

JOYPAD_PORT_2 

Joypad Port 2.

JOYPAD_PORT_3 

Joypad Port 3.

JOYPAD_PORT_4 

Joypad Port 4.

◆ joypad_style_t

Joypad Styles enumeration.

Enumerator
JOYPAD_STYLE_NONE 

Unsupported Joypad Style.

JOYPAD_STYLE_N64 

Nintendo 64 Joypad Style.

A standard N64 controller, which has an analog stick, directional pad, start button, L & R shoulder buttons, a Z trigger, A & B face buttons, and a C-directional pad.

For convenience, the N64 style will coarsely simulate certain GameCube controller inputs:

  • C-directional pad maps to the C-stick.
  • L & R shoulder buttons map to the analog triggers.
JOYPAD_STYLE_GCN 

GameCube Joypad Style.

A standard GameCube controller, which is supported on N64 when using a passive adapter to convert the plug.

The GameCube controller has more and different buttons than a Nintendo 64 controller: X & Y buttons, analog L & R triggers, and an analog C-stick instead of buttons.

For convenience, the GameCube style will coarsely simulate the C-directional pad using C-stick inputs.

JOYPAD_STYLE_MOUSE 

Mouse Joypad Style.

The N64 Mouse peripheral is read like a controller, but only has A & B buttons, and the analog stick reports the relative value since it was last read.

◆ joypad_accessory_type_t

Joypad Accessories enumeration.

Enumerator
JOYPAD_ACCESSORY_TYPE_NONE 

No accessory.

JOYPAD_ACCESSORY_TYPE_UNKNOWN 

Unknown or malfunctioning accessory.

JOYPAD_ACCESSORY_TYPE_CONTROLLER_PAK 

Controller Pak accessory.

JOYPAD_ACCESSORY_TYPE_RUMBLE_PAK 

Rumble Pak accessory.

JOYPAD_ACCESSORY_TYPE_TRANSFER_PAK 

Transfer Pak accessory.

JOYPAD_ACCESSORY_TYPE_BIO_SENSOR 

Bio Sensor accessory.

JOYPAD_ACCESSORY_TYPE_SNAP_STATION 

Pokemon Snap Station accessory.

◆ joypad_axis_t

Joypad Axis enumeration values.

These values are used to index into the joypad_inputs_t structure.

Enumerator
JOYPAD_AXIS_STICK_X 

Joypad stick X axis.

JOYPAD_AXIS_STICK_Y 

Joypad stick Y axis.

JOYPAD_AXIS_CSTICK_X 

Joypad C-stick X axis.

JOYPAD_AXIS_CSTICK_Y 

Joypad C-stick Y axis.

JOYPAD_AXIS_ANALOG_L 

Joypad analog L trigger axis.

JOYPAD_AXIS_ANALOG_R 

Joypad analog R trigger axis.

◆ joypad_2d_t

Joypad 2D axes enumeration.

These values are used to select one or more 2D input axes.

Enumerator
JOYPAD_2D_STICK 

Analog stick 2D axes.

JOYPAD_2D_DPAD 

D-Pad 2D axes.

JOYPAD_2D_C 

C buttons 2D axes.

JOYPAD_2D_LH 

Left-Hand 2D axes: Analog stick or D-Pad.

JOYPAD_2D_RH 

Right-Hand 2D axes: Analog stick or C buttons.

JOYPAD_2D_ANY 

Any 2D axes: Analog stick, D-Pad, or C buttons.

◆ joypad_8way_t

Joypad 8-way directional enumeration.

Enumerator
JOYPAD_8WAY_NONE 

8-way no direction.

JOYPAD_8WAY_RIGHT 

8-way right direction.

JOYPAD_8WAY_UP_RIGHT 

8-way up-right direction.

JOYPAD_8WAY_UP 

8-way up direction.

JOYPAD_8WAY_UP_LEFT 

8-way up-left direction.

JOYPAD_8WAY_LEFT 

8-way left direction.

JOYPAD_8WAY_DOWN_LEFT 

8-way down-left direction.

JOYPAD_8WAY_DOWN 

8-way down direction.

JOYPAD_8WAY_DOWN_RIGHT 

8-way down-right direction.

Function Documentation

◆ joypad_read_n64_inputs()

joypad_inputs_t joypad_read_n64_inputs ( joypad_port_t  port)

Read the inputs from a Nintendo 64 controller synchronously.

This function is intended for use in situations where interrupts may be disabled or where joypad_init may not have been called.

Note
This function is slow: it blocks for about 10% of a frame. To avoid this performance hit, use the managed function in the Joypad subsystem instead if possible: joypad_get_inputs
Parameters
portJoypad port (joypad_port_t) to read from.
Returns
Joypad inputs structure (joypad_inputs_t)

◆ joypad_init()

void joypad_init ( void  )

Initialize the Joypad subsystem.

Starts reading Joypads during VI interrupt.

◆ joypad_close()

void joypad_close ( void  )

Close the Joypad subsystem.

Stops reading Joypads during VI interrupt.

◆ joypad_poll()

void joypad_poll ( void  )

Fetch the current Joypad input state.

This function must be called once per frame, or any time after the Joypads have been read. After calling this function, you can read the Joypad state using the following functions:

This function is very fast. In fact, joypads are read in background asynchronously under interrupt, so this function just synchronizes the internal state.

◆ joypad_is_connected()

bool joypad_is_connected ( joypad_port_t  port)

Whether a Joybus device is plugged in to a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Return values
trueA Joybus device is connected to the Joypad port.
falseNothing is connected to the Joypad port.

◆ joypad_get_identifier()

joybus_identifier_t joypad_get_identifier ( joypad_port_t  port)

Get the Joybus device identifier for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joybus device identifier (joybus_identifier_t)

◆ joypad_get_style()

joypad_style_t joypad_get_style ( joypad_port_t  port)

Get the Joypad style for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joypad style enumeration value (joypad_style_t)

◆ joypad_get_accessory_type()

joypad_accessory_type_t joypad_get_accessory_type ( joypad_port_t  port)

Get the Joypad accessory type for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joypad accessory type enumeration value (joypad_accessory_type_t)

◆ joypad_get_accessory_state()

int joypad_get_accessory_state ( joypad_port_t  port)

Get the Joypad accessory state for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joypad accessory state enumeration value

◆ joypad_get_accessory_error()

int joypad_get_accessory_error ( joypad_port_t  port)

Get the Joypad accessory error for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joypad accessory error enumeration value

◆ joypad_get_transfer_pak_status()

uint8_t joypad_get_transfer_pak_status ( joypad_port_t  port)

Get the Transfer Pak status byte for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Transfer Pak status byte (joybus_transfer_pak_status_t)

◆ joypad_get_rumble_supported()

bool joypad_get_rumble_supported ( joypad_port_t  port)

Is rumble supported for a Joypad port?

Parameters
portJoypad port number (joypad_port_t)
Returns
Whether rumble is supported

◆ joypad_get_rumble_active()

bool joypad_get_rumble_active ( joypad_port_t  port)

Is rumble active for a Joypad port?

Parameters
portJoypad port number (joypad_port_t)
Returns
Whether rumble is active

◆ joypad_set_rumble_active()

void joypad_set_rumble_active ( joypad_port_t  port,
bool  active 
)

Activate or deactivate rumble on a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
activeWhether rumble should be active

◆ joypad_get_inputs()

joypad_inputs_t joypad_get_inputs ( joypad_port_t  port)

Get the current Joypad inputs state for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joypad inputs structure (joypad_inputs_t)

◆ joypad_get_buttons()

joypad_buttons_t joypad_get_buttons ( joypad_port_t  port)

Get the current Joypad buttons state for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joypad buttons structure (joypad_buttons_t)

◆ joypad_get_buttons_pressed()

joypad_buttons_t joypad_get_buttons_pressed ( joypad_port_t  port)

Get the Joypad buttons that were pressed since the last time Joypads were read for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joypad buttons structure (joypad_buttons_t)

◆ joypad_get_buttons_released()

joypad_buttons_t joypad_get_buttons_released ( joypad_port_t  port)

Get the Joypad buttons that were released since the last time Joypads were read for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joypad buttons structure (joypad_buttons_t)

◆ joypad_get_buttons_held()

joypad_buttons_t joypad_get_buttons_held ( joypad_port_t  port)

Get the Joypad buttons that are held down since the last time Joypads were read for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
Returns
Joypad buttons structure (joypad_buttons_t)

◆ joypad_get_axis_pressed()

int joypad_get_axis_pressed ( joypad_port_t  port,
joypad_axis_t  axis 
)

Get the direction of a "press" of an axis on a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
axisJoypad axis enumeration value (joypad_axis_t)
Return values
+1Axis is pressed in the positive direction
-1Axis is pressed in the negative direction
0Axis is not pressed

◆ joypad_get_axis_released()

int joypad_get_axis_released ( joypad_port_t  port,
joypad_axis_t  axis 
)

Get the direction of a "release" of an axis on a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
axisJoypad axis enumeration value (joypad_axis_t)
Return values
+1Axis was released in the positive direction
-1Axis was released in the negative direction
0Axis is not released

◆ joypad_get_axis_held()

int joypad_get_axis_held ( joypad_port_t  port,
joypad_axis_t  axis 
)

Get the direction that an axis is held on a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
axisJoypad axis enumeration value (joypad_axis_t)
Return values
+1Axis is being held in the positive direction
-1Axis is being held in the negative direction
0Axis is not being held

◆ joypad_get_direction()

joypad_8way_t joypad_get_direction ( joypad_port_t  port,
joypad_2d_t  axes 
)

Get the 8-way direction for a Joypad port's directional axes.

Parameters
portJoypad port number (joypad_port_t)
axes2D axes enumeration value (joypad_2d_t)
Returns
Joypad 8-way direction enumeration value (joypad_8way_t)

◆ joypad_accessory_reset()

void joypad_accessory_reset ( joypad_port_t  port)

Reset the accessory state for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)

◆ joypad_transfer_pak_wait_timer_init()

void joypad_transfer_pak_wait_timer_init ( joypad_port_t  port)

Initialize the Transfer Pak wait timer if necessary.

Parameters
portJoypad port number (joypad_port_t)

◆ joypad_accessory_detect_async()

void joypad_accessory_detect_async ( joypad_port_t  port)

Detect which accessory is inserted in an N64 controller.

  • Step 1: Ensure Transfer Pak is turned off
  • Step 2A: Set Controller Pak "linear paging bank" to 0
  • Step 2B: Backup the Controller Pak "label" area
  • Step 2C: Overwrite the Controller Pak "label" area
  • Step 2D: Read back the "label" area to detect Controller Pak
  • Step 2E: Restore the Controller Pak "label" area
  • Step 3A: Write probe value to detect Rumble Pak
  • Step 3B: Read probe value to detect Rumble Pak
  • Step 4A: Write probe value to detect Transfer Pak
  • Step 4B: Read probe value to detect Transfer Pak
  • Step 4C: Write probe value to turn off Transfer Pak
  • Step 5A: Write probe value to detect Snap Station
  • Step 5B: Read probe value to detect Snap Station
Parameters
portJoypad port to detect the accessory on (joypad_port_t)

◆ joypad_rumble_pak_toggle_async()

void joypad_rumble_pak_toggle_async ( joypad_port_t  port,
bool  active 
)

Turn the Rumble Pak motor on or off for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
activeWhether the motor should be on (true) or off (false)

◆ joypad_accessory_xfer_async()

void joypad_accessory_xfer_async ( joypad_port_t  port,
joypad_accessory_xfer_t  xfer,
uint16_t  start_addr,
void *  dst,
size_t  len,
joypad_accessory_io_callback_t  callback,
void *  ctx 
)

Read or write data from a Joypad accessory asynchronously.

This function can perform a bulk transfer of data from a Joypad accessory. A bulk transfer can read or write any number of bytes from any starting address in the accessory, including misaligned addresses.

It builds upon the lower level primitives joybus_accessory_read and joybus_accessory_write, which are limited to 32-byte, aligned data blocks. To perform misaligned writes, this function will perform read-modify-write operations on the accessory when needed.

This function can operate on any Joypad accessory.

The joybus protocol for accessories includes a builtin checksum to detect corruptions on the wire (that can indeed happen during normal operation). This function will automatically retry the transfer in case of a checksum error (up to some hardcoded number of times) and then eventually fail with a JOYPAD_ACCESSORY_ERROR_CHECKSUM error. If you get this error, it might be useless to try again and you can just assume the connection to the accessory is electrically faulty.

Note
Multi-bank Controller Paks (with sizes > 32 KiB), require an explicit bank switch operation to access data beyond the first 32 KiB. See joypad_controller_pak_set_bank; notice also that only 32 KiB at a time will be available so the valid address range for Controller Paks is 0x0000-0x7FFF.
Parameters
portJoypad port number (joypad_port_t)
xferTransfer direction ( JOYPAD_ACCESSORY_XFER_READ or JOYPAD_ACCESSORY_XFER_WRITE)
start_addrStarting address in the accessory to read from, or write to. There is no alignment requirement for this address.
dstDestination buffer to read accessory data into.
lenNumber of bytes to read. Any number of bytes can be read.
callbackCallback function to call when the read operation completes.
ctxOpaque pointer to pass to the callback function.

◆ joypad_accessory_xfer()

joypad_accessory_error_t joypad_accessory_xfer ( joypad_port_t  port,
joypad_accessory_xfer_t  xfer,
uint16_t  start_addr,
void *  dst,
size_t  len 
)

Read or write data from a joypad accessory.

This is the blocking version of joypad_accessory_xfer_async. Like the asynchronous version, this function can read or write any number of bytes from any starting address in the accessory.

This builds upon the lower level primitives joybus_accessory_read and joybus_accessory_write, which are limited to 32-byte, aligned data blocks.

Parameters
portJoypad port number (joypad_port_t)
xferTransfer direction (JOYPAD_ACCESSORY_XFER_READ or JOYPAD_ACCESSORY_XFER_WRITE)
start_addrStarting address in the accessory to read from. There is no alignment requirement for this address.
dstDestination buffer to read accessory data into.
lenNumber of bytes to read. Any number of bytes can be read.
Returns
joypad_accessory_error_t Error code indicating the result of the read operation.

◆ joypad_controller_pak_set_bank()

joypad_accessory_error_t joypad_controller_pak_set_bank ( joypad_port_t  port,
uint8_t  bank 
)

Select the active bank for a Controller Pak.

Most controller paks (including all first-party ones) have a single bank of 32 KiB of storage. However, some third-party controller paks have multiple banks, and require an explicit bank switch operation to access data beyond the first 32 KiB.

Generic transfer functions for accessories like joypad_accessory_xfer_async will only access the active bank.

There is no way to probe the number of banks in a Controller Pak at the hardware level. In situation where probing is necessary (eg: formatting functions), write tests can be performed to determine the number of banks.

Parameters
portJoypad port number (joypad_port_t)
bankBank number to switch to.
Returns
joypad_accessory_error_t Error code for the transfer operation.

◆ joypad_transfer_pak_enable_async()

void joypad_transfer_pak_enable_async ( joypad_port_t  port,
bool  enabled 
)

Enable or disable the Transfer Pak for a Joypad port.

Parameters
portJoypad port number (joypad_port_t)
enabledWhether the Transfer Pak should be enabled (true) or disabled (false)

◆ joypad_transfer_pak_load_async()

void joypad_transfer_pak_load_async ( joypad_port_t  port,
uint16_t  cart_addr,
void *  dst,
size_t  len 
)

Load data from the GB cartridge inserted in a Transfer Pak.

Parameters
portJoypad port number (joypad_port_t)
cart_addrStarting address in the GB cartridge to load from.
[out]dstDestination buffer to load cartridge data into.
lenNumber of bytes to load (must be a multiple of 32).

◆ joypad_transfer_pak_store_async()

void joypad_transfer_pak_store_async ( joypad_port_t  port,
uint16_t  cart_addr,
void *  src,
size_t  len 
)

Store data on the GB cartridge inserted in a Transfer Pak.

Parameters
portJoypad port number (joypad_port_t)
cart_addrStarting address in the GB cartridge to store into.
[in]srcSource buffer of data to store on GB cartridge.
lenNumber of bytes to store (must be a multiple of 32).