Standard N64 Controller

What is the Standard Controller?
The standard N64 Controller, illustrated below, is a controller which is marketed by Nintendo to be used with the N64 Control Deck. This Controller is distributed as part of the Nintendo 64 Control Set or may be purchased through Nintendo authorized retailers. This chapter addresses common questions asked by software developers concerning the standard N64 Controller.

Standard Controller Recognition

Figure 26.2.1 Standard Controller

Figure 26.2.2 Standard Controller (back view)

How to Build the Program for the Standard Controller
The chart below outlines the flow for a program used to handle the Standard Controller. An explanation of each step follows.

Figure 26.2.3 Flow for Standard Controller Program

1. Make the initial settings in order to use the serial interface (SI). Execute the osContInit() function. This need only be done once. With the Controller, there is no need to initialize the SI device itself.

2. Verify that the Standard Controller is plugged in. This is done by checking the status that is returned after execution of the osContInit() function. To be specific, you need to verify that the value of the "type" member variable of the OSContStatus structure, which is an argument of the osContInit() function, is equal to CONT_TYPE_NORMAL when the value of "type" is masked with CONT_TYPE_MASK. When the Standard Controller is connected, both the CONT_ABSOLUTE bit and the CONT_JOYPORT bit are set in "type." CONT_TYPE_NORMAL incorporates the bits for both CONT_ABSOLUTE and CONT_JOYPORT.

3. After the first two steps are performed, execute the osContStartReadData() function to begin reading the data from the Controller Pak. Executing this function starts the reading of data from the control stick and the buttons.

4. As the final step, return the data read from the control stick and the buttons of the Controller to the structure used for storing the data. Execute the osContGetReadData() function. This returns the data read from the Controller's control stick and the buttons to the function's osContPad structure argument.

By repeating these steps to read and get data, you can build a program which responds to the Controller in real time.

For a concrete example, see the sample program in section 26.2.4.1, "osContStartReadData, osContGetRead Data

Standard Controller Function Specifications
Following are descriptions of the the library functions used to handle the Standard Controller in an N64 program.

Function Name - osContStartReadData, osContGetReadData
Start reading data from the Controller

Syntax

    #include

    s32 osContStartReadData(OSMesgQueue *mq);

    void osContGetReadData(OSContPad *pad);

Description
The osContStartReadData and osContGetReadData functions obtain game Controller input settings.

The osContStartReadData function issues a read data command to obtain game Controller input settings, and the osContGetReadData call returns 3D Stick data and button settings to the location pointed to by the pad argument.

You must supply a block of memory large enough for MAXCONTROLLERS structures of type OSContStatus. The message queue pointed to by the mq argument must be an initialized message queue associated with the OS_EVENT_SI event. Please see the osSetEventMesg function in the N64 Online Function Reference Manual, for details on how to create this association.

The read data command will take about two milliseconds to pull data back from the game Controllers. You can use the osRecvMesg call on the message queue specified by the mq argument to wait for this event.

If the osContSetCh() function (please see Section 26.1.6.4, "osContSetCh") sets the number of direct-type SI devices accessed at a value less than the MAXCONTROLLERS number, then the area secured can be smaller than the MAXCONTROLLERS number, provided more devices are not added later.

    typedef struct {
            u16     button;         /* Controller button data */
            s8      stick_x;        /* Control stick's X coordinate position */
            s8      stick_y;        /* Control stick's Y coordinate position */
            u8      errno;          /* Error values returned from the Controller  */
    } OSContPad;

The Control Stick's coordinate positions stick_x and stick_y are signed characters with the range of -128 ~ 127. However, for the actual program we recommend using values within the ranges shown below:

Left/right X axis | +/- 61
Up/down Y axis | +/- 63
X axis incline | +/- 45
Y axis incline | +/- 47

For additional information, please see Section 26.2.5, Programming Notes.

The 3D Control Stick data is of type signed char and in the range between 80 and -80. The game Controller's input settings can be the following defined constants:

- START_BUTTON is the start button

- A_BUTTON is the A Button

- B_BUTTON is the B Button

- U_CBUTTONS is the C Button Up

- D_CBUTTONS is the C Button Down

- L_C_BUTTONS is the C Button Left

- R_CBUTTONS is the C Button Right

- U_JPAD is the Control Stick Up

- D_JPAD is the Control Stick Down

- L_JPAD is the Control Stick Left

- R_JPAD is the Control Stick Right

- Z_TRIG is the Z Button

- L_TRIG is the L Button

- R_TRIG is the R Button

The error number returned from game Controllers include:

CONT_NO_RESPONSE_ERROR
The controller does not respond.

CONT_OVERRUN_ERROR
The controller sends data at a higher data transfer rate than the hardware can handle. In this case, you should ignore the data.

Example

    void mainproc(void)
    {
            OSMesgQueue     intMesgQueue;
            OSMesg          intMesgBuf[1];
            OSContStatus    sdata[MAXCONTROLLERS];
            OSContPad       rdata[MAXCONTROLLERS];
            u8              pattern;
            int             i;
            int             cont_exist = 0;
    /*
            osCreateMesgQueue(&intMesgQueue,&intMesgBuf,1);
            osSetEventMesg(OS_EVENT_SI, &intMesgQueue, NULL);
            osContInit(&*intMesgQueue, &pattern, &sdata[0]);
    osCreateMesgQueue(&intMesgQueue, intMesgBuf, 1);
            osSetEventMesg(OS_EVENT_SI, &intMesgQueue, NULL);
            osContInit(&intMesgQueue, &pattern, &sdata[0]);

            /* Confirm if controller is inserted */
            for(i = 0; i < MAXCONTROLLERS; i++){
                    if(((pattern >> i) & 1) && (sdata[i].errno == 0)){
                            if((sdata[i].type & CONT_TYPE_MASK) == CONT_TYPE_NORMAL){
                                    osSyncPrintf(controller is inserted in port);
                                    cont_exist = 1;
                            }
                    }
            }

            /* if controller is inserted */
            if(cont_exist){
                    /* start reading controller data */
                    osContStartReadData(&intMesgQueue);
                           .
                           .
                    /* “confirm the end of reading */
                    osRecvMesg(&intMesgQueue, NULL, OS_MESG_BLOCK);
                    /* get controller data */
                    osContGetReadData(&rdata[0]);
            }
    }

