2010-10-19 07:29:20 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2010 Yamagi Burmeister
|
|
|
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or (at
|
|
|
|
* your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
*
|
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* =======================================================================
|
|
|
|
*
|
2014-01-05 17:09:26 +00:00
|
|
|
* This is the Quake II input system backend, implemented with SDL.
|
2010-10-19 07:29:20 +00:00
|
|
|
*
|
|
|
|
* =======================================================================
|
|
|
|
*/
|
2013-04-28 19:33:08 +00:00
|
|
|
|
2013-06-15 07:23:02 +00:00
|
|
|
#include "../../client/refresh/header/local.h"
|
2012-08-01 11:47:32 +00:00
|
|
|
#include "../../client/header/keyboard.h"
|
2012-08-01 14:53:40 +00:00
|
|
|
#include "../generic/header/input.h"
|
2014-06-10 07:43:53 +00:00
|
|
|
#include "../../client/header/client.h"
|
2012-08-01 14:53:40 +00:00
|
|
|
|
2013-11-10 08:46:28 +00:00
|
|
|
/* There's no sdl-config on OS X and Windows */
|
2013-09-01 12:19:33 +00:00
|
|
|
#if defined(_WIN32) || defined(__APPLE__)
|
|
|
|
#ifdef SDL2
|
|
|
|
#include <SDL2/SDL.h>
|
2013-11-10 08:46:28 +00:00
|
|
|
#else /* SDL1.2 */
|
2012-06-04 09:52:07 +00:00
|
|
|
#include <SDL/SDL.h>
|
2013-11-10 08:46:28 +00:00
|
|
|
#endif /*SDL2 */
|
|
|
|
#else /* not _WIN32 || APPLE */
|
2010-10-19 07:29:20 +00:00
|
|
|
#include <SDL.h>
|
2013-11-10 08:46:28 +00:00
|
|
|
#endif /* _WIN32 || APPLE */
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2013-11-10 08:46:28 +00:00
|
|
|
/* SDL 1.2 <-> 2.0 compatiblity cruft */
|
2013-08-25 22:55:31 +00:00
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
|
|
#define SDLK_KP0 SDLK_KP_0
|
|
|
|
#define SDLK_KP1 SDLK_KP_1
|
|
|
|
#define SDLK_KP2 SDLK_KP_2
|
|
|
|
#define SDLK_KP3 SDLK_KP_3
|
|
|
|
#define SDLK_KP4 SDLK_KP_4
|
|
|
|
#define SDLK_KP5 SDLK_KP_5
|
|
|
|
#define SDLK_KP6 SDLK_KP_6
|
|
|
|
#define SDLK_KP7 SDLK_KP_7
|
|
|
|
#define SDLK_KP8 SDLK_KP_8
|
|
|
|
#define SDLK_KP9 SDLK_KP_9
|
|
|
|
|
|
|
|
#define SDLK_RMETA SDLK_RGUI
|
|
|
|
#define SDLK_LMETA SDLK_LGUI
|
|
|
|
|
2013-11-10 08:46:28 +00:00
|
|
|
#define SDLK_COMPOSE SDLK_APPLICATION
|
2013-08-25 22:55:31 +00:00
|
|
|
|
|
|
|
#define SDLK_PRINT SDLK_PRINTSCREEN
|
|
|
|
#define SDLK_SCROLLOCK SDLK_SCROLLLOCK
|
|
|
|
#define SDLK_NUMLOCK SDLK_NUMLOCKCLEAR
|
|
|
|
#endif
|
|
|
|
|
2010-10-19 08:25:47 +00:00
|
|
|
#define MOUSE_MAX 3000
|
|
|
|
#define MOUSE_MIN 40
|
2013-11-10 08:46:28 +00:00
|
|
|
|
|
|
|
/* Globals */
|
|
|
|
static int mouse_x, mouse_y;
|
|
|
|
static int old_mouse_x, old_mouse_y;
|
|
|
|
static qboolean have_grab;
|
|
|
|
static qboolean mlooking;
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2014-01-25 10:45:08 +00:00
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
|
|
qboolean in_relativemode;
|
|
|
|
#endif
|
|
|
|
|
2013-11-10 08:46:28 +00:00
|
|
|
/* CVars */
|
|
|
|
cvar_t *vid_fullscreen;
|
|
|
|
static cvar_t *in_grab;
|
|
|
|
static cvar_t *in_mouse;
|
|
|
|
static cvar_t *exponential_speedup;
|
2014-06-13 12:43:34 +00:00
|
|
|
cvar_t *freelook;
|
|
|
|
cvar_t *lookstrafe;
|
|
|
|
cvar_t *m_forward;
|
2013-11-10 08:46:28 +00:00
|
|
|
static cvar_t *m_filter;
|
2014-06-13 12:43:34 +00:00
|
|
|
cvar_t *m_pitch;
|
|
|
|
cvar_t *m_side;
|
|
|
|
cvar_t *m_yaw;
|
|
|
|
cvar_t *sensitivity;
|
2013-11-10 08:46:28 +00:00
|
|
|
static cvar_t *windowed_mouse;
|
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* ------------------------------------------------------------------ */
|
2012-11-13 21:37:17 +00:00
|
|
|
|
2010-10-19 08:25:47 +00:00
|
|
|
/*
|
2013-11-10 08:46:28 +00:00
|
|
|
* This creepy function translates the SDL
|
|
|
|
* keycodes to the internal key representation
|
|
|
|
* of the id Tech 2 engine.
|
2010-10-19 08:25:47 +00:00
|
|
|
*/
|
2013-11-10 08:46:28 +00:00
|
|
|
static int
|
2010-10-19 08:25:47 +00:00
|
|
|
IN_TranslateSDLtoQ2Key(unsigned int keysym)
|
2010-10-19 07:29:20 +00:00
|
|
|
{
|
2012-06-08 10:23:01 +00:00
|
|
|
int key = 0;
|
|
|
|
|
|
|
|
if ((keysym >= SDLK_SPACE) && (keysym < SDLK_DELETE))
|
|
|
|
{
|
2013-04-28 19:33:08 +00:00
|
|
|
/* These happen to match
|
2012-06-08 10:23:01 +00:00
|
|
|
the ASCII chars */
|
|
|
|
key = (int)keysym;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (keysym)
|
|
|
|
{
|
|
|
|
case SDLK_PAGEUP:
|
|
|
|
key = K_PGUP;
|
|
|
|
break;
|
|
|
|
case SDLK_KP9:
|
|
|
|
key = K_KP_PGUP;
|
|
|
|
break;
|
|
|
|
case SDLK_PAGEDOWN:
|
|
|
|
key = K_PGDN;
|
|
|
|
break;
|
|
|
|
case SDLK_KP3:
|
|
|
|
key = K_KP_PGDN;
|
|
|
|
break;
|
|
|
|
case SDLK_KP7:
|
|
|
|
key = K_KP_HOME;
|
|
|
|
break;
|
|
|
|
case SDLK_HOME:
|
|
|
|
key = K_HOME;
|
|
|
|
break;
|
|
|
|
case SDLK_KP1:
|
|
|
|
key = K_KP_END;
|
|
|
|
break;
|
|
|
|
case SDLK_END:
|
|
|
|
key = K_END;
|
|
|
|
break;
|
|
|
|
case SDLK_KP4:
|
|
|
|
key = K_KP_LEFTARROW;
|
|
|
|
break;
|
|
|
|
case SDLK_LEFT:
|
|
|
|
key = K_LEFTARROW;
|
|
|
|
break;
|
|
|
|
case SDLK_KP6:
|
|
|
|
key = K_KP_RIGHTARROW;
|
|
|
|
break;
|
|
|
|
case SDLK_RIGHT:
|
|
|
|
key = K_RIGHTARROW;
|
|
|
|
break;
|
|
|
|
case SDLK_KP2:
|
|
|
|
key = K_KP_DOWNARROW;
|
|
|
|
break;
|
|
|
|
case SDLK_DOWN:
|
|
|
|
key = K_DOWNARROW;
|
|
|
|
break;
|
|
|
|
case SDLK_KP8:
|
|
|
|
key = K_KP_UPARROW;
|
|
|
|
break;
|
|
|
|
case SDLK_UP:
|
|
|
|
key = K_UPARROW;
|
|
|
|
break;
|
|
|
|
case SDLK_ESCAPE:
|
2013-03-18 18:37:26 +00:00
|
|
|
key = K_ESCAPE;
|
2012-06-08 10:23:01 +00:00
|
|
|
break;
|
|
|
|
case SDLK_KP_ENTER:
|
|
|
|
key = K_KP_ENTER;
|
|
|
|
break;
|
|
|
|
case SDLK_RETURN:
|
|
|
|
key = K_ENTER;
|
|
|
|
break;
|
|
|
|
case SDLK_TAB:
|
|
|
|
key = K_TAB;
|
|
|
|
break;
|
|
|
|
case SDLK_F1:
|
|
|
|
key = K_F1;
|
|
|
|
break;
|
|
|
|
case SDLK_F2:
|
|
|
|
key = K_F2;
|
|
|
|
break;
|
|
|
|
case SDLK_F3:
|
|
|
|
key = K_F3;
|
|
|
|
break;
|
|
|
|
case SDLK_F4:
|
|
|
|
key = K_F4;
|
|
|
|
break;
|
|
|
|
case SDLK_F5:
|
|
|
|
key = K_F5;
|
|
|
|
break;
|
|
|
|
case SDLK_F6:
|
|
|
|
key = K_F6;
|
|
|
|
break;
|
|
|
|
case SDLK_F7:
|
|
|
|
key = K_F7;
|
|
|
|
break;
|
|
|
|
case SDLK_F8:
|
|
|
|
key = K_F8;
|
|
|
|
break;
|
|
|
|
case SDLK_F9:
|
|
|
|
key = K_F9;
|
|
|
|
break;
|
|
|
|
case SDLK_F10:
|
|
|
|
key = K_F10;
|
|
|
|
break;
|
|
|
|
case SDLK_F11:
|
|
|
|
key = K_F11;
|
|
|
|
break;
|
|
|
|
case SDLK_F12:
|
|
|
|
key = K_F12;
|
|
|
|
break;
|
|
|
|
case SDLK_F13:
|
|
|
|
key = K_F13;
|
|
|
|
break;
|
|
|
|
case SDLK_F14:
|
|
|
|
key = K_F14;
|
|
|
|
break;
|
|
|
|
case SDLK_F15:
|
|
|
|
key = K_F15;
|
|
|
|
break;
|
|
|
|
case SDLK_BACKSPACE:
|
|
|
|
key = K_BACKSPACE;
|
|
|
|
break;
|
|
|
|
case SDLK_KP_PERIOD:
|
|
|
|
key = K_KP_DEL;
|
|
|
|
break;
|
|
|
|
case SDLK_DELETE:
|
|
|
|
key = K_DEL;
|
|
|
|
break;
|
|
|
|
case SDLK_PAUSE:
|
|
|
|
key = K_PAUSE;
|
|
|
|
break;
|
|
|
|
case SDLK_LSHIFT:
|
|
|
|
case SDLK_RSHIFT:
|
|
|
|
key = K_SHIFT;
|
|
|
|
break;
|
|
|
|
case SDLK_LCTRL:
|
|
|
|
case SDLK_RCTRL:
|
|
|
|
key = K_CTRL;
|
|
|
|
break;
|
|
|
|
case SDLK_RMETA:
|
|
|
|
case SDLK_LMETA:
|
|
|
|
key = K_COMMAND;
|
|
|
|
break;
|
|
|
|
case SDLK_RALT:
|
|
|
|
case SDLK_LALT:
|
|
|
|
key = K_ALT;
|
|
|
|
break;
|
|
|
|
case SDLK_KP5:
|
|
|
|
key = K_KP_5;
|
|
|
|
break;
|
|
|
|
case SDLK_INSERT:
|
|
|
|
key = K_INS;
|
|
|
|
break;
|
|
|
|
case SDLK_KP0:
|
|
|
|
key = K_KP_INS;
|
|
|
|
break;
|
|
|
|
case SDLK_KP_MULTIPLY:
|
|
|
|
key = K_KP_STAR;
|
|
|
|
break;
|
|
|
|
case SDLK_KP_PLUS:
|
|
|
|
key = K_KP_PLUS;
|
|
|
|
break;
|
|
|
|
case SDLK_KP_MINUS:
|
|
|
|
key = K_KP_MINUS;
|
|
|
|
break;
|
|
|
|
case SDLK_KP_DIVIDE:
|
|
|
|
key = K_KP_SLASH;
|
|
|
|
break;
|
|
|
|
case SDLK_MODE:
|
|
|
|
key = K_MODE;
|
|
|
|
break;
|
|
|
|
case SDLK_COMPOSE:
|
|
|
|
key = K_COMPOSE;
|
|
|
|
break;
|
|
|
|
case SDLK_HELP:
|
|
|
|
key = K_HELP;
|
|
|
|
break;
|
|
|
|
case SDLK_PRINT:
|
|
|
|
key = K_PRINT;
|
|
|
|
break;
|
|
|
|
case SDLK_SYSREQ:
|
|
|
|
key = K_SYSREQ;
|
|
|
|
break;
|
|
|
|
case SDLK_MENU:
|
|
|
|
key = K_MENU;
|
|
|
|
break;
|
|
|
|
case SDLK_POWER:
|
|
|
|
key = K_POWER;
|
|
|
|
break;
|
|
|
|
case SDLK_UNDO:
|
|
|
|
key = K_UNDO;
|
|
|
|
break;
|
|
|
|
case SDLK_SCROLLOCK:
|
|
|
|
key = K_SCROLLOCK;
|
|
|
|
break;
|
|
|
|
case SDLK_NUMLOCK:
|
|
|
|
key = K_KP_NUMLOCK;
|
|
|
|
break;
|
|
|
|
case SDLK_CAPSLOCK:
|
|
|
|
key = K_CAPSLOCK;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return key;
|
2010-10-19 07:29:20 +00:00
|
|
|
}
|
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* ------------------------------------------------------------------ */
|
2013-08-26 21:55:34 +00:00
|
|
|
|
2010-10-19 08:25:47 +00:00
|
|
|
/*
|
2014-01-05 17:09:26 +00:00
|
|
|
* Updates the input queue state. Called every
|
|
|
|
* frame by the client and does nearly all the
|
|
|
|
* input magic.
|
2010-10-19 08:25:47 +00:00
|
|
|
*/
|
2014-01-05 17:09:26 +00:00
|
|
|
void
|
|
|
|
IN_Update(void)
|
2010-10-19 07:29:20 +00:00
|
|
|
{
|
2014-01-05 17:09:26 +00:00
|
|
|
qboolean want_grab;
|
|
|
|
SDL_Event event;
|
|
|
|
unsigned int key;
|
2013-11-10 08:46:28 +00:00
|
|
|
|
2013-08-25 22:55:31 +00:00
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
2014-01-05 17:09:26 +00:00
|
|
|
SDL_Keymod modstate;
|
2013-08-25 22:55:31 +00:00
|
|
|
#else
|
2014-01-05 17:09:26 +00:00
|
|
|
SDLMod modstate;
|
2013-08-25 22:55:31 +00:00
|
|
|
#endif
|
2014-01-05 17:09:26 +00:00
|
|
|
|
|
|
|
/* Get and process an event */
|
|
|
|
while (SDL_PollEvent(&event))
|
2010-10-19 07:29:20 +00:00
|
|
|
{
|
2014-01-05 17:09:26 +00:00
|
|
|
|
|
|
|
switch (event.type)
|
|
|
|
{
|
|
|
|
/* The mouse wheel */
|
2013-08-26 21:55:34 +00:00
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
2014-01-05 17:09:26 +00:00
|
|
|
case SDL_MOUSEWHEEL:
|
2015-01-16 15:58:46 +00:00
|
|
|
Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), true);
|
|
|
|
Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), false);
|
2013-11-26 18:22:29 +00:00
|
|
|
break;
|
2013-08-26 21:55:34 +00:00
|
|
|
#endif
|
2014-01-05 17:09:26 +00:00
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
|
|
|
if (event.button.button == 4)
|
|
|
|
{
|
2015-01-16 15:58:46 +00:00
|
|
|
Key_Event(K_MWHEELUP, true);
|
|
|
|
Key_Event(K_MWHEELUP, false);
|
2013-11-26 18:22:29 +00:00
|
|
|
break;
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
|
|
|
else if (event.button.button == 5)
|
|
|
|
{
|
2015-01-16 15:58:46 +00:00
|
|
|
Key_Event(K_MWHEELDOWN, true);
|
|
|
|
Key_Event(K_MWHEELDOWN, false);
|
2013-11-26 18:22:29 +00:00
|
|
|
break;
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
|
|
|
#endif
|
2012-06-08 10:23:01 +00:00
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
switch( event.button.button )
|
|
|
|
{
|
|
|
|
case SDL_BUTTON_LEFT:
|
|
|
|
key = K_MOUSE1;
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_MIDDLE:
|
|
|
|
key = K_MOUSE3;
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_RIGHT:
|
|
|
|
key = K_MOUSE2;
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_X1:
|
|
|
|
key = K_MOUSE4;
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_X2:
|
|
|
|
key = K_MOUSE5;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2012-04-29 13:57:33 +00:00
|
|
|
|
2015-01-16 15:58:46 +00:00
|
|
|
Key_Event(key, (event.type == SDL_MOUSEBUTTONDOWN));
|
2013-03-18 18:37:26 +00:00
|
|
|
break;
|
|
|
|
|
2014-03-26 19:34:19 +00:00
|
|
|
case SDL_MOUSEMOTION:
|
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
|
|
/* This is a hack to work around an unsuccessful
|
2015-01-16 15:58:46 +00:00
|
|
|
SDL_SetRelativeMouseMode(). This can happen if
|
|
|
|
some broken security software is blocking raw
|
|
|
|
input (to prevent keyloggers accessing the input
|
|
|
|
queue), or if - on Linux / Unix - XInput2 is not
|
|
|
|
available.
|
|
|
|
|
|
|
|
Since SDL_WarpMouseInWindow() injects a movement
|
|
|
|
event into the queue, we ignore events that move
|
|
|
|
the mouse exactly to the warp position.
|
|
|
|
|
|
|
|
The underlying issue _should_ be solved in SDL
|
|
|
|
2.0.3 an above. */
|
2014-03-26 19:34:19 +00:00
|
|
|
if (have_grab && !in_relativemode)
|
|
|
|
{
|
|
|
|
int center_x = vid.width / 2;
|
|
|
|
int center_y = vid.height / 2;
|
|
|
|
if (event.motion.x == center_x && event.motion.y == center_y)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
SDL_WarpMouseInWindow(NULL, center_x, center_y);
|
|
|
|
}
|
|
|
|
#endif
|
2014-06-10 07:43:53 +00:00
|
|
|
if (cls.key_dest == key_game && (int)cl_paused->value == 0) {
|
|
|
|
mouse_x += event.motion.xrel;
|
|
|
|
mouse_y += event.motion.yrel;
|
|
|
|
}
|
2014-03-26 19:34:19 +00:00
|
|
|
break;
|
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* The user pressed a button */
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
modstate = SDL_GetModState();
|
2012-06-08 10:23:01 +00:00
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* Fullscreen switch via Alt-Return */
|
|
|
|
if ((modstate & KMOD_ALT) && (event.key.keysym.sym == SDLK_RETURN))
|
|
|
|
{
|
|
|
|
GLimp_ToggleFullscreen();
|
|
|
|
break;
|
|
|
|
}
|
2012-06-08 10:23:01 +00:00
|
|
|
|
2015-01-16 15:58:46 +00:00
|
|
|
/* Make Shift+Escape toggle the console. */
|
2014-01-05 17:09:26 +00:00
|
|
|
if ((modstate & KMOD_SHIFT) && (event.key.keysym.sym == SDLK_ESCAPE))
|
|
|
|
{
|
|
|
|
Cbuf_ExecuteText(EXEC_NOW, "toggleconsole");
|
|
|
|
break;
|
|
|
|
}
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* Get the pressed key and add it to the key list */
|
|
|
|
key = IN_TranslateSDLtoQ2Key(event.key.keysym.sym);
|
2013-11-10 08:46:28 +00:00
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
if (key)
|
|
|
|
{
|
2015-01-16 15:58:46 +00:00
|
|
|
Key_Event(key, true);
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
2012-06-08 10:23:01 +00:00
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
break;
|
2012-06-08 10:23:01 +00:00
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* The user released a key */
|
|
|
|
case SDL_KEYUP:
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* Get the pressed key and remove it from the key list */
|
|
|
|
key = IN_TranslateSDLtoQ2Key(event.key.keysym.sym);
|
2012-06-08 10:23:01 +00:00
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
if (key)
|
|
|
|
{
|
2015-01-16 15:58:46 +00:00
|
|
|
Key_Event(key, false);
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
2012-06-08 10:23:01 +00:00
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-06-08 10:23:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Grab and ungrab the mouse if the
|
2012-10-29 20:21:22 +00:00
|
|
|
* console or the menu is opened */
|
2013-07-30 18:13:49 +00:00
|
|
|
want_grab = (vid_fullscreen->value || in_grab->value == 1 ||
|
|
|
|
(in_grab->value == 2 && windowed_mouse->value));
|
2013-11-10 08:46:28 +00:00
|
|
|
|
2013-07-30 18:13:49 +00:00
|
|
|
if (have_grab != want_grab)
|
2012-06-08 10:23:01 +00:00
|
|
|
{
|
2013-08-25 22:55:31 +00:00
|
|
|
GLimp_GrabInput(want_grab);
|
2013-07-30 18:13:49 +00:00
|
|
|
have_grab = want_grab;
|
2012-06-08 10:23:01 +00:00
|
|
|
}
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Move handling
|
|
|
|
*/
|
|
|
|
void
|
2015-01-16 15:58:46 +00:00
|
|
|
IN_Move(usercmd_t *cmd)
|
2014-01-05 17:09:26 +00:00
|
|
|
{
|
|
|
|
if (m_filter->value)
|
2012-06-08 10:23:01 +00:00
|
|
|
{
|
2014-01-05 17:09:26 +00:00
|
|
|
if ((mouse_x > 1) || (mouse_x < -1))
|
|
|
|
{
|
|
|
|
mouse_x = (mouse_x + old_mouse_x) * 0.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((mouse_y > 1) || (mouse_y < -1))
|
|
|
|
{
|
|
|
|
mouse_y = (mouse_y + old_mouse_y) * 0.5;
|
|
|
|
}
|
2012-06-08 10:23:01 +00:00
|
|
|
}
|
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
old_mouse_x = mouse_x;
|
|
|
|
old_mouse_y = mouse_y;
|
|
|
|
|
|
|
|
if (mouse_x || mouse_y)
|
|
|
|
{
|
|
|
|
if (!exponential_speedup->value)
|
|
|
|
{
|
|
|
|
mouse_x *= sensitivity->value;
|
|
|
|
mouse_y *= sensitivity->value;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((mouse_x > MOUSE_MIN) || (mouse_y > MOUSE_MIN) ||
|
|
|
|
(mouse_x < -MOUSE_MIN) || (mouse_y < -MOUSE_MIN))
|
|
|
|
{
|
|
|
|
mouse_x = (mouse_x * mouse_x * mouse_x) / 4;
|
|
|
|
mouse_y = (mouse_y * mouse_y * mouse_y) / 4;
|
|
|
|
|
|
|
|
if (mouse_x > MOUSE_MAX)
|
|
|
|
{
|
|
|
|
mouse_x = MOUSE_MAX;
|
|
|
|
}
|
|
|
|
else if (mouse_x < -MOUSE_MAX)
|
|
|
|
{
|
|
|
|
mouse_x = -MOUSE_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mouse_y > MOUSE_MAX)
|
|
|
|
{
|
|
|
|
mouse_y = MOUSE_MAX;
|
|
|
|
}
|
|
|
|
else if (mouse_y < -MOUSE_MAX)
|
|
|
|
{
|
|
|
|
mouse_y = -MOUSE_MAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add mouse X/Y movement to cmd */
|
2015-01-16 15:58:46 +00:00
|
|
|
if ((in_strafe.state & 1) || (lookstrafe->value && mlooking))
|
2014-01-05 17:09:26 +00:00
|
|
|
{
|
|
|
|
cmd->sidemove += m_side->value * mouse_x;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-01-16 15:58:46 +00:00
|
|
|
cl.viewangles[YAW] -= m_yaw->value * mouse_x;
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
|
|
|
|
2015-01-16 15:58:46 +00:00
|
|
|
if ((mlooking || freelook->value) && !(in_strafe.state & 1))
|
2014-01-05 17:09:26 +00:00
|
|
|
{
|
2015-01-16 15:58:46 +00:00
|
|
|
cl.viewangles[PITCH] += m_pitch->value * mouse_y;
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cmd->forwardmove -= m_forward->value * mouse_y;
|
|
|
|
}
|
|
|
|
|
|
|
|
mouse_x = mouse_y = 0;
|
|
|
|
}
|
2010-10-19 07:29:20 +00:00
|
|
|
}
|
2014-01-05 17:09:26 +00:00
|
|
|
|
|
|
|
/* ------------------------------------------------------------------ */
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2010-10-19 08:25:47 +00:00
|
|
|
/*
|
|
|
|
* Centers the view
|
|
|
|
*/
|
|
|
|
static void
|
2012-06-08 10:23:01 +00:00
|
|
|
IN_ForceCenterView(void)
|
2010-10-19 07:29:20 +00:00
|
|
|
{
|
2015-01-16 15:58:46 +00:00
|
|
|
cl.viewangles[PITCH] = 0;
|
2012-04-29 13:57:33 +00:00
|
|
|
}
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2010-10-19 08:25:47 +00:00
|
|
|
/*
|
2013-11-10 08:46:28 +00:00
|
|
|
* Look down
|
2010-10-19 08:25:47 +00:00
|
|
|
*/
|
2010-10-19 07:29:20 +00:00
|
|
|
static void
|
2012-06-08 10:23:01 +00:00
|
|
|
IN_MLookDown(void)
|
2010-10-19 07:29:20 +00:00
|
|
|
{
|
|
|
|
mlooking = true;
|
|
|
|
}
|
|
|
|
|
2010-10-19 08:25:47 +00:00
|
|
|
/*
|
2013-11-10 08:46:28 +00:00
|
|
|
* Look up
|
2010-10-19 08:25:47 +00:00
|
|
|
*/
|
2010-10-19 07:29:20 +00:00
|
|
|
static void
|
2012-06-08 10:23:01 +00:00
|
|
|
IN_MLookUp(void)
|
2010-10-19 07:29:20 +00:00
|
|
|
{
|
|
|
|
mlooking = false;
|
2015-01-16 15:58:46 +00:00
|
|
|
IN_CenterView();
|
2010-10-19 07:29:20 +00:00
|
|
|
}
|
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
|
2014-01-05 19:22:34 +00:00
|
|
|
/*
|
|
|
|
* Initializes the backend
|
|
|
|
*/
|
|
|
|
void
|
2015-01-16 15:58:46 +00:00
|
|
|
IN_Init(void)
|
2014-01-05 19:22:34 +00:00
|
|
|
{
|
2015-01-16 15:58:46 +00:00
|
|
|
Com_Printf("------- input initialization -------\n");
|
|
|
|
|
2014-01-05 19:22:34 +00:00
|
|
|
mouse_x = mouse_y = 0;
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2013-11-10 08:46:28 +00:00
|
|
|
exponential_speedup = Cvar_Get("exponential_speedup", "0", CVAR_ARCHIVE);
|
2013-05-01 21:24:44 +00:00
|
|
|
freelook = Cvar_Get("freelook", "1", 0);
|
2013-11-10 08:46:28 +00:00
|
|
|
in_grab = Cvar_Get("in_grab", "2", CVAR_ARCHIVE);
|
|
|
|
in_mouse = Cvar_Get("in_mouse", "0", CVAR_ARCHIVE);
|
2013-05-01 21:24:44 +00:00
|
|
|
lookstrafe = Cvar_Get("lookstrafe", "0", 0);
|
2013-11-10 08:46:28 +00:00
|
|
|
m_filter = Cvar_Get("m_filter", "0", CVAR_ARCHIVE);
|
2013-05-01 21:24:44 +00:00
|
|
|
m_forward = Cvar_Get("m_forward", "1", 0);
|
2013-11-10 08:46:28 +00:00
|
|
|
m_pitch = Cvar_Get("m_pitch", "0.022", 0);
|
2013-05-01 21:24:44 +00:00
|
|
|
m_side = Cvar_Get("m_side", "0.8", 0);
|
2013-11-10 08:46:28 +00:00
|
|
|
m_yaw = Cvar_Get("m_yaw", "0.022", 0);
|
|
|
|
sensitivity = Cvar_Get("sensitivity", "3", 0);
|
|
|
|
vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
|
|
|
|
windowed_mouse = Cvar_Get("windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE);
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2013-05-01 21:24:44 +00:00
|
|
|
Cmd_AddCommand("+mlook", IN_MLookDown);
|
|
|
|
Cmd_AddCommand("-mlook", IN_MLookUp);
|
|
|
|
Cmd_AddCommand("force_centerview", IN_ForceCenterView);
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2015-01-16 15:58:46 +00:00
|
|
|
have_grab = GLimp_InputIsGrabbed();
|
|
|
|
|
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
|
|
SDL_SetRelativeMouseMode(have_grab ? SDL_TRUE : SDL_FALSE);
|
|
|
|
in_relativemode = (SDL_GetRelativeMouseMode() == SDL_TRUE);
|
|
|
|
#else
|
|
|
|
SDL_EnableUNICODE(0);
|
|
|
|
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Com_Printf("------------------------------------\n\n");
|
2010-10-19 07:29:20 +00:00
|
|
|
}
|
|
|
|
|
2010-10-19 08:25:47 +00:00
|
|
|
/*
|
|
|
|
* Shuts the backend down
|
|
|
|
*/
|
2010-10-19 07:29:20 +00:00
|
|
|
void
|
2015-01-16 15:58:46 +00:00
|
|
|
IN_Shutdown(void)
|
2010-10-19 07:29:20 +00:00
|
|
|
{
|
2013-11-10 08:46:28 +00:00
|
|
|
Cmd_RemoveCommand("force_centerview");
|
2013-05-01 21:24:44 +00:00
|
|
|
Cmd_RemoveCommand("+mlook");
|
|
|
|
Cmd_RemoveCommand("-mlook");
|
2013-11-10 08:46:28 +00:00
|
|
|
|
2015-01-16 15:58:46 +00:00
|
|
|
Com_Printf("Shutting down input.\n");
|
2010-10-19 07:29:20 +00:00
|
|
|
}
|
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* ------------------------------------------------------------------ */
|
2010-10-19 08:30:02 +00:00
|
|
|
|