]> icculus.org git repositories - btb/d2x.git/blob - arch/sdl/joy.c
OS X stuff
[btb/d2x.git] / arch / sdl / joy.c
1 /* $ Id: $ */
2 /*
3  *
4  * SDL joystick support
5  *
6  *
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include <conf.h>
11 #endif
12
13 #include <SDL/SDL.h>
14
15 #include "joy.h"
16 #include "error.h"
17 #include "timer.h"
18 #include "console.h"
19 #include "event.h"
20
21 #define MAX_JOYSTICKS 16
22 #define MAX_AXES 32
23
24 #define MAX_AXES_PER_JOYSTICK 8
25 #define MAX_BUTTONS_PER_JOYSTICK 16
26
27 char joy_present = 0;
28 int num_joysticks = 0;
29
30 int joy_deadzone = 0;
31
32 struct joybutton {
33         int state;
34         fix time_went_down;
35         int num_downs;
36         int num_ups;
37 };
38
39 struct joyaxis {
40         int             value;
41         int             min_val;
42         int             center_val;
43         int             max_val;
44 };
45
46 static struct joyinfo {
47         int n_axes;
48         int n_buttons;
49         struct joyaxis axes[MAX_AXES];
50         struct joybutton buttons[MAX_BUTTONS];
51 } Joystick;
52
53 static struct {
54         SDL_Joystick *handle;
55         int n_axes;
56         int n_buttons;
57         int axis_map[MAX_AXES_PER_JOYSTICK];
58         int button_map[MAX_BUTTONS_PER_JOYSTICK];
59 } SDL_Joysticks[MAX_JOYSTICKS];
60
61 void joy_button_handler(SDL_JoyButtonEvent *jbe)
62 {
63         int button;
64
65         button = SDL_Joysticks[jbe->which].button_map[jbe->button];
66
67         Joystick.buttons[button].state = jbe->state;
68
69         switch (jbe->type) {
70         case SDL_JOYBUTTONDOWN:
71                 Joystick.buttons[button].time_went_down
72                         = timer_get_fixed_seconds();
73                 Joystick.buttons[button].num_downs++;
74                 break;
75         case SDL_JOYBUTTONUP:
76                 Joystick.buttons[button].num_ups++;
77                 break;
78         }
79 }
80
81 void joy_axis_handler(SDL_JoyAxisEvent *jae)
82 {
83         int axis;
84
85         axis = SDL_Joysticks[jae->which].axis_map[jae->axis];
86         
87         Joystick.axes[axis].value = jae->value;
88 }
89
90
91 /* ----------------------------------------------- */
92
93 int joy_init()
94 {
95         int i,j,n;
96
97         if (SDL_Init(SDL_INIT_JOYSTICK) < 0) {
98                 con_printf(CON_VERBOSE, "sdl-joystick: initialisation failed: %s.",SDL_GetError());
99                 return 0;
100         }
101
102         memset(&Joystick,0,sizeof(Joystick));
103
104         n = SDL_NumJoysticks();
105
106         con_printf(CON_VERBOSE, "sdl-joystick: found %d joysticks\n", n);
107         for (i = 0; i < n; i++) {
108                 con_printf(CON_VERBOSE, "sdl-joystick %d: %s\n", i, SDL_JoystickName(i));
109                 SDL_Joysticks[num_joysticks].handle = SDL_JoystickOpen(i);
110                 if (SDL_Joysticks[num_joysticks].handle) {
111                         joy_present = 1;
112                         SDL_Joysticks[num_joysticks].n_axes
113                                 = SDL_JoystickNumAxes(SDL_Joysticks[num_joysticks].handle);
114                         SDL_Joysticks[num_joysticks].n_buttons
115                                 = SDL_JoystickNumButtons(SDL_Joysticks[num_joysticks].handle);
116                         con_printf(CON_VERBOSE, "sdl-joystick: %d axes\n", SDL_Joysticks[num_joysticks].n_axes);
117                         con_printf(CON_VERBOSE, "sdl-joystick: %d buttons\n", SDL_Joysticks[num_joysticks].n_buttons);
118                         for (j=0; j < SDL_Joysticks[num_joysticks].n_axes; j++)
119                                 SDL_Joysticks[num_joysticks].axis_map[j] = Joystick.n_axes++;
120                         for (j=0; j < SDL_Joysticks[num_joysticks].n_buttons; j++)
121                                 SDL_Joysticks[num_joysticks].button_map[j] = Joystick.n_buttons++;
122                         num_joysticks++;
123                 } else
124                         con_printf(CON_VERBOSE, "sdl-joystick: initialization failed!\n");
125                 con_printf(CON_VERBOSE, "sdl-joystick: %d axes (total)\n", Joystick.n_axes);
126                 con_printf(CON_VERBOSE, "sdl-joystick: %d buttons (total)\n", Joystick.n_buttons);
127         }
128                 
129         return joy_present;
130 }
131
132 void joy_close()
133 {
134         while (num_joysticks)
135                 SDL_JoystickClose(SDL_Joysticks[--num_joysticks].handle);
136 }
137
138 void joy_get_pos(int *x, int *y)
139 {
140         int axis[MAX_AXES];
141
142         if (!num_joysticks) {
143                 *x=*y=0;
144                 return;
145         }
146
147         joystick_read_raw_axis (JOY_ALL_AXIS, axis);
148
149         *x = joy_get_scaled_reading( axis[0], 0 );
150         *y = joy_get_scaled_reading( axis[1], 1 );
151 }
152
153 int joy_get_btns()
154 {
155 #if 0 // This is never used?
156         int i, buttons = 0;
157         for (i=0; i++; i<buttons) {
158                 switch (Joystick.buttons[i].state) {
159                 case SDL_PRESSED:
160                         buttons |= 1<<i;
161                         break;
162                 case SDL_RELEASED:
163                         break;
164                 }
165         }
166         return buttons;
167 #else
168         return 0;
169 #endif
170 }
171
172 int joy_get_button_down_cnt( int btn )
173 {
174         int num_downs;
175
176         if (!num_joysticks)
177                 return 0;
178
179         event_poll();
180
181         num_downs = Joystick.buttons[btn].num_downs;
182         Joystick.buttons[btn].num_downs = 0;
183
184         return num_downs;
185 }
186
187 fix joy_get_button_down_time(int btn)
188 {
189         fix time;
190
191         if (!num_joysticks)
192                 return 0;
193
194         event_poll();
195
196         switch (Joystick.buttons[btn].state) {
197         case SDL_PRESSED:
198                 time = timer_get_fixed_seconds() - Joystick.buttons[btn].time_went_down;
199                 Joystick.buttons[btn].time_went_down = timer_get_fixed_seconds();
200                 break;
201         case SDL_RELEASED:
202                 time = 0;
203                 break;
204         }
205
206         return time;
207 }
208
209 ubyte joystick_read_raw_axis( ubyte mask, int * axis )
210 {
211         int i;
212         
213         if (!num_joysticks)
214                 return 0;
215
216         event_poll();
217
218         for (i = 0; i <= JOY_NUM_AXES; i++) {
219                 axis[i] = Joystick.axes[i].value;
220         }
221
222         return 0;
223 }
224
225 void joy_flush()
226 {
227         int i;
228
229         if (!num_joysticks)
230                 return;
231
232         for (i = 0; i < Joystick.n_buttons; i++) {
233                 Joystick.buttons[i].time_went_down = 0;
234                 Joystick.buttons[i].num_downs = 0;
235         }
236         
237 }
238
239 int joy_get_button_state( int btn )
240 {
241         if (!num_joysticks)
242                 return 0;
243
244         if(btn >= Joystick.n_buttons)
245                 return 0;
246
247         event_poll();
248
249         return Joystick.buttons[btn].state;
250 }
251
252 void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max)
253 {
254         int i;
255
256         for (i = 0; i < JOY_NUM_AXES; i++) {
257                 axis_center[i] = Joystick.axes[i].center_val;
258                 axis_min[i] = Joystick.axes[i].min_val;
259                 axis_max[i] = Joystick.axes[i].max_val;
260         }
261 }
262
263 void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max)
264 {
265         int i;
266
267         for (i = 0; i < JOY_NUM_AXES; i++) {
268                 Joystick.axes[i].center_val = axis_center[i];
269                 Joystick.axes[i].min_val = axis_min[i];
270                 Joystick.axes[i].max_val = axis_max[i];
271         }
272 }
273
274 int joy_get_scaled_reading( int raw, int axis_num )
275 {
276 #if 1
277         return raw/256;
278 #else
279         int d, x;
280
281         raw -= Joystick.axes[axis_num].center_val;
282         
283         if (raw < 0)
284                 d = Joystick.axes[axis_num].center_val - Joystick.axes[axis_num].min_val;
285         else if (raw > 0)
286                 d = Joystick.axes[axis_num].max_val - Joystick.axes[axis_num].center_val;
287         else
288                 d = 0;
289         
290         if (d)
291                 x = ((raw << 7) / d);
292         else
293                 x = 0;
294         
295         if ( x < -128 )
296                 x = -128;
297         if ( x > 127 )
298                 x = 127;
299         
300         d =  (joy_deadzone) * 6;
301         if ((x > (-1*d)) && (x < d))
302                 x = 0;
303         
304         return x;
305 #endif
306 }
307
308 void joy_set_slow_reading( int flag )
309 {
310 }