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