]> git.mxchange.org Git - flightgear.git/blob - src/Joystick/joystick.cxx
Swapped throttle and rudder axes.
[flightgear.git] / src / Joystick / joystick.cxx
1 // joystick.cxx -- joystick support
2 //
3 // Written by Curtis Olson, started October 1998.
4 //
5 // Copyright (C) 1998 - 1999  Curtis L. Olson - curt@flightgear.org
6 //
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.
11 //
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.
16 //
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.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #ifdef HAVE_WINDOWS_H
29 #  include <windows.h>                     
30 #endif
31
32 #include <simgear/debug/logstream.hxx>
33
34 #include <Aircraft/aircraft.hxx>
35 #include <Main/options.hxx>
36
37 #if defined( ENABLE_PLIB_JOYSTICK )
38 #  include <plib/js.h>          // plib include
39 #elif defined( ENABLE_GLUT_JOYSTICK )
40 #  include <GL/glut.h>
41 #  include <simgear/xgl.h>
42 #endif
43
44
45 #include "joystick.hxx"
46
47
48 #if defined( ENABLE_PLIB_JOYSTICK )
49
50 // joystick classes
51 static jsJoystick *js0;
52 static jsJoystick *js1;
53
54 // these will hold the values of the axes
55 static float *js_ax0, *js_ax1;
56
57 static bool sync_throttle=false;
58
59 static float throttle_tmp=0;
60
61 #define SYNC_TOLERANCE 0.02
62
63 #elif defined( ENABLE_GLUT_JOYSTICK )
64
65 // Do we want these user settable ??
66 static float joy_scale = 1./1000;
67
68 // play with following to get your desired sensitivity
69 static int x_dead_zone = 50;
70 static int y_dead_zone = 2*x_dead_zone;
71
72 // Joystick support using glut -- William Riley -- riley@technologist.com
73
74 // Joystick fixed values for calibration and scaling
75 static float joy_x_max = joy_scale;
76 static float joy_y_max = joy_scale;
77
78 static int joy_z_min = 1000, /* joy_z_ctr=0, */ joy_z_max = -1000;
79 static int joy_z_dead_min = 100, joy_z_dead_max = -100;
80
81 #elif defined( MACOS )
82 #  warning port me: no joystick support
83 #else
84 #  error port me: no joystick support
85 #endif
86
87
88
89 #if defined( ENABLE_GLUT_JOYSTICK )
90
91 // Function called by glutJoystickFunc(), adjusts read values and
92 // passes them to the necessary aircraft control functions
93 void joystick(unsigned int buttonMask, int js_x, int js_y, int js_z)
94 {
95     float joy_x, joy_y, joy_z;
96     // adjust the values to fgfs's scale and allow a 'dead zone' to
97     // reduce jitter code adapted from joystick.c by Michele
98     // F. America - nomimarketing@mail.telepac.pt
99
100     if( js_x > -x_dead_zone && js_x < x_dead_zone) {
101         joy_x = 0.0;
102     } else {
103         joy_x = js_x * joy_scale;
104     }
105
106     if( js_y > -y_dead_zone && js_y < y_dead_zone) {
107         joy_y = 0.0;
108     } else {
109         joy_y = js_y * joy_scale;
110     }
111
112     if( js_z >= joy_z_dead_min && js_z <= joy_z_dead_max ) {
113         joy_z = 0.0;
114     }
115     joy_z = (float)js_z / (float)(joy_z_max - joy_z_min);
116     joy_z = (((joy_z*2.0)+1.0)/2);
117
118     // Pass the values to the control routines
119     controls.set_elevator( -joy_y );
120     controls.set_aileron( joy_x );
121     controls.set_throttle( FGControls::ALL_ENGINES, joy_z );
122 }
123
124 #endif // ENABLE_GLUT_JOYSTICK
125
126
127 // Initialize the joystick(s)
128 int fgJoystickInit( void ) {
129
130     FG_LOG( FG_INPUT, FG_INFO, "Initializing joystick" );
131
132 #if defined( ENABLE_PLIB_JOYSTICK )
133
134     js0 = new jsJoystick ( 0 );
135     js1 = new jsJoystick ( 1 );
136
137     if ( js0->notWorking () ) {
138         // not working
139     } else {
140         // allocate storage for axes values
141         js_ax0 = new float [ js0->getNumAxes() ];
142
143         // configure
144         js0->setDeadBand( 0, 0.1 );
145         js0->setDeadBand( 1, 0.1 );
146
147         FG_LOG ( FG_INPUT, FG_INFO, 
148                  "  Joystick 0 detected with " << js0->getNumAxes() 
149                  << " axes" );
150     }
151
152     if ( js1->notWorking () ) {
153         // not working
154     } else {
155         // allocate storage for axes values
156         js_ax1 = new float [ js1->getNumAxes() ];
157
158         // configure
159         js1->setDeadBand( 0, 0.1 );
160         js1->setDeadBand( 1, 0.1 );
161
162         FG_LOG ( FG_INPUT, FG_INFO,
163                  "  Joystick 1 detected with " << js1->getNumAxes() 
164                  << " axes" );
165     }
166
167     if ( js0->notWorking() && js1->notWorking() ) {
168         FG_LOG ( FG_INPUT, FG_INFO, "  No joysticks detected" );
169         return 0;
170     }
171
172     // I hate doing this sort of thing, but it's overridable from the
173     // command line/config file.  If the user hasn't specified an
174     // autocoordination preference, and if they have a single 2 axis
175     // joystick, then automatical enable auto_coordination.
176
177     if ( (current_options.get_auto_coordination() == 
178           fgOPTIONS::FG_AUTO_COORD_NOT_SPECIFIED) &&
179          (!js0->notWorking() && js1->notWorking() && (js0->getNumAxes() < 3)
180           )
181          )
182     {
183         current_options.set_auto_coordination(fgOPTIONS::FG_AUTO_COORD_ENABLED);
184     }
185     
186     if(current_options.get_trim_mode() > 0) {
187         FG_LOG(FG_INPUT, FG_INFO,
188                "  Waiting for user to synchronize throttle lever...");
189         sync_throttle=true;
190     }
191
192
193 #elif defined( ENABLE_GLUT_JOYSTICK )
194
195     glutJoystickFunc(joystick, 100);
196
197 #elif defined( MACOS )
198 #  warning port me: no joystick support
199 #else
200 #  error port me: no joystick support
201 #endif
202
203     return 1;
204 }
205
206
207 #if defined( ENABLE_PLIB_JOYSTICK )
208
209 // update the control parameters based on joystick intput
210 int fgJoystickRead( void ) {
211     int b;
212
213     if ( ! js0->notWorking() ) {
214         js0->read( &b, js_ax0 ) ;
215         controls.set_aileron( js_ax0[0] );
216         controls.set_elevator( -js_ax0[1] );
217
218         //  Added by William Riley -- riley@technologist.com
219         if ( js0->getNumAxes() >= 3 ) {
220             throttle_tmp=(-js_ax0[3] + 1) / 2;
221         
222             if(sync_throttle == true) {
223                 if (fabs(controls.get_throttle(0)-throttle_tmp)
224                     < SYNC_TOLERANCE)
225                 {
226                     FG_LOG(FG_INPUT, FG_INFO, "  Throttle lever synchronized.");
227                     controls.set_throttle(FGControls::ALL_ENGINES,throttle_tmp);
228                     sync_throttle=false;
229                 }    
230             } else {
231                 controls.set_throttle( FGControls::ALL_ENGINES,throttle_tmp );
232             }
233         } 
234         if ( js0->getNumAxes() > 3 ) {
235             if ( current_options.get_auto_coordination() !=
236                   fgOPTIONS::FG_AUTO_COORD_ENABLED ) 
237             {
238                 controls.set_rudder( js_ax0[2] );
239             }
240         }
241         //  End of William's code
242
243     }
244
245     if ( ! js1->notWorking() ) {
246         js1->read( &b, js_ax1 ) ;
247         if ( current_options.get_auto_coordination() !=
248              fgOPTIONS::FG_AUTO_COORD_ENABLED ) 
249         {
250             controls.set_rudder( js_ax1[0] );
251         }
252         controls.set_throttle( FGControls::ALL_ENGINES, -js_ax1[1] * 1.05 );
253     }
254
255     return 1;
256 }
257
258 #endif // ENABLE_PLIB_JOYSTICK
259