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