Joystick routines



int install_joystick(int type);
Initialises the joystick, and calibrates the centre position value. You must call this before using any other joystick functions, and you should make sure that the joystick is in the middle position at the time. Returns zero on success. The type parameter should be one of the values:

JOY_TYPE_AUTODETECT
Attempts to autodetect your joystick hardware. It isn't possible to reliably distinguish between all the possible input setups, so this routine can only ever choose the standard joystick, Sidewider, or GamePad Pro drivers, but it will use information from the configuration file if one is available (this can be created using the setup utility or by calling the save_joystick_data() function), so you can always use JOY_TYPE_AUTODETECT in your code and then select the exact hardware type from the setup program.

JOY_TYPE_NONE
Dummy driver for machines without any joystick.

JOY_TYPE_STANDARD
A normal two button stick.

JOY_TYPE_2PADS
Dual joystick mode (two sticks, each with two buttons).

JOY_TYPE_4BUTTON
Enable the extra buttons on a 4-button joystick.

JOY_TYPE_6BUTTON
Enable the extra buttons on a 6-button joystick.

JOY_TYPE_8BUTTON
Enable the extra buttons on an 8-button joystick.

JOY_TYPE_FSPRO
CH Flightstick Pro or compatible stick, which provides four buttons, an analogue throttle control, and a 4-direction coolie hat.

JOY_TYPE_WINGEX
A Logitech Wingman Extreme, which should also work with any Thrustmaster Mk.I compatible joystick. It provides support for four buttons and a coolie hat. This also works with the Wingman Warrior, if you plug in the 15 pin plug (remember to unplug the 9-pin plug!) and set the tiny switch in front to the "H" position (you will not be able to use the throttle or the spinner though).

JOY_TYPE_SIDEWINDER
The Microsoft Sidewinder digital pad (supports up to four controllers, each with ten buttons and a digital direction control).

JOY_TYPE_GAMEPAD_PRO
The Gravis GamePad Pro (supports up to two controllers, each with ten buttons and a digital direction control).

JOY_TYPE_SNESPAD_LPT1
JOY_TYPE_SNESPAD_LPT2
JOY_TYPE_SNESPAD_LPT3
SNES joypads connected to LPT1, LPT2, and LPT3 respectively.

JOY_TYPE_WINGWARRIOR
A Wingman Warrior joystick.

As soon as you have installed the joystick module, you will be able to read the button state and digital (on/off toggle) direction information, which may be enough for some games. If you want to get full analogue input, though, you need to use the calibrate_joystick() functions to measure the exact range of the inputs: see below.

void remove_joystick();
Removes the joystick handler. You don't normally need to bother calling this, because allegro_exit() will do it for you.

int poll_joystick();
Unlike the mouse and keyboard, the joystick is not interrupt driven, so you need to call this function every now and again to update the global position values.

extern int num_joysticks;
Global variable containing the number of active joystick devices. The current drivers support a maximum of four controllers.

extern JOYSTICK_INFO joy[n];
Global array of joystick state information, which is updated by the poll_joystick() function. Only the first num_joysticks elements will contain meaningful information. The JOYSTICK_INFO structure is defined as:

   typedef struct JOYSTICK_INFO
   {
      int flags;                       - status flags for this joystick
      int num_sticks;                  - how many stick inputs?
      int num_buttons;                 - how many buttons?
      JOYSTICK_STICK_INFO stick[n];    - stick state information
      JOYSTICK_BUTTON_INFO button[n];  - button state information
   } JOYSTICK_INFO;

The button status is stored in the structure:

   typedef struct JOYSTICK_BUTTON_INFO
   {
      int b;                           - boolean on/off flag
      char *name;                      - description of this button
   } JOYSTICK_BUTTON_INFO;

You may wish to display the button names as part of an input configuration screen to let the user choose what game function will be performed by each button, but in simpler situations you can safely assume that the first two elements in the button array will always be the main trigger controls.