Programming Notes

1. The Control Stick Reset Function
   Do not create a command during game play that involves simultaneously pressing the Left, Right, and Start button.

   Simultaneously pressing these three buttons resets the neutral position of the Standard Controller's Control Stick. Thus, make sure that no essential control actions inside the game reset the Control Stick. And conversely, make sure that resetting the Control Stick has no unexpected action on the game.

2. Simultaneously Pressing Up/Down or Left/Right on the Control Pad
   Be sure the game does not hang or other problems arise when either the Up/Down, or Left/Right are pressed simultaneously on the Control Pad. Depending upon the situation, the user might press Up/Down or Left/Right at the same time.

   As countermeasures to such an occurrence you can:

   - Establish the priority for input from Up/Down and Left/Right
   - Ignore this kind of input

3. Manipulation of Unused Buttons
   Be sure the game does not hang or other problems arise when the user presses unused buttons during a game. The same goes for manipulation of other Controllers when a game is only designed to play from Controller 1.

   Players sometimes press unused buttons during game play. Unexpected input might also come from peripheral devices.

   Please be especially careful about buttons that are not used during normal game play but are used when the game is run in debug mode.

4. Playing with the Control Stick
   Set some lower value for play with the Control Stick in order to avoid detecting input when the stick has not been touched.

   The coordinates of the Control Stick when it is not being touched are not necessarily set back to the origin. Moreover, the actual position will vary from device to device, and even within the same device from one time to the next.

5. Upper Limit Value for the Control Stick
   The upper limit value which can be input with the Control Stick varies from Controller to Controller. For important manipulations be careful not to set values which cannot be input.

   Control Stick resolution differs from Controller to Controller. Moreover, as a Controller gets old, the uppermost value that the Control Stick can input can decline. To handle the variation between Control Sticks, we recommend you set the actual usable range to the values shown below.

   Left/right X axis | +/- 61
   Up/down Y axis | +/- 63
   X axis incline | +/- 45
   Y axis incline | +/- 47

   3D Control Stick - Explanation of Symbols

   XA | Maximum horizontal center stop width
   XB | Minimum horizontal counts left
   XB' | Minimum horizontal counts right
   XC | Minimum horizontal counts with Control Stick in the up/right direction
   XC' | Minimum horizontal counts with Control Stick in the up/left direction
   XC'' | Minimum horizontal counts with Control Stick in the down/left direction
   XC''' | Minimum horizontal counts with Control Stick in the down/right direction
   YA | Maximum vertical center stop width
   YB | Minimum vertical counts up
   YB' | Minimum vertical counts downM
   YC | Minimum vertical counts with Control Stick in the up/right direction
   YC' | Minimum vertical counts with Control Stick in the up/left direction
   YC'' | Minimum vertical counts with Control Stick in the down/left direction
   YC''' | Minimum vertical counts with Control Stick in the down/right direction

   Figure 26.2.4 3D Control Stick Values

   A new Controller will present the following values.

   XA | MAX: 7 Counts
   XBM: minimum guaranteed value of XB, XB' | MIN: 70 Counts
   XCM: minimum guaranteed value of XC, XC', XC'', XC''' | MIN: 54 Counts
   YA: | MAX: 7 Counts
   YBM: minimum guaranteed value of YB, YB' | MIN: 74 Counts
   YCM: minimum guaranteed value of YC, YC', YC'', YC''' | MIN: 56 Counts

   A Controller which has been used for approximately 5 million direction changes will present these values.

   XA | MAX: 7 Counts
   XBM : minimum guaranteed value of XB, XB' | MIN: 68 Counts
   XCM : minimum guaranteed value of XC, XC', XC'', XC''' | MIN: 52 Counts
   YA | MAX: 7 Counts
   YBM : minimum guaranteed value of YB, YB' | MIN: 70 Counts
   YCM : minimum guaranteed value of YC, YC', YC'', YC''' | MIN: 54 Counts

   Given the above values, the program's actual range can be calculated, as follows.

   Horizontal direction of X axis (one side) MIN = XBM - XA = 68 - 7 = 61 Counts

   Vertical direction of Y axis (one side) MIN = YBM - YA = 70 - 7 = 63 Counts

   Diagonal direction of X axis (one side) MIN (45°) = XCM - XA = 52 - 7 = 45 Counts

   Diagonal direction of Y axis (one side) MIN (45°) = YCM - YA = 54 - 7 = 47 Counts

   If resolution is required, then calibration will need to be performed for every game (and for every Controller). However, correcting the Controller every time can create problems related to the fairness of a game. Additionally, if you do not need to worry about the type of game and the central dead zone width (for example knocking down blocks), then the XBM, XCM, YBM, YCM values can act as the actual range in the program.

   In short, you'll need to adjust the central dead zone width on the application side in accordance with the nature of the game.

6. Control Stick Input Values
   Make sure that nothing unusual happens no matter what value in the range from -128 to 127 is input, either Up/Down or Left/Right with the Control Stick.

   If the neutral position of the Control Stick is off center, then these values could be input as the maximum (minimum) values.

Copyright © 1999 Nintendo of America Inc. All Rights Reserved Nintendo and N64 are registered trademarks of Nintendo Last Updated January, 1999