Click here if you are stuck in someone else's frames.
Sample Program using Joystick Game Library Functions

Here's some sample code that shows how the library functions can be used to provide Joystick control to your programs.

    /* JOYTEST.C -- Illustrates how joysticks are used in some games.
     * by Gary Neal, Jr. -- garyneal@oocities.com
     */

    #include <conio.h>                   /* Console specific IO */
    #include "include\vmode.h"           /* Video functions */
    #include "include\joystick.h"        /* Our joystick functions */

    /* Function prototype */
    void CallibrateJoystick(int joystickNum);

    /* Global variables */
    struct {
        unsigned short Min;              /* Minimum pot value */
        unsigned short Mid;              /* Middle pot value */
        unsigned short Max;              /* Maximum pot value */
    } joyPotLimit[4];                    /* Pot value limits */

    /* Begin main program */
    int main(int argc, char *argv[])
    {
        int X = 160, Y = 100, C = 1;     /* Pixel attributes */
        int buttonReleased = 1;          /* Button released flag */

        joystickDirectAccess = 1;        /* Use direct access for testing */
        Joyin(1);                        /* Test for joystick pots */
        if (joyPotVal[JsA_Xaxis] == 0 && joyPotVal[JsA_Yaxis] == 0) {
            cputs("No joystick detected...\r\nAborting...\r\n");
            return 1;                    /* Quit if joystick pots not detected */
        }

        /* Set access according to input parameter */
        if (argc >= 2 && *argv[1] == '0')
            joystickDirectAccess = 0;
        else
            joystickDirectAccess = 1;

        CallibrateJoystick(0);           /* Callibrate Joystick A */

        if (!SetVideoMode(VGA256)) {
            cputs("Could not initialize VGA system...\r\n");
            return 1;
        }

        while (kbhit()) getch();         /* Clear the keyboard */

        /* End program at the stroke of a key */
        while (!kbhit()) {
            Joyin(0);                    /* Get joystick pot values */

            SetPixel(X, Y, 0);           /* Erase pixel from screen */

            /* Get horizontal coordinate and adjust X-coordinate */
            if (joyPotVal[JsA_Xaxis] < joyPotLimit[JsA_Xaxis].Min) {
                if (--X < 0) X = 0;
            } else if (joyPotVal[JsA_Xaxis] > joyPotLimit[JsA_Xaxis].Max) {
                if (++X >= ScreenWidth) X = ScreenWidth - 1;
            }

            /* Get vertical coordinate and adjust Y-coordinate */
            if (joyPotVal[JsA_Yaxis] < joyPotLimit[JsA_Yaxis].Min) {
                if (--Y < 0) Y = 0;
            } else if (joyPotVal[JsA_Yaxis] > joyPotLimit[JsA_Yaxis].Max) {
                if (++Y >= ScreenHeight) Y = ScreenHeight - 1;
            }

            /* Change color if button is pressed */
            if (buttonReleased) {
                if (JoystickButtonPressed(JsAbutton1)) {
                    C = ++C % ScreenColors;
                    buttonReleased = 0;
                }
            } else
                buttonReleased = !JoystickButtonPressed(JsAbutton1);

            /* Redraw pixel on screen */
            if (C == 0) SetPixel(X, Y, 15);
            SetPixel(X, Y, C);
        }

        /* Clean up and return */
        while (kbhit()) getch();         /* Clear the keyboard */
        SetVideoMode(TEXT_MODE);
        return 0;
    }

    void CallibrateJoystick(int joystickNum)
    {
        int buttonMask, potBase;

        buttonMask = 0x30 << ((joystickNum & 1) << 1);
        potBase    = (joystickNum & 1) << 1;

        cprintf("Callibrating Joystick %c", ((joystickNum & 1) ? 'B' : 'A'));
        while (kbhit()) getch();         /* Clear the keyboard */
        cputs("\r\nMove joystick to far upper-left and press a button.");
        while (!JoystickButtonPressed(buttonMask) && !kbhit()) {
            Joyin(0);                    /* Get joystick pots */
            joyPotLimit[potBase].Min     = joyPotVal[potBase]     + 20;
            joyPotLimit[potBase + 1].Min = joyPotVal[potBase + 1] + 20;
        }
        while (JoystickButtonPressed(buttonMask) && !kbhit());
        while (kbhit()) getch();         /* Clear the keyboard */
        cputs(" [OK]\r\nMove joystick far lower-right and press a button.");
        while (!JoystickButtonPressed(buttonMask) && !kbhit()) {
            Joyin(0);                    /* Get joystick pots */
            joyPotLimit[potBase].Max     = joyPotVal[potBase]     - 20;
            joyPotLimit[potBase + 1].Max = joyPotVal[potBase + 1] - 20;
        }
        while (JoystickButtonPressed(buttonMask) && !kbhit());
        while (kbhit()) getch();         /* Clear the keyboard */
        cputs(" [OK]\r\nCenter the joystick and press a button.");
        while (!JoystickButtonPressed(buttonMask) && !kbhit()) {
            Joyin(0);                    /* Get joystick pots */
            joyPotLimit[potBase].Mid     = joyPotVal[potBase];
            joyPotLimit[potBase + 1].Mid = joyPotVal[potBase + 1];
        }
        while (JoystickButtonPressed(buttonMask) && !kbhit());
        while (kbhit()) getch();         /* Clear the keyboard */
        cputs(" [OK]");
    }

