SDL-1.2.14
[sdl_omap.git] / src / joystick / dc / SDL_sysjoystick.c
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 Sam Lantinga
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #ifdef SDL_JOYSTICK_DC
25
26 #include "SDL_events.h"
27 #include "SDL_joystick.h"
28 #include "../SDL_sysjoystick.h"
29 #include "../SDL_joystick_c.h"
30
31 #include <dc/maple.h>
32 #include <dc/maple/controller.h>
33
34 #define MAX_JOYSTICKS   8       /* only 2 are supported in the multimedia API */
35 #define MAX_AXES        6       /* each joystick can have up to 6 axes */
36 #define MAX_BUTTONS     8       /* and 8 buttons                      */
37 #define MAX_HATS        2
38
39 #define JOYNAMELEN      8
40
41 /* array to hold joystick ID values */
42 static uint8    SYS_Joystick_addr[MAX_JOYSTICKS];
43
44 /* The private structure used to keep track of a joystick */
45 struct joystick_hwdata
46 {
47         cont_cond_t prev_cond;
48         int prev_buttons;
49 };
50
51 /* Function to scan the system for joysticks.
52  * This function should set SDL_numjoysticks to the number of available
53  * joysticks.  Joystick 0 should be the system default joystick.
54  * It should return 0, or -1 on an unrecoverable fatal error.
55  */
56 int SDL_SYS_JoystickInit(void)
57 {
58         int numdevs;
59
60         int p,u;
61
62         numdevs = 0;
63         for(p=0;p<MAPLE_PORT_COUNT;p++) {
64                 for(u=0;u<MAPLE_UNIT_COUNT;u++) {
65                         if (maple_device_func(p,u)&MAPLE_FUNC_CONTROLLER) {
66                                 SYS_Joystick_addr[numdevs] = maple_addr(p,u);
67                                 numdevs++;
68                         }
69                 }
70         }
71
72         return(numdevs);
73 }
74
75 /* Function to get the device-dependent name of a joystick */
76 const char *SDL_SYS_JoystickName(int index)
77 {
78         maple_device_t *dev;
79         if (maple_compat_resolve(SYS_Joystick_addr[index],&dev,MAPLE_FUNC_CONTROLLER)!=0) return NULL;
80         return dev->info.product_name;
81 }
82
83 /* Function to open a joystick for use.
84    The joystick to open is specified by the index field of the joystick.
85    This should fill the nbuttons and naxes fields of the joystick structure.
86    It returns 0, or -1 if there is an error.
87  */
88 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
89 {
90         /* allocate memory for system specific hardware data */
91         joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
92         if (joystick->hwdata == NULL)
93         {
94                 SDL_OutOfMemory();
95                 return(-1);
96         }
97         SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
98
99         /* fill nbuttons, naxes, and nhats fields */
100         joystick->nbuttons = MAX_BUTTONS;
101         joystick->naxes = MAX_AXES;
102         joystick->nhats = MAX_HATS;
103         return(0);
104 }
105
106
107 /* Function to update the state of a joystick - called as a device poll.
108  * This function shouldn't update the joystick structure directly,
109  * but instead should call SDL_PrivateJoystick*() to deliver events
110  * and update joystick device state.
111  */
112
113 void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
114 {
115 const   int sdl_buttons[] = {
116         CONT_C,
117         CONT_B,
118         CONT_A,
119         CONT_START,
120         CONT_Z,
121         CONT_Y,
122         CONT_X,
123         CONT_D
124 };
125
126         uint8 addr;
127         cont_cond_t cond,*prev_cond;
128         int buttons,prev_buttons,i,changed;
129
130         addr = SYS_Joystick_addr[joystick->index];
131         if (cont_get_cond(addr,&cond)<0) return;
132
133         buttons = cond.buttons;
134         prev_buttons = joystick->hwdata->prev_buttons;
135         changed = buttons^prev_buttons;
136
137         if ((changed)&(CONT_DPAD_UP|CONT_DPAD_DOWN|CONT_DPAD_LEFT|CONT_DPAD_RIGHT)) {
138                 int hat = SDL_HAT_CENTERED;
139                 if (buttons&CONT_DPAD_UP) hat|=SDL_HAT_UP;
140                 if (buttons&CONT_DPAD_DOWN) hat|=SDL_HAT_DOWN;
141                 if (buttons&CONT_DPAD_LEFT) hat|=SDL_HAT_LEFT;
142                 if (buttons&CONT_DPAD_RIGHT) hat|=SDL_HAT_RIGHT;
143                 SDL_PrivateJoystickHat(joystick, 0, hat);
144         }
145         if ((changed)&(CONT_DPAD2_UP|CONT_DPAD2_DOWN|CONT_DPAD2_LEFT|CONT_DPAD2_RIGHT)) {
146                 int hat = SDL_HAT_CENTERED;
147                 if (buttons&CONT_DPAD2_UP) hat|=SDL_HAT_UP;
148                 if (buttons&CONT_DPAD2_DOWN) hat|=SDL_HAT_DOWN;
149                 if (buttons&CONT_DPAD2_LEFT) hat|=SDL_HAT_LEFT;
150                 if (buttons&CONT_DPAD2_RIGHT) hat|=SDL_HAT_RIGHT;
151                 SDL_PrivateJoystickHat(joystick, 1, hat);
152         }
153
154         for(i=0;i<sizeof(sdl_buttons)/sizeof(sdl_buttons[0]);i++) {
155                 if (changed & sdl_buttons[i]) {
156                         SDL_PrivateJoystickButton(joystick, i, (buttons & sdl_buttons[i])?SDL_PRESSED:SDL_RELEASED);
157                 }
158         }
159
160         prev_cond = &joystick->hwdata->prev_cond;
161         if (cond.joyx!=prev_cond->joyx)
162                 SDL_PrivateJoystickAxis(joystick, 0, cond.joyx-128);
163         if (cond.joyy!=prev_cond->joyy)
164                 SDL_PrivateJoystickAxis(joystick, 1, cond.joyy-128);
165         if (cond.rtrig!=prev_cond->rtrig)
166                 SDL_PrivateJoystickAxis(joystick, 2, cond.rtrig);
167         if (cond.ltrig!=prev_cond->ltrig)
168                 SDL_PrivateJoystickAxis(joystick, 3, cond.ltrig);
169         if (cond.joy2x!=prev_cond->joy2x)
170                 SDL_PrivateJoystickAxis(joystick, 4, cond.joy2x-128);
171         if (cond.joy2y!=prev_cond->joy2y)
172                 SDL_PrivateJoystickAxis(joystick, 5, cond.joy2y-128);
173
174         joystick->hwdata->prev_buttons = buttons;
175         joystick->hwdata->prev_cond = cond;
176 }
177
178 /* Function to close a joystick after use */
179 void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
180 {
181         if (joystick->hwdata != NULL) {
182                 /* free system specific hardware data */
183                 SDL_free(joystick->hwdata);
184         }
185 }
186
187 /* Function to perform any system-specific joystick related cleanup */
188 void SDL_SYS_JoystickQuit(void)
189 {
190         return;
191 }
192
193 #endif /* SDL_JOYSTICK_DC */