1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<META name="keywords" content="JS, PLIB, OpenGL, joystick, library, portable, interface, games, Baker, Steve, jsJoystick">
<META name="description" content="The PLIB Joystick Library (JS) is a portable interface that has no inherent restrictions over the number and type of joysticks it supports. It is a wrapper to make the various underlying OS mechanisms look the same to application code.">
<TITLE>A Joystick Library.</TITLE>
</HEAD>
<BODY text="#B5A642" link="#8FFF8F" vlink="#18A515" alink="#20336B"
bgcolor="#005000" background="../marble.png">
<TABLE>
<TR>
<TD>
<H1>A Joystick Library.</H1>
</TD>
</TR>
<TR>
<TD>
by Steve Baker
</TD>
</TR>
</TABLE>
<H2>Introduction</H2>
JS is now just one component of <A HREF="../index.html">PLIB</A>.
<p>
This Joystick Library (JS) is a portable interface that
has no inherent restrictions over the number and type
of joysticks it supports - although in actuality, most
implementations will simply sit on top of an underlying
driver provided by the Operating System.
<p>
You should include the JS header file '/usr/include/plib/js.h'
and link to the JS library '/usr/lib/libjs.a'.
<p>
Before using any JS functions, you should initialise the
library by calling:
<pre>
jsInit () ;
</pre>
JS is essentially just a wrapper to make the various
underlying OS mechanisms look the same to application code.
<pre>
class jsJoystick
{
jsJoystick ( int id = 0 ) ;
~jsJoystick () ;
const char* getName () const ;
int getNumAxes () const ;
int getNumButtons () const ;
int notWorking () const ;
void setError () ;
float getDeadBand ( int axis ) const ;
void setDeadBand ( int axis, float db ) ;
float getSaturation ( int axis ) const ;
void setSaturation ( int axis, float st ) ;
void setMinRange ( float *axes ) ;
void setMaxRange ( float *axes ) ;
void setCenter ( float *axes ) ;
void getMinRange ( float *axes ) const ;
void getMaxRange ( float *axes ) const ;
void getCenter ( float *axes ) const ;
void read ( int *buttons, float *axes ) ;
void rawRead ( int *buttons, float *axes ) ;
}
</pre>
You pass the identifier (0..n) of the joystick you wish to
open into the constructor function. If you leave the number
off, it'll grab the first joystick available.
<p>
If the joystick is unavailable, not working, not installed or
otherwise bad, the package will return zero for all the axes
and all the buttons will appear to be up. If you need to
check for the existance of a particular stick, you can
call <code>notWorking()</code> which returns JS_TRUE if
there is some problem with that stick, JS_FALSE otherwise.
<p>
<code>getName()</code> tells you the device name of the
joystick, if available through API calls in your OS. A
typical value is "CH PRODUCTS CH PRO PEDALS USB ". If no
name is available, this method will return the empty string.
<p>
<code>getNumAxes()</code> tells you how many axes the stick
has. Note that it is NOT safe to assume that all sticks have
the same number of axes - or that they all have a maximum of
three or something. When you pass axis data into and out of
JS, your arrays MUST be sized large enough for that stick.
<p>
When you are testing joystick code, you need to be sure your
program does the right thing when no joystick is installed.
Since it's inconvenient to do keep uninstalling your stick
to do that, we provide <code>setError()</code> which causes
that stick to react exactly as if it were not installed.
<p>
To read the joystick, just call <code>read(&buttons,axes)</code>
where 'buttons' is an integer and 'axes' is an array of
floating point numbers. The buttons variable will be populated
with a number that has one bit per button (0==Not Pressed, 1==Pressed)
and the elements of the axis array will be scaled from an idealized
-1.0 to +1.0 range. (In practice, your stick may not reach those
limits - or it may marginally exceed them).
<p>
For a basic two axis stick, axis zero is Left/Right with left being
negative and right positive. Axis one is North/South with north being
negative and right positive (this is counter-intuitive - but that's
what they do).
<p>
M$-Windows letters its stick axes X,Y,Z,R,U,V. These correspond
to JS axes 0,1,2,3,4,5,6.
<H2>Buttons</H2>
One continually annoying thing about PC joysticks is the lack of
standards for their names. Most sticks have at least two buttons -
mine has six (maybe some have still more). The problem is to know
how to name them. My game pad has buttons labelled A,B,C,D,R,L
corresponding to bits 0,1,2,3,4,5 in the 'buttons' variable.
<p>
Anyway, some joysticks have features that operate by setting
two or more button bits at once. This is quite easy to catch by
masking multiple bits from the 'buttons' word.
<H2>Demo Program</H2>
The demo program that comes with JS is quite useful for finding out
which buttons set which bits and which axes are which - and in
which direction they operate.
<H2>Calibration</H2>
Since most joysticks are analog devices (and fairly cheap, nasty ones
at that), you will not generally get numbers that are accurately
in the range -1..1 with exactly zero being returned when the joystick
is centered on it's springs. This means that you may wish to calibrate
your joystick. The <code>rawRead</code> routine bypasses all the scaling and
offsetting to return RAW data directly from the OS that you can use during
calibration.
<p>
For each axis of the joystick, you should provide a maximum number
(that you wish to correspond to 1.0 returned by <code>read()</code>),
a minimum number (corresponding to -1.0) and a center point number
(corresponding to 0.0) by calling
<code>setMaxRange()/setMinRange()/setCenter()</code> as appropriate.
<p>
However, even with calibration, you should expect the joystick to
drift somewhat over time due to the position of the cable, the
temperature of the potentiometers and probably, the phase of the moon.
This drift is typically not serious at the max and min limits - but
in some applications, the user will expect (for example) for his
character in a game to stop moving completely when he releases the
stick. Since we cannot guarantee to get the same exact number out
of the stick when he does this, you'll need to implement a 'dead band'
in the middle of the stick's travel. This is done with
<code>setDeadBand(axis,amount)</code> where 'axis' is the number of the
axis you wish to have a dead band implemented on - and 'amount' is the
amount of dead band either side of 0.0.
<p>
There are corresponding 'get' routines for each 'set'.
<p>
The <code>read</code> routine is auto-calibrated when you create
the joystick class - so if the joystick is not centered at that
moment, you will get bad data from that point onwards. This is
quite common in games - so don't feel too badly about it. Just
arrange to 'new' all your joysticks early on in the program - when
your user's hands are likely to still be on the keyboard or mouse -
and provide a hot-key to pause the game and recalibrate the stick
on demand.
<hr>
<table>
<tr>
<td>
<a href="http://validator.w3.org/check/referer"><img border="0" src="../valid-html40.png" alt="Valid HTML 4.0!" height="31" width="88"></a>
<td>
<ADDRESS>
<A HREF="http://www.sjbaker.org">
Steve J. Baker.</A>
<<A HREF="mailto:sjbaker1@airmail.net">sjbaker1@airmail.net</A>>
</ADDRESS>
</table>
</BODY>
</HTML>
|