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