Joystick routines



Getting input from the PC joystick is not a pleasant task. Not because it is particularly complicated, but because it depends on a high-precision timing loop, and the exact results of this can vary depending on the type of joystick, the speed of your computer, the temperature of the room, and the phases of the moon. If you want to get meaningful input you have to calibrate the joystick before using it, which is a royal pain in the arse.

extern int joy_type;
Global variable telling the joystick code what sort of joystick is plugged in. Possible values are:

JOY_TYPE_STANDARD
A normal two button stick. This is the default, and should work with any joystick.

JOY_TYPE_FSPRO
If you have a CH Flightstick Pro, and want to use the cool features it provides (four buttons, an analogue throttle, and a 4-direction coolie hat), you should set this value before calling any other joystick functions.

JOY_TYPE_4BUTTON
Set this value to enable the extra buttons on a 4-button joystick (eg. the Gravis Gamepad).

JOY_TYPE_6BUTTON
Set this value to enable the extra buttons on a 6-button joystick.

JOY_TYPE_2PADS
Use dual joystick mode.

JOY_TYPE_WINGEX
This is used for Logitech Wingman Extreme joysticks, and should 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).

int initialise_joystick();
Initialises the joystick, and calibrates the centre position value. You must call this before using any other joystick functions, and you should make sure the user has centered the joystick when you do. Returns non-zero if there is no joystick present (in which case you can still call the other joystick routines, but they will return zero positions). There is no need to use this function if the joystick has already been calibrated with the setup utility: if that is the case you can just call load_joystick_data(NULL) to restore the previous settings.

void 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 joy_left, joy_right, joy_up, joy_down;
These variables simulate a digital joystick. They are updated by poll_joystick(), and will contain non-zero if the joystick is moved in the relevant direction. You don't need to fully calibrate the joystick in order to use these: just initialise_joystick() is enough (this is how the demo game accesses the joystick).

extern int joy2_left, joy2_right, joy2_up, joy2_down;
Digital position variables for the second joystick (only valid if joy_type is set to JOY_TYPE_2PADS).

extern int joy_b1, joy_b2;
Joystick button states. Call poll_joystick() to update them. Note that these values tend to bounce between on and off a few times when the button is pressed or released, so in some situations you may need to add a small delay after the buttons change state (see test.c for an example).

extern int joy2_b1, joy2_b2;
Button state for the second joystick (only valid if joy_type is set to JOY_TYPE_2PADS).

extern int joy_b3, joy_b4;
Like the two standard buttons, these are updated by poll_joystick(). They will only contain valid data if joy_type is set to JOY_TYPE_FSPRO, JOY_TYPE_4BUTTON, JOY_TYPE_6BUTTON, or JOY_TYPE_WINGEX. You can also access the Flightstick Pro buttons with the aliases (from allegro.h):

      #define joy_FSPRO_trigger     joy_b1
      #define joy_FSPRO_butleft     joy_b2
      #define joy_FSPRO_butright    joy_b3
      #define joy_FSPRO_butmiddle   joy_b4

The Wingman Extreme buttons are also aliased in allegro.h:

      #define joy_WINGEX_trigger    joy_b1
      #define joy_WINGEX_buttop     joy_b2
      #define joy_WINGEX_butthumb   joy_b3
      #define joy_WINGEX_butmiddle  joy_b4

extern int joy_b5, joy_b6;
Like the standard buttons, these are updated by poll_joystick(). They will only contain valid data if joy_type is set to JOY_TYPE_6BUTTON.

extern int joy_hat;
Updated by poll_joystick(). This will only contain valid data if joy_type equals JOY_TYPE_FSPRO or JOY_TYPE_WINGEX (and in the latter case, only if the hat has been calibrated). It can have one of the following values (these are mutually exclusive):

JOY_HAT_CENTRE
JOY_HAT_UP
JOY_HAT_DOWN
JOY_HAT_LEFT
JOY_HAT_RIGHT

int calibrate_joystick_tl();
int calibrate_joystick_br();
If you want to get analogue stick position information, rather than just using the joy_left, joy_right, joy_up, and joy_down variables, you need to individually calibrate the top left, bottom right, and centre joystick positions. Calling initialise_joystick() will calibrate the centre, and must be done first. After this you can tell the user to move the joystick to the top left and bottom right extremes, and call the appropriate calibration routine for each corner. See test.c for an example. After doing this, you can use the position variables:

extern int joy_x, joy_y;
Analogue axis positions, ranging from -128 to 128. You must fully calibrate the joystick before using these variables: see above. Call poll_joystick() to update them.

extern int joy2_x, joy2_y;
Analogue axis position for the second joystick (only valid if joy_type is set to JOY_TYPE_2PADS).

int calibrate_joystick_throttle_min();
int calibrate_joystick_throttle_max();
There is seemingly no end to the things that need calibrating :-) To use the Flightstick Pro's analogue throttle, call these functions with the throttle in the minimum and maximum positions respectively.

extern int joy_throttle;
Throttle position, ranging from 0 to 255 (whether 0 is fully forward or fully backward depends on how the user calibrated the throttle: some people prefer to use the throttle backwards to the way most people use it). This is updated by poll_joystick(), and only contains valid data when joy_type = JOY_TYPE_FSPRO and you have calibrated the throttle.

int calibrate_joystick_hat(int direction);
The hardware implementation used by the Wingman Extreme requires that the coolie hat be calibrated (this only applies to Thrustmaster compatible joysticks like the Wingman Extreme, and not to CH compatible joysticks: they are wired differently). In order to prevent random behaviour, if this is not calibrated the joy_hat variable will always contain JOY_HAT_CENTRE. The argument passed to calibrate_joystick_hat() is one of:

JOY_HAT_CENTRE
JOY_HAT_UP
JOY_HAT_DOWN
JOY_HAT_LEFT
JOY_HAT_RIGHT

Note that to achieve better calibration of the coolie hat the joystick should be centered when this function is called.

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 initialise_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 and calibrate it.




Back to Contents