]> git.mxchange.org Git - flightgear.git/blob - Joystick/js.hxx
Converted to new logstream debugging facility. This allows release
[flightgear.git] / Joystick / js.hxx
1 #ifndef __INCLUDED_JS_H__
2 #define __INCLUDED_JS_H__ 1
3
4 #ifdef __linux__
5 #  include <stdio.h>
6 #  include <unistd.h>
7 #  include <fcntl.h>
8 #  include <linux/joystick.h>
9 #endif
10
11 #define JS_TRUE  1
12 #define JS_FALSE 0
13
14 /*
15   This is all set up for the older Linux and BSD drivers
16   which restrict you to two axes.
17 */
18
19 #define _JS_MAX_AXES 2
20
21 class jsJoystick
22 {
23   JS_DATA_TYPE js    ;
24   char         fname [ 128 ] ;
25   int          error ;
26   int          fd    ;
27
28   int          num_axes ;
29
30   float dead_band [ _JS_MAX_AXES ] ;
31   float center    [ _JS_MAX_AXES ] ;
32   float max       [ _JS_MAX_AXES ] ;
33   float min       [ _JS_MAX_AXES ] ;
34
35   void open ()
36   {
37     num_axes = _JS_MAX_AXES ;
38
39     fd = ::open ( fname, O_RDONLY ) ;
40
41     error = ( fd < 0 ) ;
42
43     if ( error )
44       return ;
45
46     int counter = 0 ;
47
48     /*
49       The Linux driver seems to return 512 for all axes
50       when no stick is present - but there is a chance
51       that could happen by accident - so it's gotta happen
52       on both axes for at least 100 attempts.
53     */
54
55     do
56     { 
57       rawRead ( NULL, center ) ;
58       counter++ ;
59     } while ( counter < 100 && center[0] == 512.0f && center[1] == 512.0f ) ;
60    
61     if ( counter >= 100 )
62       error = JS_TRUE ;
63
64     for ( int i = 0 ; i < _JS_MAX_AXES ; i++ )
65     {
66       max [ i ] = center [ i ] * 2.0f ;
67       min [ i ] = 0.0f ;
68       dead_band [ i ] = 0.0f ;
69     }
70   }
71
72   void close ()
73   {
74     if ( ! error )
75       ::close ( fd ) ;
76   }
77
78   float fudge_axis ( float value, int axis )
79   {
80     if ( value < center[axis] )
81     {
82       float xx = ( value - center[ axis ] ) /
83                  ( center [ axis ] - min [ axis ] ) ;
84
85       xx = ( xx > -dead_band [ axis ] ) ? 0.0f :
86                   ( ( xx + dead_band [ axis ] ) / ( 1.0f - dead_band [ axis ] ) ) ;
87
88       return ( xx < -1.0f ) ? -1.0f : xx ;
89     }
90     else
91     {
92       float xx = ( value - center [ axis ] ) /
93                  ( max [ axis ] - center [ axis ] ) ;
94
95       xx = ( xx < dead_band [ axis ] ) ? 0.0f :
96                   ( ( xx - dead_band [ axis ] ) / ( 1.0f - dead_band [ axis ] ) ) ;
97
98       return ( xx > 1.0f ) ? 1.0f : xx ;
99     }
100   }
101
102 public:
103
104   jsJoystick ( int id = 0 )
105   {
106     sprintf ( fname, "/dev/js%d", id ) ;
107     open () ;
108   }
109
110   ~jsJoystick ()
111   {
112     close () ;
113   }
114
115   int  getNumAxes () { return num_axes ; }
116   int  notWorking () { return error ;    }
117   void setError   () { error = JS_TRUE ; }
118
119   float getDeadBand ( int axis )           { return dead_band [ axis ] ; }
120   void  setDeadBand ( int axis, float db ) { dead_band [ axis ] = db   ; }
121
122   void setMinRange ( float *axes ) { memcpy ( min   , axes, num_axes * sizeof(float) ) ; }
123   void setMaxRange ( float *axes ) { memcpy ( max   , axes, num_axes * sizeof(float) ) ; }
124   void setCenter   ( float *axes ) { memcpy ( center, axes, num_axes * sizeof(float) ) ; }
125
126   void getMinRange ( float *axes ) { memcpy ( axes, min   , num_axes * sizeof(float) ) ; }
127   void getMaxRange ( float *axes ) { memcpy ( axes, max   , num_axes * sizeof(float) ) ; }
128   void getCenter   ( float *axes ) { memcpy ( axes, center, num_axes * sizeof(float) ) ; }
129
130   void read ( int *buttons, float *axes )
131   {
132     if ( error )
133     {
134       if ( buttons )
135         *buttons = 0 ;
136
137       if ( axes )
138         for ( int i = 0 ; i < _JS_MAX_AXES ; i++ )
139           axes[i] = 0.0f ;
140     }
141
142     float raw_axes [ _JS_MAX_AXES ] ;
143
144     rawRead ( buttons, raw_axes ) ;
145
146     if ( axes )
147       for ( int i = 0 ; i < _JS_MAX_AXES ; i++ )
148         axes[i] = ( i < num_axes ) ? fudge_axis ( raw_axes[i], i ) : 0.0f ; 
149   }
150
151   void rawRead ( int *buttons, float *axes )
152   {
153     if ( error )
154     {
155       if ( buttons ) *buttons =   0  ;
156       if ( axes )
157         for ( int i = 0 ; i < _JS_MAX_AXES ; i++ )
158           axes[i] = 1500.0f ;
159
160       return ;
161     }
162
163     int status = ::read ( fd, &js, JS_RETURN ) ;
164
165     if ( status != JS_RETURN )
166     {
167       perror ( fname ) ;
168       setError () ;
169       return ;
170     }
171
172     if ( buttons )
173       *buttons = js.buttons ;
174
175     if ( axes )
176     {
177       axes[0] = (float) js.x ;
178       axes[1] = (float) js.y ;
179     }
180   }
181 } ;
182
183 #endif
184