Each joystick will provide one or more stick inputs, of varying types. These can be digital controls which snap to specific positions (eg. a gamepad controller, the coolie hat on a Flightstick Pro or Wingman Extreme, or a normal joystick which hasn't yet been calibrated), or they can be full analogue inputs with a smooth range of motion. Sticks may also have different numbers of axis, for example a normal directional control has two, but the Flightstick Pro throttle is only a single axis, and it is possible that the system could be extended in the future to support full 3d controllers. A stick input is described by the structure:

   typedef struct JOYSTICK_STICK_INFO
   {
      int flags;                       - status flags for this input
      int num_axis;                    - how many axis do we have?
      JOYSTICK_AXIS_INFO axis[n];      - axis state information
      char *name;                      - description of this input
   } JOYSTICK_STICK_INFO;

A single joystick may provide several different stick inputs, but you can safely assume that the first element in the stick array will always be the main directional controller.

Information about each of the stick axis is stored in the substructure:

   typedef struct JOYSTICK_AXIS_INFO
   {
      int pos;                         - analogue axis position
      int d1, d2;                      - digital axis position
      char *name;                      - description of this axis
   } JOYSTICK_AXIS_INFO;

This provides both analogue input in the pos field (ranging from -128 to 128 or from 0 to 255, depending on the type of the control), and digital values in the d1 and d2 fields. For example, when describing the X-axis position, the pos field will hold the horizontal position of the joystick, d1 will be set if it is moved left, and d2 will be set if it is moved right. Allegro will fill in all these values regardless of whether it is using a digital or analogue joystick, emulating the pos field for digital inputs by snapping it to the min, middle, and maximum positions, and emulating the d1 and d2 values for an analogue stick by comparing the current position with the centre point.

The joystick flags field may contain any combination of the bit flags:

JOYFLAG_DIGITAL
This control is currently providing digital input.

JOYFLAG_ANALOGUE
This control is currently providing analogue input.

JOYFLAG_CALIB_DIGITAL
This control will be capable of providing digital input once it has been calibrated, but is not doing this at the moment.

JOYFLAG_CALIB_ANALOGUE
This control will be capable of providing analogue input once it has been calibrated, but is not doing this at the moment.

JOYFLAG_CALIBRATE
Indicates that this control needs to be calibrated. Many devices require multiple calibration steps, so you should call the calibrate_joystick() function from a loop until this flag is cleared.

JOYFLAG_SIGNED
Indicates that the analogue axis position is in signed format, ranging from -128 to 128. This is the case for all 2d directional controls.

JOYFLAG_UNSIGNED
Indicates that the analogue axis position is in unsigned format, ranging from 0 to 255. This is the case for all 1d throttle controls.

Note for people who spell funny: in case you don't like having to type "analogue", there are some #define aliases in allegro.h that will allow to to write "analog" instead.

char *calibrate_joystick_name(int n);
Returns a text description for the next type of calibration that will be done on the specified joystick, or NULL if no more calibration is required.

int calibrate_joystick(int n);
Most joysticks need to be calibrated before they can provide full analogue input. This function performs the next operation in the calibration series for the specified stick, assuming that the joystick has been positioned in the manner described by a previous call to calibrate_joystick_name(), returning zero on success. For example, a simple routine to fully calibrate all the joysticks might look like:

      int i;

for (i=0; i<;num_joysticks; i++) { while (joy[i].flags & JOYFLAG_CALIBRATE) { char *msg = calibrate_joystick_name(i); printf("%s, and press a key\n", msg); readkey(); if (calibrate_joystick(i) != 0) { printf("oops!\n"); exit(1); } } }

int save_joystick_data(char *filename);
After all the headache of calibrating the joystick, you may not want to make your poor users repeat the process every time they run your program. Call this function to save the joystick calibration data into the specified configuration file, from which it can later be read by load_joystick_data(). Pass a NULL filename to write the data to the currently selected configuration file. Returns zero on success.

int load_joystick_data(char *filename);
Restores calibration data previously stored by save_joystick_data() or the setup utility. This sets up all aspects of the joystick code: you don't even need to call install_joystick() if you are using this function. Pass a NULL filename to read the data from the currently selected configuration file. Returns zero on success: if it fails the joystick state is undefined and you must reinitialise it from scratch.




Back to Contents