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