12 #include <string.h> // for memset
24 #define MAX_JOYSTICKS 16
26 #define MAX_AXES_PER_JOYSTICK 8
27 #define MAX_BUTTONS_PER_JOYSTICK 16
28 #define MAX_HATS_PER_JOYSTICK 4
30 extern char *joyaxis_text[]; //from kconfig.c
33 int num_joysticks = 0;
54 /* This struct is a "virtual" joystick, which includes all the axes
55 * and buttons of every joystick found.
57 static struct joyinfo {
60 struct joyaxis axes[JOY_MAX_AXES];
61 struct joybutton buttons[JOY_MAX_BUTTONS];
64 /* This struct is an array, with one entry for each physical joystick
72 int hat_map[MAX_HATS_PER_JOYSTICK]; //Note: Descent expects hats to be buttons, so these are indices into Joystick.buttons
73 int axis_map[MAX_AXES_PER_JOYSTICK];
74 int button_map[MAX_BUTTONS_PER_JOYSTICK];
75 } SDL_Joysticks[MAX_JOYSTICKS];
77 void joy_button_handler(SDL_JoyButtonEvent *jbe)
81 button = SDL_Joysticks[jbe->which].button_map[jbe->button];
83 vkey_handler(KEY_JB1 + button, jbe->state == SDL_PRESSED);
85 Joystick.buttons[button].state = jbe->state;
88 case SDL_JOYBUTTONDOWN:
89 Joystick.buttons[button].time_went_down
90 = timer_get_fixed_seconds();
91 Joystick.buttons[button].num_downs++;
94 Joystick.buttons[button].num_ups++;
99 void joy_hat_handler(SDL_JoyHatEvent *jhe)
101 int hat = SDL_Joysticks[jhe->which].hat_map[jhe->hat];
104 vkey_handler(KEY_JB1 + hat + 0, (jhe->value & SDL_HAT_UP ) > 0);
105 vkey_handler(KEY_JB1 + hat + 1, (jhe->value & SDL_HAT_RIGHT) > 0);
106 vkey_handler(KEY_JB1 + hat + 2, (jhe->value & SDL_HAT_DOWN ) > 0);
107 vkey_handler(KEY_JB1 + hat + 3, (jhe->value & SDL_HAT_LEFT ) > 0);
109 //Save last state of the hat-button
110 Joystick.buttons[hat ].last_state = Joystick.buttons[hat ].state;
111 Joystick.buttons[hat+1].last_state = Joystick.buttons[hat+1].state;
112 Joystick.buttons[hat+2].last_state = Joystick.buttons[hat+2].state;
113 Joystick.buttons[hat+3].last_state = Joystick.buttons[hat+3].state;
115 //get current state of the hat-button
116 Joystick.buttons[hat ].state = ((jhe->value & SDL_HAT_UP)>0);
117 Joystick.buttons[hat+1].state = ((jhe->value & SDL_HAT_RIGHT)>0);
118 Joystick.buttons[hat+2].state = ((jhe->value & SDL_HAT_DOWN)>0);
119 Joystick.buttons[hat+3].state = ((jhe->value & SDL_HAT_LEFT)>0);
121 //determine if a hat-button up or down event based on state and last_state
122 for(hbi=0;hbi<4;hbi++)
124 if( !Joystick.buttons[hat+hbi].last_state && Joystick.buttons[hat+hbi].state) //last_state up, current state down
126 Joystick.buttons[hat+hbi].time_went_down
127 = timer_get_fixed_seconds();
128 Joystick.buttons[hat+hbi].num_downs++;
130 else if(Joystick.buttons[hat+hbi].last_state && !Joystick.buttons[hat+hbi].state) //last_state down, current state up
132 Joystick.buttons[hat+hbi].num_ups++;
137 void joy_axis_handler(SDL_JoyAxisEvent *jae)
141 axis = SDL_Joysticks[jae->which].axis_map[jae->axis];
143 Joystick.axes[axis].value = jae->value;
147 /* ----------------------------------------------- */
154 if (SDL_Init(SDL_INIT_JOYSTICK) < 0) {
155 con_printf(CON_VERBOSE, "sdl-joystick: initialisation failed: %s.",SDL_GetError());
159 memset(&Joystick,0,sizeof(Joystick));
160 memset(joyaxis_text, 0, JOY_MAX_AXES * sizeof(char *));
162 n = SDL_NumJoysticks();
164 con_printf(CON_VERBOSE, "sdl-joystick: found %d joysticks\n", n);
165 for (i = 0; i < n; i++) {
166 con_printf(CON_VERBOSE, "sdl-joystick %d: %s\n", i, SDL_JoystickName(i));
167 SDL_Joysticks[num_joysticks].handle = SDL_JoystickOpen(i);
168 if (SDL_Joysticks[num_joysticks].handle) {
171 SDL_Joysticks[num_joysticks].n_axes
172 = SDL_JoystickNumAxes(SDL_Joysticks[num_joysticks].handle);
173 if(SDL_Joysticks[num_joysticks].n_axes > MAX_AXES_PER_JOYSTICK)
175 Warning("sdl-joystick: found %d axes, only %d supported. Game may be unstable.\n", SDL_Joysticks[num_joysticks].n_axes, MAX_AXES_PER_JOYSTICK);
176 SDL_Joysticks[num_joysticks].n_axes = MAX_AXES_PER_JOYSTICK;
179 SDL_Joysticks[num_joysticks].n_buttons
180 = SDL_JoystickNumButtons(SDL_Joysticks[num_joysticks].handle);
181 if(SDL_Joysticks[num_joysticks].n_buttons > MAX_BUTTONS_PER_JOYSTICK)
183 Warning("sdl-joystick: found %d buttons, only %d supported. Game may be unstable.\n", SDL_Joysticks[num_joysticks].n_buttons, MAX_BUTTONS_PER_JOYSTICK);
184 SDL_Joysticks[num_joysticks].n_buttons = MAX_BUTTONS_PER_JOYSTICK;
187 SDL_Joysticks[num_joysticks].n_hats
188 = SDL_JoystickNumHats(SDL_Joysticks[num_joysticks].handle);
189 if(SDL_Joysticks[num_joysticks].n_hats > MAX_HATS_PER_JOYSTICK)
191 Warning("sdl-joystick: found %d hats, only %d supported. Game may be unstable.\n", SDL_Joysticks[num_joysticks].n_hats, MAX_HATS_PER_JOYSTICK);
192 SDL_Joysticks[num_joysticks].n_hats = MAX_HATS_PER_JOYSTICK;
195 con_printf(CON_VERBOSE, "sdl-joystick: %d axes\n", SDL_Joysticks[num_joysticks].n_axes);
196 con_printf(CON_VERBOSE, "sdl-joystick: %d buttons\n", SDL_Joysticks[num_joysticks].n_buttons);
197 con_printf(CON_VERBOSE, "sdl-joystick: %d hats\n", SDL_Joysticks[num_joysticks].n_hats);
199 for (j=0; j < SDL_Joysticks[num_joysticks].n_axes; j++)
201 sprintf(temp, "J%d A%d", i + 1, j + 1);
202 joyaxis_text[Joystick.n_axes] = d_strdup(temp);
203 SDL_Joysticks[num_joysticks].axis_map[j] = Joystick.n_axes++;
205 for (j=0; j < SDL_Joysticks[num_joysticks].n_buttons; j++)
207 sprintf(temp, "J%dB%d", i + 1, j + 1);
208 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
209 SDL_Joysticks[num_joysticks].button_map[j] = Joystick.n_buttons++;
211 for (j=0; j < SDL_Joysticks[num_joysticks].n_hats; j++)
213 SDL_Joysticks[num_joysticks].hat_map[j] = Joystick.n_buttons;
214 //a hat counts as four buttons
216 sprintf(temp, "J%dH%dUP", i + 1, j + 1);
217 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
218 Joystick.n_buttons++;
220 sprintf(temp, "J%dH%dRIGHT", i + 1, j + 1);
221 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
222 Joystick.n_buttons++;
224 sprintf(temp, "J%dH%dDOWN", i + 1, j + 1);
225 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
226 Joystick.n_buttons++;
228 sprintf(temp, "J%dH%dLEFT", i + 1, j + 1);
229 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
230 Joystick.n_buttons++;
236 con_printf(CON_VERBOSE, "sdl-joystick: initialization failed!\n");
238 con_printf(CON_VERBOSE, "sdl-joystick: %d axes (total)\n", Joystick.n_axes);
239 con_printf(CON_VERBOSE, "sdl-joystick: %d buttons (total)\n", Joystick.n_buttons);
242 joy_num_axes = Joystick.n_axes;
250 while (num_joysticks)
251 SDL_JoystickClose(SDL_Joysticks[--num_joysticks].handle);
252 while (Joystick.n_axes--)
253 d_free(joyaxis_text[Joystick.n_axes]);
254 while (Joystick.n_buttons--)
255 d_free(key_text[KEY_JB1 + Joystick.n_buttons]);
258 void joy_get_pos(int *x, int *y)
260 int axis[JOY_MAX_AXES];
262 if (!num_joysticks) {
267 joystick_read_raw_axis (JOY_ALL_AXIS, axis);
269 *x = joy_get_scaled_reading( axis[0], 0 );
270 *y = joy_get_scaled_reading( axis[1], 1 );
275 #if 0 // This is never used?
277 for (i=0; i++; i<buttons) {
278 switch (Joystick.buttons[i].state) {
292 int joy_get_button_down_cnt( int btn )
301 num_downs = Joystick.buttons[btn].num_downs;
302 Joystick.buttons[btn].num_downs = 0;
307 fix joy_get_button_down_time(int btn)
316 switch (Joystick.buttons[btn].state) {
318 time = timer_get_fixed_seconds() - Joystick.buttons[btn].time_went_down;
319 Joystick.buttons[btn].time_went_down = timer_get_fixed_seconds();
329 ubyte joystick_read_raw_axis( ubyte mask, int * axis )
332 ubyte channel_masks = 0;
339 for (i = 0; i < Joystick.n_axes; i++)
341 if ((axis[i] = Joystick.axes[i].value))
342 channel_masks |= 1 << i;
345 return channel_masks;
355 for (i = 0; i < Joystick.n_buttons; i++) {
356 Joystick.buttons[i].time_went_down = 0;
357 Joystick.buttons[i].num_downs = 0;
362 int joy_get_button_state( int btn )
367 if(btn >= Joystick.n_buttons)
372 return Joystick.buttons[btn].state;
375 void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max)
379 for (i = 0; i < Joystick.n_axes; i++)
381 axis_center[i] = Joystick.axes[i].center_val;
382 axis_min[i] = Joystick.axes[i].min_val;
383 axis_max[i] = Joystick.axes[i].max_val;
387 void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max)
391 for (i = 0; i < Joystick.n_axes; i++)
393 Joystick.axes[i].center_val = axis_center[i];
394 Joystick.axes[i].min_val = axis_min[i];
395 Joystick.axes[i].max_val = axis_max[i];
399 int joy_get_scaled_reading( int raw, int axis_num )
406 raw -= Joystick.axes[axis_num].center_val;
409 d = Joystick.axes[axis_num].center_val - Joystick.axes[axis_num].min_val;
411 d = Joystick.axes[axis_num].max_val - Joystick.axes[axis_num].center_val;
416 x = ((raw << 7) / d);
425 d = (joy_deadzone) * 6;
426 if ((x > (-1*d)) && (x < d))
433 void joy_set_slow_reading( int flag )