1 // joystick.cxx -- joystick support
3 // Written by Curtis Olson, started October 1998.
5 // Copyright (C) 1998 - 1999 Curtis L. Olson - curt@flightgear.org
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include <simgear/logstream.hxx>
34 #include <Aircraft/aircraft.hxx>
35 #include <Main/options.hxx>
37 #if defined( ENABLE_PLIB_JOYSTICK )
38 # include <plib/js.h> // plib include
39 #elif defined( ENABLE_GLUT_JOYSTICK )
41 # include <simgear/xgl.h>
45 #include "joystick.hxx"
48 #if defined( ENABLE_PLIB_JOYSTICK )
51 static jsJoystick *js0;
52 static jsJoystick *js1;
54 // these will hold the values of the axes
55 static float *js_ax0, *js_ax1;
57 #elif defined( ENABLE_GLUT_JOYSTICK )
59 // Do we want these user settable ??
60 static float joy_scale = 1./1000;
62 // play with following to get your desired sensitivity
63 static int x_dead_zone = 50;
64 static int y_dead_zone = 2*x_dead_zone;
66 // Joystick support using glut -- William Riley -- riley@technologist.com
68 // Joystick fixed values for calibration and scaling
69 static float joy_x_max = joy_scale;
70 static float joy_y_max = joy_scale;
72 static int joy_z_min = 1000, /* joy_z_ctr=0, */ joy_z_max = -1000;
73 static int joy_z_dead_min = 100, joy_z_dead_max = -100;
75 #elif defined( MACOS )
76 # warning port me: no joystick support
78 # error port me: no joystick support
83 #if defined( ENABLE_GLUT_JOYSTICK )
85 // Function called by glutJoystickFunc(), adjusts read values and
86 // passes them to the necessary aircraft control functions
87 void joystick(unsigned int buttonMask, int js_x, int js_y, int js_z)
89 float joy_x, joy_y, joy_z;
90 // adjust the values to fgfs's scale and allow a 'dead zone' to
91 // reduce jitter code adapted from joystick.c by Michele
92 // F. America - nomimarketing@mail.telepac.pt
94 if( js_x > -x_dead_zone && js_x < x_dead_zone) {
97 joy_x = js_x * joy_scale;
100 if( js_y > -y_dead_zone && js_y < y_dead_zone) {
103 joy_y = js_y * joy_scale;
106 if( js_z >= joy_z_dead_min && js_z <= joy_z_dead_max ) {
109 joy_z = (float)js_z / (float)(joy_z_max - joy_z_min);
110 joy_z = (((joy_z*2.0)+1.0)/2);
112 // Pass the values to the control routines
113 controls.set_elevator( -joy_y );
114 controls.set_aileron( joy_x );
115 controls.set_throttle( FGControls::ALL_ENGINES, joy_z );
118 #endif // ENABLE_GLUT_JOYSTICK
121 // Initialize the joystick(s)
122 int fgJoystickInit( void ) {
124 FG_LOG( FG_INPUT, FG_INFO, "Initializing joystick" );
126 #if defined( ENABLE_PLIB_JOYSTICK )
128 js0 = new jsJoystick ( 0 );
129 js1 = new jsJoystick ( 1 );
131 if ( js0->notWorking () ) {
134 // allocate storage for axes values
135 js_ax0 = new float [ js0->getNumAxes() ];
138 js0->setDeadBand( 0, 0.1 );
139 js0->setDeadBand( 1, 0.1 );
141 FG_LOG ( FG_INPUT, FG_INFO,
142 " Joystick 0 detected with " << js0->getNumAxes()
146 if ( js1->notWorking () ) {
149 // allocate storage for axes values
150 js_ax1 = new float [ js1->getNumAxes() ];
153 js1->setDeadBand( 0, 0.1 );
154 js1->setDeadBand( 1, 0.1 );
156 FG_LOG ( FG_INPUT, FG_INFO,
157 " Joystick 1 detected with " << js1->getNumAxes()
161 if ( js0->notWorking() && js1->notWorking() ) {
162 FG_LOG ( FG_INPUT, FG_INFO, " No joysticks detected" );
166 // I hate doing this sort of thing, but it's overridable from the
167 // command line/config file. If the user hasn't specified an
168 // autocoordination preference, and if they have a single 2 axis
169 // joystick, then automatical enable auto_coordination.
171 if ( (current_options.get_auto_coordination() ==
172 fgOPTIONS::FG_AUTO_COORD_NOT_SPECIFIED) &&
173 (!js0->notWorking() && js1->notWorking() && (js0->getNumAxes() < 3)
177 current_options.set_auto_coordination(fgOPTIONS::FG_AUTO_COORD_ENABLED);
181 #elif defined( ENABLE_GLUT_JOYSTICK )
183 glutJoystickFunc(joystick, 100);
185 #elif defined( MACOS )
186 # warning port me: no joystick support
188 # error port me: no joystick support
195 #if defined( ENABLE_PLIB_JOYSTICK )
197 // update the control parameters based on joystick intput
198 int fgJoystickRead( void ) {
201 if ( ! js0->notWorking() ) {
202 js0->read( &b, js_ax0 ) ;
203 controls.set_aileron( js_ax0[0] );
204 controls.set_elevator( -js_ax0[1] );
206 // Added by William Riley -- riley@technologist.com
207 if ( js0->getNumAxes() >= 3 ) {
208 controls.set_throttle( FGControls::ALL_ENGINES,
209 ((-js_ax0[2] + 1) / 2) );
211 if ( js0->getNumAxes() > 3 ) {
212 if ( current_options.get_auto_coordination() !=
213 fgOPTIONS::FG_AUTO_COORD_ENABLED )
215 controls.set_rudder( js_ax0[3] );
218 // End of William's code
222 if ( ! js1->notWorking() ) {
223 js1->read( &b, js_ax1 ) ;
224 if ( current_options.get_auto_coordination() !=
225 fgOPTIONS::FG_AUTO_COORD_ENABLED )
227 controls.set_rudder( js_ax1[0] );
229 controls.set_throttle( FGControls::ALL_ENGINES, -js_ax1[1] * 1.05 );
235 #endif // ENABLE_PLIB_JOYSTICK