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