1.2 Standard Controller

If you were to directly call N64 OS functions to perform Standard Controller processes, you would need to perform a number of transactions just to read the status of the Controller. However, with the NuSystem, these low-level processes are encapsulated, thus making reading of the Controller easy.

Below are the six representative Controller functions provided by the NuSystem:

nuContInit
Initializes the Controller and other SI devices

nuContDataGet
Gets the Controller data

nuContDataGetAll
Gets the data of all four Controllers


nuContDataGetEx
Expanded version of getting the Controller data

nuContDataGetExAll
Expanded version of getting the data of 4 Controllers

nuContQueryRead
Reads the Controller status

In most cases, these are the only functions you will need. The NuSystem supports many other Controller functions as well, so except for some special processes you will not need to make direct use of the N64 OS Controller functions.


1.2.1 Initializing the Controller

To perform Controller processes, the first thing you need to do is call the SI device initialization function nuContInit.


Function name: nuContInit
Syntax: u8 nuContInit(void)
Arguments: None
Return Value: Bit pattern of the connected Controller

Internally, the nuContInit function initializes the SI Manager (by calling the nuSiMgrInit function) and then initializes the Controller Manager, the Controller Pak Manager and the Rumble Pak Manager (by calling the nuContMgrInit function, nuContPakInit function and nuContRmbInit function).

The bit pattern of the connected Controller is stored in the return value from the nuContInit function. In order from the lowest bit, the return value corresponds to Controller 1, 2, 3 and 4.

The number of valid Controllers is set in the NuSystem global variable nuContNum when the Controller Manager is initialized, so you can reference this variable when necessary to check how many Controllers are connected.


Variable name: nuContNum
Definition: u32 nuContNum
Description: The number of connected Controllers

The nuContInit function is useful because it calls the representative Managers (for the Controller, Controller Pak and Rumble Pak). However, it can also be wasteful because it may perform unnecessary processes. Initializing and registering the Rumble Pak Manager even for a game that does not support the Rumble Pak is one such an example. In reality, nuContInit is a function for beginning N64 programmers, and once you have gained an understanding of the operation of each Manager, you should create your own initialization routines based on the source of the function.

1.2.2 Reading the Controller Data

Once you have started up the Controller Manager, the Controller data is read in every other frame and stored in an internal buffer of NuSystem. The contents of this internal buffer can be read out to the user area by calling such a function as nuContDataGet. If you want to read out the status of one Controller, call the nuContDataGet function. If you want to read out the status of all Controllers, call the nuContDataGetAll function.


Function name: nuContDataGet
Syntax: void nuContDataGet(OSContPad *contpad, u32 cont_no)
Arguments: contpad Controller data structure
  cont_no The number of the controller to read
Return Value: None

Function name: nuContDataGetAll
Syntax: void nuContDataGetAll(OSContPad *contpad)
Arguments: contpad Controller data structure
Return Value: None

  typedef struct
  {
   u16 button;
   s8  stick_x;
   s8  stick_y;
   u8  errno;
  } OSContPad;
  button Bit pattern representing whether button is ON or OFF
    Check by doing a bitwise AND with the constant, CONT_A etc. (see )
  stick_x Horizontal tilt of the Control stick (-128 - 127)*1
  stick_y Vertical tilt of the Control stick (-128 ~ 127)*1
  errno Error number

 *1(Note) Since the Controllers vary, the upper-limit value that can be input is not the same. To deal with this variation, please write your programs with the following values for the actual range of use:

  Horizontal direction (X axis) -61-61
  Vertical direction (Y axis) -63-63
  X-axis diagonal -45-45
  Y-axis diagonal -47-47

Depending on the game, you may want to get trigger data like whether OFF has changed to ON, rather than about whether a button is being pressed at the time. The NuSystem defines the NUContData structure, which is the OSContPad structure with added trigger data. You can get trigger data by using the nuContDataGetEx function, which is the expanded version of the nuContDataGet function. To get data from all Controllers, use the nuContDataExALL function.


Function name: nuContDataGetEx
Syntax: void nuContDataGetEx(NUContData *contdata, u32 padno)
Arguments: contdata Pointer for storing the Controller data
  padno The pad number
Return Value: None

Function name: nuContDataGetExAll
Syntax: void nuContDataGetExAll(NUContData *contdata)
Arguments: contdata Pointer for storing the Controller data
Return Value: None

typedef struct
  {
    u16 button;
    s8  stick_x;
    s8  stick_y;
    u8  errno;
    u16 trigger;
  } NUContData;
  button Bit pattern representing whether button is ON or OFF
    Check by doing a bitwise AND with the constant, CONT_A etc. (see )
  stick_x Horizontal tilt of the Control stick *2
  stick_y Vertical tilt of the Control stick *2
  errno Error number
  trigger Bit pattern of the trigger data (the same order of "button")

 *2(Note) Since the Controllers vary, the upper-limit value that can be input is not the same. To deal with this variation, please write your programs with the following values for the real range of use:

  Horizontal direction (X axis) -61-61
  Vertical direction (Y axis) -63-63
  X-axis diagonal -45-45
  Y-axis diagonal -47-47

The trigger data is calculated with a logical operation involving the contents of the "contdata" argument passed to the function, and the Controller data read at that time, so be sure to make contdata a static variable.

1.2.3 Reading the Controller Status

When the Controller Manager is initialized, the Controller status (i.e., whether or not there is a Controller and the type) is stored in the NuSystem global variable nuContStatus. If you want to read out the current Controller status, call the nuContQueryRead function. This result is also stored in nuContStatus, but it takes about 2 milliseconds to get the status this way.


Variable name: nuContStatus
Definition: OSContStatus  nuContStatus[NU_CONT_MAXCONTROLLERS]

Function name: nuContQueryRead
Syntax: void nuContQueryRead(void)
Arguments: None
Return Value: None

typedef struct
  {
    u16 type;
    u8  status;
    u8  errno;
  } OSContStatus;
  type The type of the Controller connected to the port
    This type and the constant CONT_JOYPORT etc. (see ) are bit ORed for the check.
  status Controller status
    For example, if the Controller Pak is connected, the CONT_CARD_ON bit is ON
  errno Error number

To verify that the Standard Controller is inserted, mask with CONT_TYPE_MASK and then check whether equal to CONT_TYPE_NORMAL. If the Controller is not connected to the port, then the CONT_NO_RESPONSE_ERROR bit is set in errno.