12 #include <string.h> // for memset
26 #define MAX_JOYSTICKS 16
28 #define MAX_AXES_PER_JOYSTICK 8
29 #define MAX_BUTTONS_PER_JOYSTICK 16
30 #define MAX_HATS_PER_JOYSTICK 4
32 extern char *joyaxis_text[]; //from kconfig.c
35 int num_joysticks = 0;
48 /* This struct is a "virtual" joystick, which includes all the axes
49 * and buttons of every joystick found.
51 static struct joyinfo {
54 struct joyaxis axes[JOY_MAX_AXES];
57 /* This struct is an array, with one entry for each physical joystick
65 int hat_map[MAX_HATS_PER_JOYSTICK]; //Note: Descent expects hats to be buttons, so these are indices into Joystick.buttons
66 int axis_map[MAX_AXES_PER_JOYSTICK];
67 int button_map[MAX_BUTTONS_PER_JOYSTICK];
68 } SDL_Joysticks[MAX_JOYSTICKS];
73 // 1 = move forward/back
75 // 3 = move left/right
76 // 4 = look left/right
78 // 6 = bank left/right
80 cvar_t joy_advaxes[] = {
81 { "joy_advaxisx", "4", 1 },
82 { "joy_advaxisy", "2", 1 },
83 { "joy_advaxisz", "0", 1 },
84 { "joy_advaxisr", "0", 1 },
85 { "joy_advaxisu", "0", 1 },
86 { "joy_advaxisv", "0", 1 },
89 cvar_t joy_invert[] = {
90 { "joy_invertx", "0", 1 },
91 { "joy_inverty", "0", 1 },
92 { "joy_invertz", "0", 1 },
93 { "joy_invertr", "0", 1 },
94 { "joy_invertu", "0", 1 },
95 { "joy_invertv", "0", 1 },
99 void joy_button_handler(SDL_JoyButtonEvent *jbe)
103 button = SDL_Joysticks[jbe->which].button_map[jbe->button];
105 vkey_handler(KEY_JB1 + button, jbe->state == SDL_PRESSED);
108 void joy_hat_handler(SDL_JoyHatEvent *jhe)
110 int hat = SDL_Joysticks[jhe->which].hat_map[jhe->hat];
111 int state_up = (jhe->value & SDL_HAT_UP ) != 0;
112 int state_right = (jhe->value & SDL_HAT_RIGHT) != 0;
113 int state_down = (jhe->value & SDL_HAT_DOWN ) != 0;
114 int state_left = (jhe->value & SDL_HAT_LEFT ) != 0;
115 int old_state_up = keyd_pressed[KEY_JB1 + hat + 0];
116 int old_state_right = keyd_pressed[KEY_JB1 + hat + 1];
117 int old_state_down = keyd_pressed[KEY_JB1 + hat + 2];
118 int old_state_left = keyd_pressed[KEY_JB1 + hat + 3];
120 if (state_up != old_state_up ) vkey_handler(KEY_JB1 + hat + 0, state_up );
121 if (state_right != old_state_right) vkey_handler(KEY_JB1 + hat + 1, state_right);
122 if (state_down != old_state_down ) vkey_handler(KEY_JB1 + hat + 2, state_down );
123 if (state_left != old_state_left ) vkey_handler(KEY_JB1 + hat + 3, state_left );
126 void joy_axis_handler(SDL_JoyAxisEvent *jae)
130 axis = SDL_Joysticks[jae->which].axis_map[jae->axis];
132 Joystick.axes[axis].value = jae->value;
136 /* ----------------------------------------------- */
143 if (SDL_Init(SDL_INIT_JOYSTICK) < 0) {
144 con_printf(CON_VERBOSE, "sdl-joystick: initialisation failed: %s.",SDL_GetError());
148 memset(&Joystick,0,sizeof(Joystick));
149 memset(joyaxis_text, 0, JOY_MAX_AXES * sizeof(char *));
151 for (i = 0; i < 6; i++) {
152 cvar_registervariable(&joy_advaxes[i]);
153 cvar_registervariable(&joy_invert[i]);
156 n = SDL_NumJoysticks();
158 con_printf(CON_VERBOSE, "sdl-joystick: found %d joysticks\n", n);
159 for (i = 0; i < n; i++) {
160 con_printf(CON_VERBOSE, "sdl-joystick %d: %s\n", i, SDL_JoystickName(i));
161 SDL_Joysticks[num_joysticks].handle = SDL_JoystickOpen(i);
162 if (SDL_Joysticks[num_joysticks].handle) {
165 SDL_Joysticks[num_joysticks].n_axes
166 = SDL_JoystickNumAxes(SDL_Joysticks[num_joysticks].handle);
167 if(SDL_Joysticks[num_joysticks].n_axes > MAX_AXES_PER_JOYSTICK)
169 Warning("sdl-joystick: found %d axes, only %d supported. Game may be unstable.\n", SDL_Joysticks[num_joysticks].n_axes, MAX_AXES_PER_JOYSTICK);
170 SDL_Joysticks[num_joysticks].n_axes = MAX_AXES_PER_JOYSTICK;
173 SDL_Joysticks[num_joysticks].n_buttons
174 = SDL_JoystickNumButtons(SDL_Joysticks[num_joysticks].handle);
175 if(SDL_Joysticks[num_joysticks].n_buttons > MAX_BUTTONS_PER_JOYSTICK)
177 Warning("sdl-joystick: found %d buttons, only %d supported. Game may be unstable.\n", SDL_Joysticks[num_joysticks].n_buttons, MAX_BUTTONS_PER_JOYSTICK);
178 SDL_Joysticks[num_joysticks].n_buttons = MAX_BUTTONS_PER_JOYSTICK;
181 SDL_Joysticks[num_joysticks].n_hats
182 = SDL_JoystickNumHats(SDL_Joysticks[num_joysticks].handle);
183 if(SDL_Joysticks[num_joysticks].n_hats > MAX_HATS_PER_JOYSTICK)
185 Warning("sdl-joystick: found %d hats, only %d supported. Game may be unstable.\n", SDL_Joysticks[num_joysticks].n_hats, MAX_HATS_PER_JOYSTICK);
186 SDL_Joysticks[num_joysticks].n_hats = MAX_HATS_PER_JOYSTICK;
189 con_printf(CON_VERBOSE, "sdl-joystick: %d axes\n", SDL_Joysticks[num_joysticks].n_axes);
190 con_printf(CON_VERBOSE, "sdl-joystick: %d buttons\n", SDL_Joysticks[num_joysticks].n_buttons);
191 con_printf(CON_VERBOSE, "sdl-joystick: %d hats\n", SDL_Joysticks[num_joysticks].n_hats);
193 for (j=0; j < SDL_Joysticks[num_joysticks].n_axes; j++)
195 sprintf(temp, "J%d A%d", i + 1, j + 1);
196 joyaxis_text[Joystick.n_axes] = d_strdup(temp);
197 SDL_Joysticks[num_joysticks].axis_map[j] = Joystick.n_axes++;
199 for (j=0; j < SDL_Joysticks[num_joysticks].n_buttons; j++)
201 sprintf(temp, "J%dB%d", i + 1, j + 1);
202 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
203 SDL_Joysticks[num_joysticks].button_map[j] = Joystick.n_buttons++;
205 for (j=0; j < SDL_Joysticks[num_joysticks].n_hats; j++)
207 SDL_Joysticks[num_joysticks].hat_map[j] = Joystick.n_buttons;
208 //a hat counts as four buttons
210 sprintf(temp, "J%dH%dUP", i + 1, j + 1);
211 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
212 Joystick.n_buttons++;
214 sprintf(temp, "J%dH%dRIGHT", i + 1, j + 1);
215 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
216 Joystick.n_buttons++;
218 sprintf(temp, "J%dH%dDOWN", i + 1, j + 1);
219 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
220 Joystick.n_buttons++;
222 sprintf(temp, "J%dH%dLEFT", i + 1, j + 1);
223 key_text[KEY_JB1 + Joystick.n_buttons] = d_strdup(temp);
224 Joystick.n_buttons++;
230 con_printf(CON_VERBOSE, "sdl-joystick: initialization failed!\n");
232 con_printf(CON_VERBOSE, "sdl-joystick: %d axes (total)\n", Joystick.n_axes);
233 con_printf(CON_VERBOSE, "sdl-joystick: %d buttons (total)\n", Joystick.n_buttons);
236 joy_num_axes = Joystick.n_axes;
244 while (num_joysticks)
245 SDL_JoystickClose(SDL_Joysticks[--num_joysticks].handle);
246 while (Joystick.n_axes--)
247 d_free(joyaxis_text[Joystick.n_axes]);
248 while (Joystick.n_buttons--)
249 d_free(key_text[KEY_JB1 + Joystick.n_buttons]);
252 void joy_get_pos(int *x, int *y)
254 int axis[JOY_MAX_AXES];
256 if (!num_joysticks) {
261 joystick_read_raw_axis (JOY_ALL_AXIS, axis);
263 *x = joy_get_scaled_reading( axis[0], 0 );
264 *y = joy_get_scaled_reading( axis[1], 1 );
269 #if 0 // This is never used?
271 for (i=0; i++; i<buttons) {
272 switch (keyd_pressed[KEY_JB1 + i]) {
287 ubyte joystick_read_raw_axis( ubyte mask, int * axis )
290 ubyte channel_masks = 0;
297 for (i = 0; i < Joystick.n_axes; i++)
299 if ((axis[i] = Joystick.axes[i].value))
300 channel_masks |= 1 << i;
303 return channel_masks;
312 int joy_get_button_state( int btn )
317 if(btn >= Joystick.n_buttons)
322 return keyd_pressed[KEY_JB1 + btn];
325 void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max)
329 for (i = 0; i < Joystick.n_axes; i++)
331 axis_center[i] = Joystick.axes[i].center_val;
332 axis_min[i] = Joystick.axes[i].min_val;
333 axis_max[i] = Joystick.axes[i].max_val;
337 void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max)
341 for (i = 0; i < Joystick.n_axes; i++)
343 Joystick.axes[i].center_val = axis_center[i];
344 Joystick.axes[i].min_val = axis_min[i];
345 Joystick.axes[i].max_val = axis_max[i];
349 int joy_get_scaled_reading( int raw, int axis_num )
356 raw -= Joystick.axes[axis_num].center_val;
359 d = Joystick.axes[axis_num].center_val - Joystick.axes[axis_num].min_val;
361 d = Joystick.axes[axis_num].max_val - Joystick.axes[axis_num].center_val;
366 x = ((raw << 7) / d);
375 d = (joy_deadzone) * 6;
376 if ((x > (-1*d)) && (x < d))
383 void joy_set_slow_reading( int flag )