1 /* $Id: joy.c,v 1.10 2003-03-27 02:26:02 btb Exp $ */
13 #include <string.h> // for memset
22 #define MAX_JOYSTICKS 16
25 #define MAX_AXES_PER_JOYSTICK 8
26 #define MAX_BUTTONS_PER_JOYSTICK 16
27 #define MAX_HATS_PER_JOYSTICK 4
31 int num_joysticks = 0;
50 static struct joyinfo {
53 struct joyaxis axes[MAX_AXES];
54 struct joybutton buttons[MAX_BUTTONS+(MAX_HATS_PER_JOYSTICK*4)];
62 int hat_map[MAX_HATS_PER_JOYSTICK]; //Note: Descent expects hats to be buttons, so these are indices into Joystick.buttons
63 int axis_map[MAX_AXES_PER_JOYSTICK];
64 int button_map[MAX_BUTTONS_PER_JOYSTICK];
65 } SDL_Joysticks[MAX_JOYSTICKS];
67 void joy_button_handler(SDL_JoyButtonEvent *jbe)
71 button = SDL_Joysticks[jbe->which].button_map[jbe->button];
73 Joystick.buttons[button].state = jbe->state;
76 case SDL_JOYBUTTONDOWN:
77 Joystick.buttons[button].time_went_down
78 = timer_get_fixed_seconds();
79 Joystick.buttons[button].num_downs++;
82 Joystick.buttons[button].num_ups++;
87 void joy_hat_handler(SDL_JoyHatEvent *jhe)
89 int hat = SDL_Joysticks[jhe->which].hat_map[jhe->hat];
92 //Save last state of the hat-button
93 Joystick.buttons[hat ].last_state = Joystick.buttons[hat ].state;
94 Joystick.buttons[hat+1].last_state = Joystick.buttons[hat+1].state;
95 Joystick.buttons[hat+2].last_state = Joystick.buttons[hat+2].state;
96 Joystick.buttons[hat+3].last_state = Joystick.buttons[hat+3].state;
98 //get current state of the hat-button
99 Joystick.buttons[hat ].state = ((jhe->value & SDL_HAT_UP)>0);
100 Joystick.buttons[hat+1].state = ((jhe->value & SDL_HAT_RIGHT)>0);
101 Joystick.buttons[hat+2].state = ((jhe->value & SDL_HAT_DOWN)>0);
102 Joystick.buttons[hat+3].state = ((jhe->value & SDL_HAT_LEFT)>0);
104 //determine if a hat-button up or down event based on state and last_state
105 for(hbi=0;hbi<4;hbi++)
107 if( !Joystick.buttons[hat+hbi].last_state && Joystick.buttons[hat+hbi].state) //last_state up, current state down
109 Joystick.buttons[hat+hbi].time_went_down
110 = timer_get_fixed_seconds();
111 Joystick.buttons[hat+hbi].num_downs++;
113 else if(Joystick.buttons[hat+hbi].last_state && !Joystick.buttons[hat+hbi].state) //last_state down, current state up
115 Joystick.buttons[hat+hbi].num_ups ++;
120 void joy_axis_handler(SDL_JoyAxisEvent *jae)
124 axis = SDL_Joysticks[jae->which].axis_map[jae->axis];
126 Joystick.axes[axis].value = jae->value;
130 /* ----------------------------------------------- */
136 if (SDL_Init(SDL_INIT_JOYSTICK) < 0) {
137 con_printf(CON_VERBOSE, "sdl-joystick: initialisation failed: %s.",SDL_GetError());
141 memset(&Joystick,0,sizeof(Joystick));
143 n = SDL_NumJoysticks();
145 con_printf(CON_VERBOSE, "sdl-joystick: found %d joysticks\n", n);
146 for (i = 0; i < n; i++) {
147 con_printf(CON_VERBOSE, "sdl-joystick %d: %s\n", i, SDL_JoystickName(i));
148 SDL_Joysticks[num_joysticks].handle = SDL_JoystickOpen(i);
149 if (SDL_Joysticks[num_joysticks].handle) {
152 SDL_Joysticks[num_joysticks].n_axes
153 = SDL_JoystickNumAxes(SDL_Joysticks[num_joysticks].handle);
154 if(SDL_Joysticks[num_joysticks].n_axes > MAX_AXES_PER_JOYSTICK)
156 Warning("sdl-joystick: found %d axes, only %d supported. Game may be unstable.\n", SDL_Joysticks[num_joysticks].n_axes, MAX_AXES_PER_JOYSTICK);
157 SDL_Joysticks[num_joysticks].n_axes = MAX_AXES_PER_JOYSTICK;
160 SDL_Joysticks[num_joysticks].n_buttons
161 = SDL_JoystickNumButtons(SDL_Joysticks[num_joysticks].handle);
162 if(SDL_Joysticks[num_joysticks].n_buttons > MAX_BUTTONS_PER_JOYSTICK)
164 Warning("sdl-joystick: found %d buttons, only %d supported. Game may be unstable.\n", SDL_Joysticks[num_joysticks].n_buttons, MAX_BUTTONS_PER_JOYSTICK);
165 SDL_Joysticks[num_joysticks].n_buttons = MAX_BUTTONS_PER_JOYSTICK;
168 SDL_Joysticks[num_joysticks].n_hats
169 = SDL_JoystickNumHats(SDL_Joysticks[num_joysticks].handle);
170 if(SDL_Joysticks[num_joysticks].n_hats > MAX_HATS_PER_JOYSTICK)
172 Warning("sdl-joystick: found %d hats, only %d supported. Game may be unstable.\n", SDL_Joysticks[num_joysticks].n_hats, MAX_HATS_PER_JOYSTICK);
173 SDL_Joysticks[num_joysticks].n_hats = MAX_HATS_PER_JOYSTICK;
176 con_printf(CON_VERBOSE, "sdl-joystick: %d axes\n", SDL_Joysticks[num_joysticks].n_axes);
177 con_printf(CON_VERBOSE, "sdl-joystick: %d buttons\n", SDL_Joysticks[num_joysticks].n_buttons);
178 con_printf(CON_VERBOSE, "sdl-joystick: %d hats\n", SDL_Joysticks[num_joysticks].n_hats);
180 for (j=0; j < SDL_Joysticks[num_joysticks].n_axes; j++)
181 SDL_Joysticks[num_joysticks].axis_map[j] = Joystick.n_axes++;
182 for (j=0; j < SDL_Joysticks[num_joysticks].n_buttons; j++)
183 SDL_Joysticks[num_joysticks].button_map[j] = Joystick.n_buttons++;
184 for (j=0; j < SDL_Joysticks[num_joysticks].n_hats; j++)
186 SDL_Joysticks[num_joysticks].hat_map[j] = Joystick.n_buttons;
187 Joystick.n_buttons += 4; //a hat counts as four buttons
193 con_printf(CON_VERBOSE, "sdl-joystick: initialization failed!\n");
194 con_printf(CON_VERBOSE, "sdl-joystick: %d axes (total)\n", Joystick.n_axes);
195 con_printf(CON_VERBOSE, "sdl-joystick: %d buttons (total)\n", Joystick.n_buttons);
203 while (num_joysticks)
204 SDL_JoystickClose(SDL_Joysticks[--num_joysticks].handle);
207 void joy_get_pos(int *x, int *y)
211 if (!num_joysticks) {
216 joystick_read_raw_axis (JOY_ALL_AXIS, axis);
218 *x = joy_get_scaled_reading( axis[0], 0 );
219 *y = joy_get_scaled_reading( axis[1], 1 );
224 #if 0 // This is never used?
226 for (i=0; i++; i<buttons) {
227 switch (Joystick.buttons[i].state) {
241 int joy_get_button_down_cnt( int btn )
250 num_downs = Joystick.buttons[btn].num_downs;
251 Joystick.buttons[btn].num_downs = 0;
256 fix joy_get_button_down_time(int btn)
265 switch (Joystick.buttons[btn].state) {
267 time = timer_get_fixed_seconds() - Joystick.buttons[btn].time_went_down;
268 Joystick.buttons[btn].time_went_down = timer_get_fixed_seconds();
278 ubyte joystick_read_raw_axis( ubyte mask, int * axis )
287 for (i = 0; i <= JOY_NUM_AXES; i++) {
288 axis[i] = Joystick.axes[i].value;
301 for (i = 0; i < Joystick.n_buttons; i++) {
302 Joystick.buttons[i].time_went_down = 0;
303 Joystick.buttons[i].num_downs = 0;
308 int joy_get_button_state( int btn )
313 if(btn >= Joystick.n_buttons)
318 return Joystick.buttons[btn].state;
321 void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max)
325 for (i = 0; i < JOY_NUM_AXES; i++) {
326 axis_center[i] = Joystick.axes[i].center_val;
327 axis_min[i] = Joystick.axes[i].min_val;
328 axis_max[i] = Joystick.axes[i].max_val;
332 void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max)
336 for (i = 0; i < JOY_NUM_AXES; i++) {
337 Joystick.axes[i].center_val = axis_center[i];
338 Joystick.axes[i].min_val = axis_min[i];
339 Joystick.axes[i].max_val = axis_max[i];
343 int joy_get_scaled_reading( int raw, int axis_num )
350 raw -= Joystick.axes[axis_num].center_val;
353 d = Joystick.axes[axis_num].center_val - Joystick.axes[axis_num].min_val;
355 d = Joystick.axes[axis_num].max_val - Joystick.axes[axis_num].center_val;
360 x = ((raw << 7) / d);
369 d = (joy_deadzone) * 6;
370 if ((x > (-1*d)) && (x < d))
377 void joy_set_slow_reading( int flag )