/** * Simulate press of a key with a command. */ static void CL_PressKey_f (void) { unsigned int keyNum; if (Cmd_Argc() != 2) { Com_Printf("Usage: %s <key> : simulate press of a key\n", Cmd_Argv(0)); return; } keyNum = Key_StringToKeynum(Cmd_Argv(1)); /* @todo unicode value is wrong */ IN_EventEnqueue(keyNum, '?', qtrue); IN_EventEnqueue(keyNum, '?', qfalse); }
void IN_JoystickMove (void) { bool joy_pressed[lengthof(joy_keys)]; unsigned int axes = 0; unsigned int hats = 0; int total = 0; int i = 0; /* check whether a user has changed the joystick number */ if (in_joystickNo->modified) IN_StartupJoystick(); /* check whether joysticks are disabled */ if (!in_joystick->integer) return; if (!stick) return; SDL_JoystickUpdate(); OBJZERO(joy_pressed); /* update the ball state */ total = SDL_JoystickNumBalls(stick); if (total > 0) { int balldx = 0; int balldy = 0; for (i = 0; i < total; i++) { int dx = 0; int dy = 0; SDL_JoystickGetBall(stick, i, &dx, &dy); balldx += dx; balldy += dy; } if (balldx || balldy) { mousePosX = balldx / viddef.rx; mousePosY = balldy / viddef.ry; } } /* now query the stick buttons... */ total = SDL_JoystickNumButtons(stick); if (total > 0) { if (total > lengthof(stick_state.buttons)) total = lengthof(stick_state.buttons); for (i = 0; i < total; i++) { const bool pressed = (SDL_JoystickGetButton(stick, i) != 0); if (pressed != stick_state.buttons[i]) { IN_EventEnqueue(K_JOY1 + i, 0, pressed); stick_state.buttons[i] = pressed; } } } /* look at the hats... */ total = SDL_JoystickNumHats(stick); if (total > 0) { if (total > 4) total = 4; for (i = 0; i < total; i++) ((Uint8 *)&hats)[i] = SDL_JoystickGetHat(stick, i); } /* update hat state */ if (hats != stick_state.oldhats) { for (i = 0; i < 4; i++) { if (((Uint8 *)&hats)[i] != ((Uint8 *)&stick_state.oldhats)[i]) { /* release event */ switch (((Uint8 *)&stick_state.oldhats)[i]) { case SDL_HAT_UP: IN_EventEnqueue(hat_keys[4 * i + 0], 0, false); break; case SDL_HAT_RIGHT: IN_EventEnqueue(hat_keys[4 * i + 1], 0, false); break; case SDL_HAT_DOWN: IN_EventEnqueue(hat_keys[4 * i + 2], 0, false); break; case SDL_HAT_LEFT: IN_EventEnqueue(hat_keys[4 * i + 3], 0, false); break; case SDL_HAT_RIGHTUP: IN_EventEnqueue(hat_keys[4 * i + 0], 0, false); IN_EventEnqueue(hat_keys[4 * i + 1], 0, false); break; case SDL_HAT_RIGHTDOWN: IN_EventEnqueue(hat_keys[4 * i + 2], 0, false); IN_EventEnqueue(hat_keys[4 * i + 1], 0, false); break; case SDL_HAT_LEFTUP: IN_EventEnqueue(hat_keys[4 * i + 0], 0, false); IN_EventEnqueue(hat_keys[4 * i + 3], 0, false); break; case SDL_HAT_LEFTDOWN: IN_EventEnqueue(hat_keys[4 * i + 2], 0, false); IN_EventEnqueue(hat_keys[4 * i + 3], 0, false); break; default: break; } /* press event */ switch (((Uint8 *)&hats)[i]) { case SDL_HAT_UP: IN_EventEnqueue(hat_keys[4 * i + 0], 0, true); break; case SDL_HAT_RIGHT: IN_EventEnqueue(hat_keys[4 * i + 1], 0, true); break; case SDL_HAT_DOWN: IN_EventEnqueue(hat_keys[4 * i + 2], 0, true); break; case SDL_HAT_LEFT: IN_EventEnqueue(hat_keys[4 * i + 3], 0, true); break; case SDL_HAT_RIGHTUP: IN_EventEnqueue(hat_keys[4 * i + 0], 0, true); IN_EventEnqueue(hat_keys[4 * i + 1], 0, true); break; case SDL_HAT_RIGHTDOWN: IN_EventEnqueue(hat_keys[4 * i + 2], 0, true); IN_EventEnqueue(hat_keys[4 * i + 1], 0, true); break; case SDL_HAT_LEFTUP: IN_EventEnqueue(hat_keys[4 * i + 0], 0, true); IN_EventEnqueue(hat_keys[4 * i + 3], 0, true); break; case SDL_HAT_LEFTDOWN: IN_EventEnqueue(hat_keys[4 * i + 2], 0, true); IN_EventEnqueue(hat_keys[4 * i + 3], 0, true); break; default: break; } } } } /* save hat state */ stick_state.oldhats = hats; /* finally, look at the axes... */ total = SDL_JoystickNumAxes(stick); if (total >= 2) { /* the first two axes are used for the cursor movement */ for (i = 0; i < 2; i++) { const Sint16 axis = SDL_JoystickGetAxis(stick, i); const float velocity = ((float) axis) / 32767.0f; if (velocity > -in_joystickThreshold->value && velocity < in_joystickThreshold->value) continue; if (i & 1) { mousePosY += in_joystickSpeed->value * velocity; if (mousePosY > (int)viddef.context.height) mousePosY = (int)viddef.context.height; else if (mousePosY < 0) mousePosY = 0; } else { mousePosX += in_joystickSpeed->value * velocity; if (mousePosX > (int)viddef.context.width) mousePosX = (int)viddef.context.width; else if (mousePosX < 0) mousePosX = 0; } } } if (total > 2) { if (total > 16) total = 16; /* every axis except the first two can be normally bound to an action */ for (i = 2; i < total; i++) { const Sint16 axis = SDL_JoystickGetAxis(stick, i); const float f = ((float) axis) / 32767.0f; if (f < -in_joystickThreshold->value) { axes |= (1 << (i * 2)); } else if (f > in_joystickThreshold->value) { axes |= (1 << ((i * 2) + 1)); } } } /* Time to update axes state based on old vs. new. */ if (axes != stick_state.oldaxes) { for (i = 2; i < 16; i++) { if ((axes & (1 << i)) && !(stick_state.oldaxes & (1 << i))) IN_EventEnqueue(joy_keys[i], 0, true); if (!(axes & (1 << i)) && (stick_state.oldaxes & (1 << i))) IN_EventEnqueue(joy_keys[i], 0, false); } } /* Save for future generations. */ stick_state.oldaxes = axes; }
/** * @brief Handle input events like keys presses and joystick movement as well * as window events * @sa CL_Frame * @sa IN_Parse * @sa IN_JoystickMove */ void IN_Frame (void) { int mouse_buttonstate; unsigned short unicode; unsigned int key; SDL_Event event; IN_Parse(); IN_JoystickMove(); if (vid_grabmouse->modified) { vid_grabmouse->modified = qfalse; if (!vid_grabmouse->integer) { /* ungrab the pointer */ Com_Printf("Switch grab input off\n"); SDL_WM_GrabInput(SDL_GRAB_OFF); /* don't allow grabbing the input in fullscreen mode */ } else if (!vid_fullscreen->integer) { /* grab the pointer */ Com_Printf("Switch grab input on\n"); SDL_WM_GrabInput(SDL_GRAB_ON); } else { Com_Printf("No input grabbing in fullscreen mode\n"); Cvar_SetValue("vid_grabmouse", 0); } } oldMousePosX = mousePosX; oldMousePosY = mousePosY; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: switch (event.button.button) { case SDL_BUTTON_LEFT: mouse_buttonstate = K_MOUSE1; break; case SDL_BUTTON_MIDDLE: mouse_buttonstate = K_MOUSE3; break; case SDL_BUTTON_RIGHT: mouse_buttonstate = K_MOUSE2; break; case SDL_BUTTON_WHEELUP: mouse_buttonstate = K_MWHEELUP; break; case SDL_BUTTON_WHEELDOWN: mouse_buttonstate = K_MWHEELDOWN; break; case 6: mouse_buttonstate = K_MOUSE4; break; case 7: mouse_buttonstate = K_MOUSE5; break; default: mouse_buttonstate = K_AUX1 + (event.button.button - 8) % 16; break; } IN_EventEnqueue(mouse_buttonstate, 0, (event.type == SDL_MOUSEBUTTONDOWN)); break; case SDL_MOUSEMOTION: SDL_GetMouseState(&mousePosX, &mousePosY); mousePosX /= viddef.rx; mousePosY /= viddef.ry; break; case SDL_KEYDOWN: IN_PrintKey(&event, 1); #ifndef _WIN32 if ((event.key.keysym.mod & KMOD_ALT) && event.key.keysym.sym == SDLK_RETURN) { SDL_Surface *surface = SDL_GetVideoSurface(); if (!SDL_WM_ToggleFullScreen(surface)) { int flags = surface->flags ^= SDL_FULLSCREEN; SDL_SetVideoMode(surface->w, surface->h, 0, flags); } if (surface->flags & SDL_FULLSCREEN) { Cvar_SetValue("vid_fullscreen", 1); /* make sure, that input grab is deactivated in fullscreen mode */ Cvar_SetValue("vid_grabmouse", 0); } else { Cvar_SetValue("vid_fullscreen", 0); } vid_fullscreen->modified = qfalse; /* we just changed it with SDL. */ break; /* ignore this key */ } #endif if ((event.key.keysym.mod & KMOD_CTRL) && event.key.keysym.sym == SDLK_g) { SDL_GrabMode gm = SDL_WM_GrabInput(SDL_GRAB_QUERY); Cvar_SetValue("vid_grabmouse", (gm == SDL_GRAB_ON) ? 0 : 1); break; /* ignore this key */ } /* console key is hardcoded, so the user can never unbind it */ if ((event.key.keysym.mod & KMOD_SHIFT) && event.key.keysym.sym == SDLK_ESCAPE) { Con_ToggleConsole_f(); break; } IN_TranslateKey(&event.key.keysym, &key, &unicode); IN_EventEnqueue(key, unicode, qtrue); break; case SDL_VIDEOEXPOSE: break; case SDL_KEYUP: IN_PrintKey(&event, 0); IN_TranslateKey(&event.key.keysym, &key, &unicode); IN_EventEnqueue(key, unicode, qfalse); break; case SDL_ACTIVEEVENT: /* make sure menu no more capture input when the game window lose the focus */ if (event.active.state == SDL_APPINPUTFOCUS && event.active.gain == 0) UI_ReleaseInput(); break; case SDL_QUIT: Cmd_ExecuteString("quit"); break; case SDL_VIDEORESIZE: /* make sure that SDL_SetVideoMode is called again after we changed the size * otherwise the mouse will make problems */ vid_mode->modified = qtrue; break; } } }