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