This program not only illustrates how to use the joystick functions from the game library in a program, but it also illustrates a very important first step in using joysticks in your programs via joystick callibration.  This particular program wants to use the joysticks as digital switches to determine the direction of the pixel that it draws on screen.  Joysticks are analog devices and therefore do not lend themselves that well to this type of usage, but you can use them like digital joysticks if you know a few things about the joystick coordinates themselves.

The minimum values for the X and Y coordinates of any joysticks are left and up respectively.  The maximum values of the X and Y coordinates of the same joysticks are right and down respectively.  With that in mind, we need to be able to provide these values to our program so that it may test for these values and act accordingly.  On a PC, the minimum and maximum values for the joystick coordinates are not known so we must 'callibrate' the joystick by asking the player to move the joystick to the far upper left and far lower right positions and record these values.

It is then assumed by the program that the minimum and maximum values for the joystick axes are valid.  Of course, this relies on the player doing what the program asks.  If the program asks the player to move the joystick to the far upper-left position and the player moves the joystick to the center instead, then obviously the program will have incorrect values for the minimum X and Y coordinates.

The 'CallibrateJoystick' function works for both joysticks, just pass 0 to calibrate joystick A and 1 to calibrate joystick B.  On the surface, this may seem like a very useful function that should've been included in the JOYSTICK.C source file and the game library itself.  However, not all programs use the joysticks in the same way.  In fact, none of our previous examples used the joystick in this manner.  As such, I felt that joystick callibration should be included as the programmer saw fit, rather than blindly including it in the game library itself.  Besides, some programmer's have their own ideas as to how a joystick should be calibrated for use in a particular type of game.  So the calibration technique used in this program may not be best suited for those purposes.

One last word of caution I must include here.  Even if your program is going to be primarily controlled by a joystick (or two), you should still provide some sort of keyboard control as well.  Notice that this program made very liberal use of the 'kbhit' and 'getch' functions.  This is to ensure that this program doesn't lock up or hang if (for example) it incorrectly determines that a joystick is present when one isn't.  For that matter, this program could also hang if you try to use the BIOS to access the joystick when the joystick BIOS extensions are not present.  The program could also hang if a joystick was plugged in when the program was started and removed before the program was ended.  The use of keyboard control to abort the program prevents it from hanging under these types of circumstances.

Previous Page | Main Page | Next page

Send your questions, comments, or ideas here.