Data Structures | Modules | Files | Typedefs | Functions

Controller Subsystem
[libdragon]

Controller and accessory interface. More...

Data Structures

struct  SI_condat
 SI Controller Data. More...
struct  controller_data
 Structure for interpreting SI responses. More...

Modules

 Mempak Filesystem Routines
 

Managed mempak interface.


Files

file  controller.c
 

Controller Subsystem.


file  controller.h
 

Controller Subsystem.


Typedefs

typedef struct SI_condat _SI_condat
 SI Controller Data.
typedef struct controller_data _controller_data
 Structure for interpreting SI responses.

Functions

void controller_init ()
 Initialize the controller subsystem.
int eeprom_present ()
 Probe the EEPROM interface.
void eeprom_read (int block, uint8_t *const buf)
 Read a block from EEPROM.
void eeprom_write (int block, const uint8_t *const data)
 Write a block to EEPROM.
void controller_read (struct controller_data *output)
 Read the controller button status for all controllers.
void controller_scan ()
 Scan the controllers to determine the current button state.
struct controller_data get_keys_down ()
 Get keys that were pressed since the last inspection.
struct controller_data get_keys_up ()
 Get keys that were released since the last inspection.
struct controller_data get_keys_held ()
 Get keys that were held since the last inspection.
struct controller_data get_keys_pressed ()
 Get keys that are currently pressed, regardless of previous state.
int get_dpad_direction (int controller)
 Return the DPAD calculated direction.
void execute_raw_command (int controller, int command, int bytesout, int bytesin, unsigned char *out, unsigned char *in)
 Execute a raw PIF command.
int get_controllers_present ()
 Return a bitmask representing which controllers are present.
int get_accessories_present ()
 Return a bitmask specifying which controllers have recognized accessories.
int read_mempak_address (int controller, uint16_t address, uint8_t *data)
 Read a chunk of data from a mempak.
int write_mempak_address (int controller, uint16_t address, uint8_t *data)
 Write a chunk of data to a mempak.
int identify_accessory (int controller)
 Identify the accessory connected to a controller.
void rumble_start (int controller)
 Turn rumble on for a particular controller.
void rumble_stop (int controller)
 Turn rumble off for a particular controller.

SI status register bit definitions



#define SI_STATUS_DMA_BUSY   ( 1 << 0 )
 SI DMA busy.
#define SI_STATUS_IO_BUSY   ( 1 << 1 )
 SI IO busy.

Bitmasks for controller status

See also:
get_controllers_present
get_accessories_present


#define CONTROLLER_1_INSERTED   0xF000
 Controller 1 Inserted.
#define CONTROLLER_2_INSERTED   0x0F00
 Controller 2 Inserted.
#define CONTROLLER_3_INSERTED   0x00F0
 Controller 3 Inserted.
#define CONTROLLER_4_INSERTED   0x000F
 Controller 4 Inserted.

Accessory ID Values

See also:
identify_accessory


#define ACCESSORY_NONE   0
 No accessory present.
#define ACCESSORY_MEMPAK   1
 Mempak present.
#define ACCESSORY_RUMBLEPAK   2
 Rumblepak present.
#define ACCESSORY_VRU   3
 VRU present.

SI Error Values



#define ERROR_NONE   0x0
 No error occured.
#define ERROR_BAD_COMMAND   0x1
 Command not recognized or malformed.
#define ERROR_NOT_PRESENT   0x2
 Controller not present.

Detailed Description

Controller and accessory interface.

The controller subsystem is in charge of communication with all controllers and accessories plugged into the N64. The controller subsystem is responsible for interfacing with the serial interface (SI) registers to provide controller data, mempak and rumblepak interfacing, and EEPROM interfacing.

Code wishing to communicate with a controller or an accessory should first call controller_init. Once the controller subsystem has been initialized, code can either scan the controller interface for changes or perform direct reads from the controller interface. Controllers can be enumerated with get_controllers_present. Similarly, accessories can be enumerated with get_accessories_present and identify_accesory.

To read controllers in a managed fashion, call controller_scan at the beginning of each frame. From there, get_keys_down, get_keys_up, get_keys_held and get_keys_pressed will return the status of all keys relative to the last scan. get_dpad_direction will return a number signifying the polar direction that the D-Pad is being pressed in.

To read controllers in a non-managed fashion, call controller_read. This will return a structure consisting of all button states on all controllers currently inserted.

To enable or disable rumbling on a controller, use rumble_start and rumble_stop. These functions will turn rumble on and off at full speed respectively, so if different rumble effects are desired, consider using the Timer Subsystem for accurate timing.

A mempak attached to a controller can be treated in one of two ways: as a raw binary string, or as a formatted mempak with notes. The former allows storage of any data as long as it fits, in any format convenient to the coder, but destroys any non-homebrew data on the mempak. The latter is recommended as it is completely compatible with official N64 games, though it allows less data to be stored due to filesystem overhead. To read and write raw sectors, use read_mempak_address and write_mempak_address. The Mempak Filesystem Routines handles reading and writing from the mempak in a way compatible with official games.


Function Documentation

void controller_read ( struct controller_data output  ) 

Read the controller button status for all controllers.

Read the controller button status immediately and return results to data. If calling this function, one should not also call controller_scan as this does not update the internal state of controllers.

Parameters:
[out] output Structure to place the returned controller button status
void controller_scan (  ) 

Scan the controllers to determine the current button state.

