# Getting Control Pad Input

This section looks at user interaction with the control pad, discussing the following topics:

- Utility Functions for Using the Control Pad
- The jsanimation.c Example
- The basicslideshow.c Example

## Utility Functions for Using the Control Pad

All examples in the Jumpstart2 example set use the functions from controlpad.c in the Examples folder, which offers the following utility functions:

- `ControlPadSanityCheck`-makes sure the event broker has been initialized.
- `InitControlPad`-connects a task to the event broker for control pad interaction.
- `DoControlPad`-queries the specified control pad and de-bounces specified key presses
- `ReturnPreviousControlPad`-returns the state of the controlpad as it is remembered
- `KillControlPad`-disconnects the task from the event broker and frees resources

## The jsanimation.c Example

The animation example in the Jumpstart2 folder has been simplified to clarify how control pad interaction occurs. The `main()` function in jsanimation.c contains a loop that continuously calls `HandleControlPad()`. `HandleControlPad()` recognizes two button events:

- If the user presses the Start button, the game is over.
- If the user presses Control-A, the explosion is triggered.

`kContinuousMask` specifies for which buttons continuous presses are allowed.

Example 1: The HandleControlPad function in jsanimation

``

    #define     kContinuousMask     ( ControlA )

    int32 HandleControlPad( void )
    /*
        Respond to control pad input:
          - The A key is enabled for continuous presses.
          - Start button means quit the program.
          - A button and arrows means fire (explode the cel).
        Returns -1 if the user pressed the start button to quit, otherwise 0.
    */
    {
        uint32  controlBits;
        Point   aUFOCenter;
        int32 retValue = 0;

        DoControlPad(1, &controlBits, kContinuousMask );

        if ( controlBits & ControlStart )
    /* If the user has pressed the START button, the game is over. */
        {
            retValue = -1;
            goto DONE;
        }
    /* ControlA triggers the explosion */
        if ( controlBits & ControlA )
        {
            if ( !gBoomCount )                            /* Don't fire until previous explosion is finished */
            {
                gBoomCount = gExplosionAnim->num_Frames;
                                    /* Position center of explosion at center of the UFO */
                aUFOCenter = CalcCCBCenterPoint(gUFO_CCB);
                CenterCCB(gExplosionCCB, aUFOCenter.pt_X, aUFOCenter.pt_Y);
                                    /* Get a random center for the next UFO */
                CenterCCB(gUFO_CCB, (Coord) Random(DISPLAY_WIDTH), (Coord)
                                                             Random(DISPLAY_HEIGHT));

            }
        }

    DONE:
        return retValue;

    }

## The basicslideshow.c Example

The jsbasicslideshow.c example uses the same `JSGetControlPad()` function but a more complex `HandleControlPad()` function that allows more complex user input.

Note that this example includes controlpad.c and calls `InitControlPad()` during initialization and `KillControlPad()` during shutdown.

Example 2: The HandleControlPad function in jsbasicslideshow.c

``

    int32 HandleControlPad( void )
    /*
    Respond to the user's control pad input.
    - Right and down arrows mean show next image in list
    - Left and up arrows mean show previous image in list
    - Start button means quit the program
    - B button means show the other buffer
    - C button means toggle automatic display mode
    Returns -1 if the user pressed the start button to quit, otherwise 0.
    */
    {
        int32 retValue = 0;
        uint32  controlBits;

        DoControlPad(1, &controlBits, 0 );
    /* no continuous button presses */

    /* if the Start button is pressed, the user wants to quit */
        if ( controlBits & ControlStart )
        {
            retValue = -1;
        }

    /* if the A button is pressed \xc9  (no action in this interface) */
        else if ( controlBits & ControlA )
        {
            ;
        }

    /* if button B is pressed, display the other buffer */
        else if ( controlBits & ControlB )
            {
            gScreenContext->sc_curScreen =
                                    1 - gScreenContext->sc_curScreen;
            }
    /* if button C is pressed toggle autoshow */
        else if ( controlBits & ControlC )
            {
            gAutoShowFlag = !gAutoShowFlag;

            PRT( ("Auto-show mode is ") );
            if ( gAutoShowFlag )
                {
                 PRT( ("TRUE\n") );
                 }
            else
                PRT( ("FALSE\n") );

            }

        else if ( controlBits &
            (ControlUp | ControlLeft | ControlDown | ControlRight))
            /* Arrows mean move one image forward or backward */
            {
            if ( controlBits & ControlUp )
                {
                LoadPreviousImage();
                }
            else if ( controlBits & ControlLeft )
                {
                LoadPreviousImage();
                }
            else if ( controlBits & ControlDown )
                {
                LoadNextImage();
                }
            else if ( controlBits & ControlRight )
                {
                LoadNextImage();
                }

            }

        return retValue;

    }