]> icculus.org git repositories - btb/d2x.git/blob - input/linux_joystick.c
More header unification...
[btb/d2x.git] / input / linux_joystick.c
1 #include <conf.h>
2
3 #ifdef __ENV_LINUX__
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <linux/joystick.h>
7 #include <sys/ioctl.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10
11 #include "timer.h"
12 #include "pstypes.h"
13 #include "mono.h"
14 #include "joy.h"
15
16 #include "linux_joystick.h"
17
18 char joy_installed = 0;
19 char joy_present = 0;
20
21 joystick_device j_joystick[4];
22 joystick_axis j_axis[MAX_AXES];
23 joystick_button j_button[MAX_BUTTONS];
24
25 int j_num_axes = 0, j_num_buttons = 0;
26 int timer_rate;
27
28 int j_axes_in_sticks[4];        /* number of axes in the first [x] sticks */
29 int j_buttons_in_sticks[4];     /* number of buttons in the first [x] sticks */
30
31 int joy_deadzone = 0;
32
33 int j_Get_joydev_axis_number (int all_axis_number) {
34         int i, joy_axis_number = all_axis_number;
35
36         for (i = 0; i < j_axis[all_axis_number].joydev; i++) {
37                 joy_axis_number -= j_joystick[i].num_axes;
38         }               
39
40         return joy_axis_number;
41 }
42
43
44 int j_Get_joydev_button_number (int all_button_number) {
45         int i, joy_button_number = all_button_number;
46
47         for (i = 0; i < j_button[all_button_number].joydev; i++) {
48                 joy_button_number -= j_joystick[i].num_buttons;
49         }               
50
51         return joy_button_number;
52 }
53
54
55 int j_Update_state () {
56         int num_processed = 0, i;
57         struct js_event current_event;
58         struct JS_DATA_TYPE joy_data;
59
60         for (i = 0; i < j_num_buttons; i++) {
61                 //changed 6/24/1999 to finally squish the timedown bug - Owen Evans 
62                 if (j_button[i].state != j_button[i].last_state) {
63                         if (j_button[i].state) {
64                                 j_button[i].downcount++;
65                                 j_button[i].timedown = timer_get_fixed_seconds();
66                         }
67                 }
68                 //end changed - OE
69                 j_button[i].last_state = j_button[i].state;
70         }
71
72         for (i = 0; i < 4; i++) {
73                 if (j_joystick[i].buffer >= 0) {
74                         if (j_joystick[i].version) {
75                                 while (read (j_joystick[i].buffer, &current_event, sizeof (struct js_event)) > 0) {
76                                         num_processed++;
77                                         switch (current_event.type & ~JS_EVENT_INIT) {
78                                                 case JS_EVENT_AXIS:
79                                                         j_axis[j_axes_in_sticks[i] + current_event.number].value = current_event.value;
80                                                         break;
81                                                 case JS_EVENT_BUTTON:
82                                                         j_button[j_buttons_in_sticks[i] + current_event.number].state = current_event.value;
83                                                         break;
84                                         }
85                                 }
86                         } else {
87                                 read (j_joystick[i].buffer, &joy_data, JS_RETURN);
88                                 j_axis[j_axes_in_sticks[i] + 0].value = joy_data.x;
89                                 j_axis[j_axes_in_sticks[i] + 1].value = joy_data.y;
90                                 j_button[j_buttons_in_sticks[i] + 0].state = (joy_data.buttons & 0x01);
91                                 j_button[j_buttons_in_sticks[i] + 1].state = (joy_data.buttons & 0x02) >> 1;
92                         }
93                 }
94         }
95
96         return num_processed;
97 }
98
99
100 void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max) {
101         int i;
102
103         for (i = 0; i < 4; i++) {
104                 j_axis[i].center_val = axis_center[i];
105                 j_axis[i].min_val = axis_min[i];
106                 j_axis[i].max_val = axis_max[i];
107         }
108 }
109
110
111 void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max) {
112         int i;
113
114         //edited 05/18/99 Matt Mueller - we should return all axes instead of j_num_axes, since they are all given to us in joy_set_cal_vals ( and because checker complains :)
115         for (i = 0; i < 4; i++) {
116         //end edit -MM
117                 axis_center[i] = j_axis[i].center_val;
118                 axis_min[i] = j_axis[i].min_val;
119                 axis_max[i] = j_axis[i].max_val;
120         }
121 }
122
123
124 void joy_set_min (int axis_number, int value) {
125         j_axis[axis_number].min_val = value;
126 }
127
128
129 void joy_set_center (int axis_number, int value) {
130         j_axis[axis_number].center_val = value;
131 }
132
133
134 void joy_set_max (int axis_number, int value) {
135         j_axis[axis_number].max_val = value;
136 }
137
138
139 ubyte joy_get_present_mask () {
140         return 1;
141 }
142
143
144 void joy_set_timer_rate (int max_value) {
145         timer_rate = max_value;
146 }
147
148
149 int joy_get_timer_rate () {
150         return timer_rate;
151 }
152
153
154 void joy_flush () {
155         int i;
156
157         if (!joy_installed) return;
158
159         for (i = 0; i < j_num_buttons; i++) {
160                 j_button[i].timedown = 0;       
161                 j_button[i].downcount = 0;      
162         }
163         
164 }
165
166
167 ubyte joystick_read_raw_axis (ubyte mask, int *axes) {
168         int i;
169         
170         j_Update_state();
171
172         for (i = 0; i < j_num_axes; i++) {
173                 axes[i] = j_axis[i].value;
174         }
175
176         return 0;
177 }
178
179
180 /* joy_init () is pretty huge, a bit klunky, and by no means pretty.  But who cares?  It does the job and it's only run once. */
181
182
183 int joy_init () {
184         int i, j;
185
186         if (joy_installed) return 0;
187         joy_flush ();
188
189         if (!joy_installed)     {
190
191                 printf ("Initializing joystick... ");
192
193                 j_joystick[0].buffer = open ("/dev/js0", O_NONBLOCK);
194                 j_joystick[1].buffer = open ("/dev/js1", O_NONBLOCK);
195                 j_joystick[2].buffer = open ("/dev/js2", O_NONBLOCK);
196                 j_joystick[3].buffer = open ("/dev/js3", O_NONBLOCK);
197                 
198                 if (j_joystick[0].buffer >= 0 || j_joystick[1].buffer >= 0 || j_joystick[2].buffer >= 0 || j_joystick[3].buffer >= 0) {
199                         printf ("found: ");
200
201                         for (i = 0; i < 4; i++) {
202                                 if (j_joystick[i].buffer >= 0) {
203                                         ioctl (j_joystick[i].buffer, JSIOCGAXES, &j_joystick[i].num_axes);
204                                         ioctl (j_joystick[i].buffer, JSIOCGBUTTONS, &j_joystick[i].num_buttons);
205                                         ioctl (j_joystick[i].buffer, JSIOCGVERSION, &j_joystick[i].version);
206                                         if (!j_joystick[i].version) {
207                                                 j_joystick[i].num_axes = 2;
208                                                 j_joystick[i].num_buttons = 2;
209                                                 printf ("js%d (v0.x)  " , i);
210                                         } else {
211                                                 printf ("js%d (v%d.%d.%d)  ",
212                                                         i, 
213                                                         (j_joystick[i].version & 0xff0000) >> 16,
214                                                         (j_joystick[i].version & 0xff00) >> 8,
215                                                         j_joystick[i].version & 0xff);
216                                         }                                               
217
218                                         for (j = j_num_axes; j < (j_num_axes + j_joystick[i].num_axes); j++) {
219                                                 j_axis[j].joydev = i;
220                                                 if (j_joystick[i].version) {
221                                                         j_axis[j].center_val = 0;
222                                                         j_axis[j].max_val = 32767;
223                                                         j_axis[j].min_val = -32767;
224                                                 }
225                                         }
226                                         for (j = j_num_buttons; j < (j_num_buttons + j_joystick[i].num_buttons); j++) {
227                                                 j_button[j].joydev = i;
228                                         }
229
230                                         j_num_axes += j_joystick[i].num_axes;
231                                         j_num_buttons += j_joystick[i].num_buttons;
232                                         
233                                 } else {
234                                         j_joystick[i].num_buttons = 0;
235                                         j_joystick[i].num_axes = 0;
236                                 }       
237
238                                 for (j = 0; j < i; j++) {
239                                         j_axes_in_sticks[i] += j_joystick[j].num_axes;
240                                         j_buttons_in_sticks[i] += j_joystick[j].num_buttons;
241                                 }
242                         }
243                 } else {
244                         printf ("no joysticks found\n");
245                         return 0;
246                 }               
247
248                 printf ("\n");
249
250                 if (j_num_axes > MAX_AXES)
251                         j_num_axes = MAX_AXES;
252                 if (j_num_buttons > MAX_BUTTONS)
253                         j_num_buttons = MAX_BUTTONS;
254
255                 joy_present = 1;
256                 joy_installed = 1;
257                 return 1;
258         }
259
260         return 1;
261 }
262
263
264 void joy_close() {
265         int i;
266
267         if (!joy_installed) return;
268
269         for (i = 0; i < 4; i++) {
270                 if (j_joystick[i].buffer>=0) {
271                         printf ("closing js%d\n", i);
272                         close (j_joystick[i].buffer);
273                 }
274                 j_joystick[i].buffer=-1;
275         }
276
277         joy_present=0;
278         joy_installed=0;
279 }
280
281
282 void joy_set_cen() {
283 }
284
285
286 int joy_get_scaled_reading(int raw, int axis_num)
287 {
288  int d, x;
289
290   raw -= j_axis[axis_num].center_val;
291
292    if (raw < 0)
293     d = j_axis[axis_num].center_val - j_axis[axis_num].min_val;
294    else if (raw > 0)
295     d = j_axis[axis_num].max_val - j_axis[axis_num].center_val;
296    else
297     d = 0;
298
299    if (d)
300     x = ((raw << 7) / d);
301    else
302     x = 0;
303
304    if ( x < -128 )
305     x = -128;
306    if ( x > 127 )
307     x = 127;
308
309 //added on 4/13/99 by Victor Rachels to add deadzone control
310   d =  (joy_deadzone) * 6;
311    if ((x > (-1*d)) && (x < d))
312     x = 0;
313 //end this section addition -VR
314
315   return x;
316 }
317
318
319 void joy_get_pos(int *x, int *y) {
320         int axis[MAX_AXES];
321
322         if ((!joy_installed)||(!joy_present)) { *x=*y=0; return; }
323
324         joystick_read_raw_axis (JOY_ALL_AXIS, axis);
325
326         *x = joy_get_scaled_reading( axis[0], 0 );
327         *y = joy_get_scaled_reading( axis[1], 1 );
328 }
329
330
331 int joy_get_btns () {
332         return 0;
333 }
334
335
336 int joy_get_button_state (int btn) {
337   if(btn >= j_num_buttons)
338    return 0;
339         j_Update_state ();
340
341         return j_button[btn].state;
342 }
343
344
345 int joy_get_button_down_cnt (int btn) {
346         int downcount;
347
348         j_Update_state ();
349
350         downcount = j_button[btn].downcount;
351         j_button[btn].downcount = 0;
352
353         return downcount;
354 }
355
356
357 //changed 6/24/99 to finally squish the timedown bug - Owen Evans
358 fix joy_get_button_down_time(int btn)  {
359         fix downtime;
360         j_Update_state ();
361
362         if (j_button[btn].state) {
363                 downtime = timer_get_fixed_seconds() - j_button[btn].timedown;
364                 j_button[btn].timedown = timer_get_fixed_seconds();
365         } else {
366                 downtime = 0;
367         }
368
369         return downtime;
370 }
371 //end changed - OE
372
373 void joy_poll() {
374
375 }
376
377
378 void joy_set_slow_reading(int flag) {
379
380 }
381
382 #endif // __ENV_LINUX__