Scan the four controller ports and calculate the buttons state. This must be called before calling get_keys_down, get_keys_up, get_keys_held, get_keys_pressed or get_dpad_direction.

int eeprom_present (  ) 

Probe the EEPROM interface.

Prove the EEPROM to see if it exists on this cartridge.

Returns:
Nonzero if EEPROM present, zero if EEPROM not present
void eeprom_read ( int  block,
uint8_t *const   buf 
)

Read a block from EEPROM.

Parameters:
[in] block Block to read data from. The N64 accesses eeprom in 8 byte blocks.
[out] buf Buffer to place the eight bytes read from EEPROM.
void eeprom_write ( int  block,
const uint8_t *const   data 
)

Write a block to EEPROM.

Parameters:
[in] block Block to write data to. The N64 accesses eeprom in 8 byte blocks.
[in] data Eight bytes of data to write to block specified
void execute_raw_command ( int  controller,
int  command,
int  bytesout,
int  bytesin,
unsigned char *  out,
unsigned char *  in 
)

Execute a raw PIF command.

Send an arbitrary command to a controller and receive arbitrary data back

Parameters:
[in] controller The controller (0-3) to send the command to
[in] command The command byte to send
[in] bytesout The number of parameter bytes the command requires
[in] bytesin The number of result bytes expected
[in] out The parameter bytes to send with the command
[out] in The result bytes returned by the operation
int get_accessories_present (  ) 

Return a bitmask specifying which controllers have recognized accessories.

Queries the controller interface and returns a bitmask specifying which controllers have recognized accessories present. See CONTROLLER_1_INSERTED, CONTROLLER_2_INSERTED, CONTROLLER_3_INSERTED and CONTROLLER_4_INSERTED.

Returns:
A bitmask representing accessories recognized
int get_controllers_present (  ) 

Return a bitmask representing which controllers are present.

Queries the controller interface and returns a bitmask specifying which controllers are present. See CONTROLLER_1_INSERTED, CONTROLLER_2_INSERTED, CONTROLLER_3_INSERTED and CONTROLLER_4_INSERTED.

Returns:
A bitmask representing controllers present
int get_dpad_direction ( int  controller  ) 

Return the DPAD calculated direction.

Return the direction of the DPAD specified in controller. Follows standard polar coordinates, where 0 = 0, pi/4 = 1, pi/2 = 2, etc... Returns -1 when not pressed. Must be used in conjunction with controller_scan

Parameters:
[in] controller The controller (0-3) to inspect
Returns:
A value 0-7 to represent which direction is held, or -1 when not pressed
struct controller_data get_keys_down (  )  [read]

Get keys that were pressed since the last inspection.

Return keys pressed since last detection. This returns a standard controller_data struct identical to controller_read. However, buttons are only set if they were pressed down since the last controller_scan.

Returns:
A structure representing which buttons were just pressed down
struct controller_data get_keys_held (  )  [read]

Get keys that were held since the last inspection.

Return keys held since last detection. This returns a standard controller_data struct identical to controller_read. However, buttons are only set if they were held since the last controller_scan.

Returns:
A structure representing which buttons were held
struct controller_data get_keys_pressed (  )  [read]

Get keys that are currently pressed, regardless of previous state.

This function works identically to controller_read except for it is safe to call when using controller_scan.

Returns:
A structure representing which buttons were pressed
struct controller_data get_keys_up (  )  [read]

Get keys that were released since the last inspection.

Return keys released since last detection. This returns a standard controller_data struct identical to controller_read. However, buttons are only set if they were released since the last controller_scan.

Returns:
A structure representing which buttons were just released
int identify_accessory ( int  controller  ) 

Identify the accessory connected to a controller.

Given a controller, identify the particular accessory type inserted.

Parameters:
[in] controller The controller (0-3) to identify accessories on
Return values:
ACCESSORY_RUMBLEPAK The accessory connected is a rumblepak
ACCESSORY_MEMPAK The accessory connected is a mempak
ACCESSORY_VRU The accessory connected is a VRU
ACCESSORY_NONE The accessory was not recognized
int read_mempak_address ( int  controller,
uint16_t  address,
uint8_t *  data 
)

Read a chunk of data from a mempak.

Given a controller and an address, read 32 bytes from a mempak and return them in data.

Parameters:
[in] controller Which controller to read the data from (0-3)
[in] address A 32 byte aligned offset to read from on the mempak
[out] data Buffer to place 32 bytes of data read from the mempak
Return values:
0 if reading was successful
-1 if the controller was out of range
-2 if there was no mempak present in the controller
-3 if the mempak returned invalid data
void rumble_start ( int  controller  ) 

Turn rumble on for a particular controller.

Parameters:
[in] controller The controller (0-3) who's rumblepak should activate
void rumble_stop ( int  controller  ) 

Turn rumble off for a particular controller.

Parameters:
[in] controller The controller (0-3) who's rumblepak should deactivate
int write_mempak_address ( int  controller,
uint16_t  address,
uint8_t *  data 
)

Write a chunk of data to a mempak.

Given a controller and an address, write 32 bytes to a mempak from data.

Parameters:
[in] controller Which controller to write the data to (0-3)
[in] address A 32 byte aligned offset to write to on the mempak
[out] data Buffer to source 32 bytes of data to write to the mempak
Return values:
0 if writing was successful
-1 if the controller was out of range
-2 if there was no mempak present in the controller
-3 if the mempak returned invalid data
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines