improve linux makefile
[picodrive.git] / platform / linux / usbjoy.c
1 /* Title: USB Joystick library
2    Version 0.2
3    Written by Puck2099 (puck2099@gmail.com), (c) 2006.
4    <http://www.gp32wip.com>
5
6    If you use this library or a part of it, please, let it know.
7
8    This library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Lesser General Public
10    License as published by the Free Software Foundation; either
11    version 2.1 of the License, or (at your option) any later version.
12
13    This library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with this library; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 */
22
23 #include <stdlib.h>
24 #include <stdio.h>              /* For the definition of NULL */
25 #include <sys/types.h>          // For Device open
26 #include <sys/stat.h>
27 #include <sys/ioctl.h>
28 #include <fcntl.h>
29 #include <unistd.h>             // For Device read
30
31 #include <string.h>
32 #include <limits.h>             /* For the definition of PATH_MAX */
33 #include <linux/joystick.h>
34
35 #include "usbjoy.h"
36
37 /* This is a try to support analog joys. Untested. */
38 #define DEAD_ZONE (8*1024)
39
40 /*
41   Function: joy_open
42
43   Opens a USB joystick and fills its information.
44
45   Parameters:
46
47   joynumber - Joystick's identifier (0 reserved for GP2X's builtin Joystick).
48
49   Returns:
50
51   Filled usbjoy structure.
52
53 */
54 struct usbjoy *joy_open(int joynumber)
55 {
56         int fd;
57         char path [128];
58         struct usbjoy * joy = NULL;
59         struct js_event event;
60 #ifdef __GP2X__
61         static char insmod_done = 0;
62         // notaz: on my system I get unresolved input_* symbols, so have to 'insmod input' too
63         // also we should insmod only once, not on every joy_open() call.
64         if (!insmod_done) {
65                 system ("insmod input");
66                 system ("insmod joydev"); // Loads joydev module
67                 insmod_done = 1;
68         }
69 #endif
70
71         if (joynumber == 0) {
72         }
73         else if (joynumber > 0) {
74                 sprintf (path, "/dev/input/js%d", joynumber-1);
75                 fd = open(path, O_RDONLY, 0);
76                 if (fd == -1) {
77                         sprintf (path, "/dev/js%d", joynumber-1);
78                         fd = open(path, O_RDONLY, 0);
79                 }
80                 if (fd != -1) {
81                         joy = (struct usbjoy *) malloc(sizeof(*joy));
82                         if (joy == NULL) { close(fd); return NULL; }
83                         memset(joy, 0, sizeof(*joy));
84
85                         // Set the joystick to non-blocking read mode
86                         fcntl(fd, F_SETFL, O_NONBLOCK);
87
88                         // notaz: maybe we should flush init events now.
89                         // My pad returns axis as active when I plug it in, which is kind of annoying.
90                         while (read(fd, &event, sizeof(event)) > 0);
91
92                         // Joystick's file descriptor
93                         joy->fd = fd;
94
95                         // Joystick's name
96                         ioctl(joy->fd, JSIOCGNAME(128*sizeof(char)), joy->name);
97
98                         // Joystick's device
99                         strcpy(joy->device, path);
100
101                         // Joystick's buttons
102                         ioctl(joy->fd, JSIOCGBUTTONS, &joy->numbuttons);
103
104                         // Joystick's axes
105                         ioctl(joy->fd, JSIOCGAXES, &joy->numaxes);
106
107                         // Joystick's type (derived from name)
108                         if (strncasecmp(joy->name, "logitech", strlen("logitech")) == 0)
109                              joy->type = JOY_TYPE_LOGITECH;
110                         else joy->type = JOY_TYPE_GENERIC;
111                 } else {
112                         // printf ("ERROR: No Joystick found\n");
113                 }
114         }
115         return joy;
116 }
117
118 /*
119   Function: joy_name
120
121   Returns Joystick's name.
122
123   Parameters:
124
125   joy - Selected joystick.
126
127   Returns:
128
129   Joystick's name or NULL if <usbjoy> struct is empty.
130 */
131 char * joy_name (struct usbjoy * joy) {
132   if (joy != NULL)  return joy->name;
133   else return NULL;
134 }
135
136
137 /*
138   Function: joy_device
139
140   Returns Joystick's device.
141
142   Parameters:
143
144   joy - Selected joystick.
145
146   Returns:
147
148   Joystick's device or NULL if <usbjoy> struct is empty.
149 */
150 char * joy_device (struct usbjoy * joy) {
151   if (joy != NULL)  return joy->device;
152   else return NULL;
153 }
154
155
156 /*
157   Function: joy_buttons
158
159   Returns Joystick's buttons number.
160
161   Parameters:
162
163   joy - Selected joystick.
164
165   Returns:
166
167   Joystick's buttons or 0 if <usbjoy> struct is empty.
168 */
169 int joy_buttons (struct usbjoy * joy) {
170   if (joy != NULL) return joy->numbuttons;
171   else return 0;
172 }
173
174
175 /*
176   Function: joy_axes
177
178   Returns Joystick's axes number.
179
180   Parameters:
181
182   joy - Selected joystick.
183
184   Returns:
185
186   Joystick's axes or 0 if <usbjoy> struct is empty.
187 */
188 int joy_axes (struct usbjoy * joy) {
189   if (joy != NULL) return joy->numaxes;
190   else return 0;
191 }
192
193
194 /*
195   Function: joy_update
196
197   Updates Joystick's internal information (<statebuttons> and <stateaxes> fields).
198
199   Parameters:
200
201   joy - Selected joystick.
202
203   Returns:
204
205   0 - No events registered (no need to update).
206   1 - Events registered (a button or axe has been pushed).
207   -1 - Error: <usbjoy> struct is empty.
208 */
209 int joy_update (struct usbjoy * joy) {
210   struct js_event events[0xff];
211   int i, len;
212   int event = 0;
213   if (joy != NULL) {
214     if ((len=read(joy->fd, events, (sizeof events))) >0) {
215       len /= sizeof(events[0]);
216       for ( i=0; i<len; ++i ) {
217         switch (events[i].type & ~JS_EVENT_INIT) {
218         case JS_EVENT_AXIS:
219           if (events[i].number == 0) {
220             joy->stateaxes[JOYLEFT] = joy->stateaxes[JOYRIGHT] = 0;
221             if      (events[i].value < -DEAD_ZONE) joy->stateaxes[JOYLEFT] = 1;
222             else if (events[i].value >  DEAD_ZONE) joy->stateaxes[JOYRIGHT] = 1;
223             joy->axevals[0] = events[i].value;
224           }
225           else if (events[i].number == 1) {
226             joy->stateaxes[JOYUP] = joy->stateaxes[JOYDOWN] = 0;
227             if      (events[i].value < -DEAD_ZONE) joy->stateaxes[JOYUP] = 1;
228             else if (events[i].value >  DEAD_ZONE) joy->stateaxes[JOYDOWN] = 1;
229             joy->axevals[1] = events[i].value;
230           }
231           event = 1;
232           break;
233         case JS_EVENT_BUTTON:
234           joy->statebuttons[events[i].number] = events[i].value;
235           event = 1;
236           break;
237         default:
238           break;
239         }
240       }
241     }
242   }
243   else {
244     event = -1;
245   }
246   return event;
247 }
248
249
250 /*
251   Function: joy_getbutton
252
253   Returns Joystick's button information.
254
255   Parameters:
256
257   button - Button which value you want to know (from 0 to 31).
258   joy - Selected joystick.
259
260   Returns:
261
262   0 - Button NOT pushed.
263   1 - Button pushed.
264   -1 - Error: <usbjoy> struct is empty.
265 */
266 int joy_getbutton (int button, struct usbjoy * joy) {
267   if (joy != NULL) {
268     if (button < joy_buttons(joy)) return joy->statebuttons[button];
269     else return 0;
270   }
271   else return -1;
272 }
273
274
275 /*
276   Function: joy_getaxe
277
278   Returns Joystick's axes information.
279
280   Parameters:
281
282   axe - Axe which value you want to know (see <Axes values>).
283   joy - Selected joystick.
284
285   Returns:
286
287   0 - Direction NOT pushed.
288   1 - Direction pushed.
289   -1 - Error: <usbjoy> struct is empty.
290 */
291 int joy_getaxe (int axe, struct usbjoy * joy) {
292   if (joy != NULL) {
293     if (axe < 4) return joy->stateaxes[axe];
294     else return 0;
295   }
296   else return -1;
297 }
298
299
300 /*
301   Function: joy_close
302
303   Closes selected joystick's file descriptor and detroys it's fields.
304
305   Parameters:
306
307   joy - Selected joystick.
308
309   Returns:
310
311   0 - Joystick successfully closed.
312   -1 - Error: <usbjoy> struct is empty.
313 */
314 int joy_close (struct usbjoy * joy) {
315   if (joy != NULL) {
316     close (joy->fd);
317     free (joy);
318     return 0;
319   }
320   else return -1;
321 }
322
323
324 /*********************************************************************/
325
326 #include "../common/common.h"
327
328 int num_of_joys = 0;
329 struct usbjoy *joys[4];
330
331 void usbjoy_init (void)
332 {
333         /* Open available joysticks -GnoStiC */
334         int i, n = 0;
335
336         printf("\n");
337         for (i = 0; i < 4; i++) {
338                 joys[n] = joy_open(i+1);
339                 if (joys[n] && joy_buttons(joys[n]) > 0) {
340                         printf ("+-Joystick %d: \"%s\", buttons = %i\n", i+1, joy_name(joys[n]), joy_buttons(joys[n]));
341                         n++;
342                 }
343         }
344         num_of_joys = n;
345
346         printf("Found %d Joystick(s)\n",num_of_joys);
347 }
348
349 void usbjoy_update (void)
350 {
351         /* Update Joystick Event Cache */
352         int q, foo;
353         for (q=0; q < num_of_joys; q++) {
354                 foo = joy_update (joys[q]);
355         }
356 }
357
358 int usbjoy_check (int joyno)
359 {
360         /* Check Joystick */
361         int q, joyExKey = 0;
362         struct usbjoy *joy = joys[joyno];
363
364         if (joy != NULL) {
365                 if (joy_getaxe(JOYUP, joy))    { joyExKey |= PBTN_UP; }
366                 if (joy_getaxe(JOYDOWN, joy))  { joyExKey |= PBTN_DOWN; }
367                 if (joy_getaxe(JOYLEFT, joy))  { joyExKey |= PBTN_LEFT; }
368                 if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= PBTN_RIGHT; }
369
370                 /* loop through joy buttons to check if they are pushed */
371                 for (q=0; q<joy_buttons (joy); q++) {
372                         if (joy_getbutton (q, joy)) {
373                                 if (joy->type == JOY_TYPE_LOGITECH) {
374                                         switch (q) {
375                                                 case 0: joyExKey |= PBTN_WEST;  break;
376                                                 case 1: joyExKey |= PBTN_SOUTH; break;
377                                                 case 2: joyExKey |= PBTN_EAST;  break;
378                                                 case 3: joyExKey |= PBTN_NORTH; break;
379                                         }
380                                 } else {
381                                         switch (q) {
382                                                 case 0: joyExKey |= PBTN_NORTH; break;
383                                                 case 1: joyExKey |= PBTN_EAST;  break;
384                                                 case 2: joyExKey |= PBTN_SOUTH; break;
385                                                 case 3: joyExKey |= PBTN_WEST;  break;
386                                         }
387                                 }
388
389                                 switch (q) {
390                                         case  4: joyExKey |= PBTN_L; break;
391                                         case  5: joyExKey |= PBTN_R; break;
392                                         case  6: joyExKey |= PBTN_L; break; /* left shoulder button 2 */
393                                         case  7: joyExKey |= PBTN_R; break; /* right shoulder button 2 */
394 /*
395                                         case  8: joyExKey |= GP2X_SELECT;break;
396                                         case  9: joyExKey |= GP2X_START; break;
397                                         case 10: joyExKey |= GP2X_PUSH;  break;
398                                         case 11: joyExKey |= GP2X_PUSH;  break;
399 */
400                                 }
401                         }
402                 }
403         }
404         return joyExKey;
405 }
406
407 int usbjoy_check2 (int joyno)
408 {
409         /* Check Joystick, don't map to gp2x joy */
410         int q, to, joyExKey = 0;
411         struct usbjoy *joy = joys[joyno];
412
413         if (joy != NULL) {
414                 if (joy_getaxe(JOYUP, joy))    { joyExKey |= 1 << 0; }
415                 if (joy_getaxe(JOYDOWN, joy))  { joyExKey |= 1 << 1; }
416                 if (joy_getaxe(JOYLEFT, joy))  { joyExKey |= 1 << 2; }
417                 if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= 1 << 3; }
418
419                 /* loop through joy buttons to check if they are pushed */
420                 to = joy->numbuttons;
421                 if (to > 32-4) to = 32-4;
422                 for (q=0; q < to; q++)
423                         if (joy->statebuttons[q]) joyExKey |= 1 << (q+4);
424         }
425         return joyExKey;
426 }
427
428
429
430 void usbjoy_deinit (void)
431 {
432         int i;
433         for (i=0; i<num_of_joys; i++) {
434                 joy_close (joys[i]);
435                 joys[i] = NULL;
436         }
437         num_of_joys = 0;
438 }
439