00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "../client.h"
00027 #include "cl_input.h"
00028 #include "cl_joystick.h"
00029 #include "../ui/ui_main.h"
00030 #include "../ui/ui_nodes.h"
00031 #include "../ui/node/ui_node_abstractoption.h"
00032
00033 static SDL_Joystick *stick = NULL;
00034 static cvar_t *in_joystick;
00035 static cvar_t *in_joystickNo;
00036 static cvar_t *in_joystickThreshold;
00037 static cvar_t *in_joystickSpeed;
00038
00039 static struct {
00040 qboolean buttons[16];
00041 unsigned int oldaxes;
00042 unsigned int oldhats;
00043 } stick_state;
00044
00045
00046 static const int joy_keys[16] = {
00047 K_LEFTARROW, K_RIGHTARROW,
00048 K_UPARROW, K_DOWNARROW,
00049 K_JOY16, K_JOY17,
00050 K_JOY18, K_JOY19,
00051 K_JOY20, K_JOY21,
00052 K_JOY22, K_JOY23,
00053
00054 K_JOY24, K_JOY25,
00055 K_JOY26, K_JOY27
00056 };
00057
00058
00059
00060 static const int hat_keys[16] = {
00061 K_JOY29, K_JOY30,
00062 K_JOY31, K_JOY32,
00063 K_JOY25, K_JOY26,
00064 K_JOY27, K_JOY28,
00065 K_JOY21, K_JOY22,
00066 K_JOY23, K_JOY24,
00067 K_JOY17, K_JOY18,
00068 K_JOY19, K_JOY20
00069 };
00070
00071 void IN_JoystickMove (void)
00072 {
00073 qboolean joy_pressed[lengthof(joy_keys)];
00074 unsigned int axes = 0;
00075 unsigned int hats = 0;
00076 int total = 0;
00077 int i = 0;
00078
00079
00080 if (in_joystickNo->modified)
00081 IN_StartupJoystick();
00082
00083 if (!in_joystick->integer)
00084 return;
00085
00086 if (!stick)
00087 return;
00088
00089 SDL_JoystickUpdate();
00090
00091 memset(joy_pressed, '\0', sizeof(joy_pressed));
00092
00093
00094 total = SDL_JoystickNumBalls(stick);
00095 if (total > 0) {
00096 int balldx = 0;
00097 int balldy = 0;
00098 for (i = 0; i < total; i++) {
00099 int dx = 0;
00100 int dy = 0;
00101 SDL_JoystickGetBall(stick, i, &dx, &dy);
00102 balldx += dx;
00103 balldy += dy;
00104 }
00105 if (balldx || balldy) {
00106 mousePosX = balldx / viddef.rx;
00107 mousePosY = balldy / viddef.ry;
00108 }
00109 }
00110
00111
00112 total = SDL_JoystickNumButtons(stick);
00113 if (total > 0) {
00114 if (total > lengthof(stick_state.buttons))
00115 total = lengthof(stick_state.buttons);
00116 for (i = 0; i < total; i++) {
00117 const qboolean pressed = (SDL_JoystickGetButton(stick, i) != 0);
00118 if (pressed != stick_state.buttons[i]) {
00119 IN_EventEnqueue(K_JOY1 + i, 0, pressed);
00120 stick_state.buttons[i] = pressed;
00121 }
00122 }
00123 }
00124
00125
00126 total = SDL_JoystickNumHats(stick);
00127 if (total > 0) {
00128 if (total > 4)
00129 total = 4;
00130 for (i = 0; i < total; i++)
00131 ((Uint8 *)&hats)[i] = SDL_JoystickGetHat(stick, i);
00132 }
00133
00134
00135 if (hats != stick_state.oldhats) {
00136 for (i = 0; i < 4; i++) {
00137 if (((Uint8 *)&hats)[i] != ((Uint8 *)&stick_state.oldhats)[i]) {
00138
00139 switch (((Uint8 *)&stick_state.oldhats)[i]) {
00140 case SDL_HAT_UP:
00141 IN_EventEnqueue(hat_keys[4 * i + 0], 0, qfalse);
00142 break;
00143 case SDL_HAT_RIGHT:
00144 IN_EventEnqueue(hat_keys[4 * i + 1], 0, qfalse);
00145 break;
00146 case SDL_HAT_DOWN:
00147 IN_EventEnqueue(hat_keys[4 * i + 2], 0, qfalse);
00148 break;
00149 case SDL_HAT_LEFT:
00150 IN_EventEnqueue(hat_keys[4 * i + 3], 0, qfalse);
00151 break;
00152 case SDL_HAT_RIGHTUP:
00153 IN_EventEnqueue(hat_keys[4 * i + 0], 0, qfalse);
00154 IN_EventEnqueue(hat_keys[4 * i + 1], 0, qfalse);
00155 break;
00156 case SDL_HAT_RIGHTDOWN:
00157 IN_EventEnqueue(hat_keys[4 * i + 2], 0, qfalse);
00158 IN_EventEnqueue(hat_keys[4 * i + 1], 0, qfalse);
00159 break;
00160 case SDL_HAT_LEFTUP:
00161 IN_EventEnqueue(hat_keys[4 * i + 0], 0, qfalse);
00162 IN_EventEnqueue(hat_keys[4 * i + 3], 0, qfalse);
00163 break;
00164 case SDL_HAT_LEFTDOWN:
00165 IN_EventEnqueue(hat_keys[4 * i + 2], 0, qfalse);
00166 IN_EventEnqueue(hat_keys[4 * i + 3], 0, qfalse);
00167 break;
00168 default:
00169 break;
00170 }
00171
00172 switch (((Uint8 *)&hats)[i]) {
00173 case SDL_HAT_UP:
00174 IN_EventEnqueue(hat_keys[4 * i + 0], 0, qtrue);
00175 break;
00176 case SDL_HAT_RIGHT:
00177 IN_EventEnqueue(hat_keys[4 * i + 1], 0, qtrue);
00178 break;
00179 case SDL_HAT_DOWN:
00180 IN_EventEnqueue(hat_keys[4 * i + 2], 0, qtrue);
00181 break;
00182 case SDL_HAT_LEFT:
00183 IN_EventEnqueue(hat_keys[4 * i + 3], 0, qtrue);
00184 break;
00185 case SDL_HAT_RIGHTUP:
00186 IN_EventEnqueue(hat_keys[4 * i + 0], 0, qtrue);
00187 IN_EventEnqueue(hat_keys[4 * i + 1], 0, qtrue);
00188 break;
00189 case SDL_HAT_RIGHTDOWN:
00190 IN_EventEnqueue(hat_keys[4 * i + 2], 0, qtrue);
00191 IN_EventEnqueue(hat_keys[4 * i + 1], 0, qtrue);
00192 break;
00193 case SDL_HAT_LEFTUP:
00194 IN_EventEnqueue(hat_keys[4 * i + 0], 0, qtrue);
00195 IN_EventEnqueue(hat_keys[4 * i + 3], 0, qtrue);
00196 break;
00197 case SDL_HAT_LEFTDOWN:
00198 IN_EventEnqueue(hat_keys[4 * i + 2], 0, qtrue);
00199 IN_EventEnqueue(hat_keys[4 * i + 3], 0, qtrue);
00200 break;
00201 default:
00202 break;
00203 }
00204 }
00205 }
00206 }
00207
00208
00209 stick_state.oldhats = hats;
00210
00211
00212 total = SDL_JoystickNumAxes(stick);
00213 if (total >= 2) {
00214
00215 for (i = 0; i < 2; i++) {
00216 const Sint16 axis = SDL_JoystickGetAxis(stick, i);
00217 const float velocity = ((float) axis) / 32767.0f;
00218 if (velocity > -in_joystickThreshold->value && velocity < in_joystickThreshold->value)
00219 continue;
00220
00221 if (i & 1) {
00222 mousePosY += in_joystickSpeed->value * velocity;
00223 if (mousePosY > (int)viddef.height)
00224 mousePosY = (int)viddef.height;
00225 else if (mousePosY < 0)
00226 mousePosY = 0;
00227 } else {
00228 mousePosX += in_joystickSpeed->value * velocity;
00229 if (mousePosX > (int)viddef.width)
00230 mousePosX = (int)viddef.width;
00231 else if (mousePosX < 0)
00232 mousePosX = 0;
00233 }
00234 }
00235 }
00236
00237
00238 if (total > 2) {
00239 if (total > 16)
00240 total = 16;
00241
00242 for (i = 2; i < total; i++) {
00243 const Sint16 axis = SDL_JoystickGetAxis(stick, i);
00244 const float f = ((float) axis) / 32767.0f;
00245 if (f < -in_joystickThreshold->value) {
00246 axes |= (1 << (i * 2));
00247 } else if (f > in_joystickThreshold->value) {
00248 axes |= (1 << ((i * 2) + 1));
00249 }
00250 }
00251 }
00252
00253
00254
00255 if (axes != stick_state.oldaxes) {
00256 for (i = 2; i < 16; i++) {
00257 if ((axes & (1 << i)) && !(stick_state.oldaxes & (1 << i)))
00258 IN_EventEnqueue(joy_keys[i], 0, qtrue);
00259
00260 if (!(axes & (1 << i)) && (stick_state.oldaxes & (1 << i)))
00261 IN_EventEnqueue(joy_keys[i], 0, qfalse);
00262 }
00263 }
00264
00265
00266 stick_state.oldaxes = axes;
00267 }
00268
00272 void IN_JoystickInitMenu (void)
00273 {
00274 uiNode_t* joystickOptions = NULL;
00275 const int total = SDL_NumJoysticks();
00276
00277 if (total == 0) {
00278 UI_AddOption(&joystickOptions, "", _("None"), "0");
00279 } else {
00280 int i;
00281 for (i = 0; i < total; i++)
00282 UI_AddOption(&joystickOptions, "", SDL_JoystickName(i), va("%i", i));
00283 }
00284 UI_RegisterOption(OPTION_JOYSTICKS, joystickOptions);
00285 }
00286
00290 void IN_StartupJoystick (void)
00291 {
00292 int i = 0;
00293 int total = 0;
00294
00295 in_joystick = Cvar_Get("in_joystick", "0", CVAR_ARCHIVE, "Activate or deactivate the use of a joystick");
00296 in_joystickNo = Cvar_Get("in_joystickNo", "0", CVAR_ARCHIVE, "Joystick to use - 0 is the first - 1 is the second ...");
00297 in_joystickThreshold = Cvar_Get("in_joystickThreshold", "0.05", CVAR_ARCHIVE, "The threshold for the joystick axes");
00298 in_joystickSpeed = Cvar_Get("in_joystickSpeed", "20", CVAR_ARCHIVE, "The joystick speed for the cursor");
00299
00300 if (stick != NULL) {
00301 Com_Printf("... closing already initialized joystick\n");
00302 SDL_JoystickClose(stick);
00303 }
00304
00305 stick = NULL;
00306 memset(&stick_state, '\0', sizeof(stick_state));
00307
00308 if (!SDL_WasInit(SDL_INIT_JOYSTICK)) {
00309 Com_DPrintf(DEBUG_CLIENT, "Calling SDL_Init(SDL_INIT_JOYSTICK)...\n");
00310 if (SDL_Init(SDL_INIT_JOYSTICK) == -1) {
00311 Com_DPrintf(DEBUG_CLIENT, "SDL_Init(SDL_INIT_JOYSTICK) failed: %s\n", SDL_GetError());
00312 return;
00313 }
00314 Com_DPrintf(DEBUG_CLIENT, "SDL_Init(SDL_INIT_JOYSTICK) passed.\n");
00315 }
00316
00317 total = SDL_NumJoysticks();
00318 Com_Printf("%d possible joysticks\n", total);
00319 for (i = 0; i < total; i++)
00320 Com_DPrintf(DEBUG_CLIENT, "[%d] %s\n", i, SDL_JoystickName(i));
00321
00322 if (in_joystickNo->integer < 0 || in_joystickNo->integer >= total)
00323 Cvar_Set("in_joystickNo", "0");
00324 in_joystickNo->modified = qfalse;
00325
00326 stick = SDL_JoystickOpen(in_joystickNo->integer);
00327
00328 if (stick == NULL) {
00329 Com_Printf("no joystick found.\n");
00330 return;
00331 }
00332
00333 Com_Printf("joystick %d opened - set cvar in_joystickNo to change this\n", in_joystickNo->integer);
00334 Com_Printf("... name: %s\n", SDL_JoystickName(in_joystickNo->integer));
00335 Com_Printf("... axes: %d\n", SDL_JoystickNumAxes(stick));
00336 Com_Printf("... hats: %d\n", SDL_JoystickNumHats(stick));
00337 Com_Printf("... buttons: %d\n", SDL_JoystickNumButtons(stick));
00338 Com_Printf("... balls: %d\n", SDL_JoystickNumBalls(stick));
00339
00340 SDL_JoystickEventState(SDL_QUERY);
00341 }
00342