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
|
|
|
|
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
|
|
|
#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 */
|
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 mlooking;
|
2010-10-19 07:29:20 +00:00
|
|
|
|
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;
|
|
|
|
|
2016-12-19 02:16:44 +00:00
|
|
|
|
|
|
|
extern void GLimp_GrabInput(qboolean grab);
|
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
/* ------------------------------------------------------------------ */
|
2012-11-13 21:37:17 +00:00
|
|
|
|
2010-10-19 08:25:47 +00:00
|
|
|
/*
|
2015-01-17 07:34:58 +00:00
|
|
|
* This creepy function translates SDL keycodes into
|
|
|
|
* the id Tech 2 engines interal representation.
|
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;
|
|
|
|
|
2015-01-17 07:34:58 +00:00
|
|
|
/* These must be translated */
|
|
|
|
switch (keysym)
|
2012-06-08 10:23:01 +00:00
|
|
|
{
|
2015-01-17 07:34:58 +00:00
|
|
|
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:
|
|
|
|
key = K_ESCAPE;
|
|
|
|
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;
|
2012-06-08 10:23:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
2017-03-04 15:31:34 +00:00
|
|
|
extern int glimp_refreshRate;
|
|
|
|
|
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
|
|
|
|
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)
|
|
|
|
{
|
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-17 07:34:58 +00:00
|
|
|
Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), true, true);
|
|
|
|
Key_Event((event.wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN), false, true);
|
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-17 07:34:58 +00:00
|
|
|
Key_Event(K_MWHEELUP, true, true);
|
|
|
|
Key_Event(K_MWHEELUP, false, true);
|
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-17 07:34:58 +00:00
|
|
|
Key_Event(K_MWHEELDOWN, true, true);
|
|
|
|
Key_Event(K_MWHEELDOWN, false, true);
|
2013-11-26 18:22:29 +00:00
|
|
|
break;
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
|
|
|
#endif
|
2015-12-12 17:47:46 +00:00
|
|
|
/* fall-through */
|
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-17 07:34:58 +00:00
|
|
|
Key_Event(key, (event.type == SDL_MOUSEBUTTONDOWN), true);
|
2013-03-18 18:37:26 +00:00
|
|
|
break;
|
|
|
|
|
2014-03-26 19:34:19 +00:00
|
|
|
case SDL_MOUSEMOTION:
|
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;
|
|
|
|
|
2015-01-17 07:34:58 +00:00
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
|
|
case SDL_TEXTINPUT:
|
2015-12-12 17:47:46 +00:00
|
|
|
if((event.text.text[0] >= ' ') &&
|
|
|
|
(event.text.text[0] <= '~'))
|
2015-01-21 16:24:03 +00:00
|
|
|
{
|
|
|
|
Char_Event(event.text.text[0]);
|
|
|
|
}
|
|
|
|
|
2015-01-17 07:34:58 +00:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
2014-01-05 17:09:26 +00:00
|
|
|
case SDL_KEYDOWN:
|
2015-01-17 07:34:58 +00:00
|
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
2015-01-21 16:24:03 +00:00
|
|
|
if ((event.key.keysym.unicode >= SDLK_SPACE) &&
|
|
|
|
(event.key.keysym.unicode < SDLK_DELETE))
|
|
|
|
{
|
|
|
|
Char_Event(event.key.keysym.unicode);
|
|
|
|
}
|
2015-01-17 07:34:58 +00:00
|
|
|
#endif
|
2015-12-12 17:47:46 +00:00
|
|
|
/* fall-through */
|
Workaround for better AZERTY-Keyboard support
The first row of AZERTY-Keyboards (used in France and Belgium) doesn't
have numbers as keys but ², &, é, ", ', (, -, è, _, ç, à, ), =
(with small differences between France and Belgium).
For some of those keys we don't have keycodes - and neither does SDL2.
See also https://bugzilla.libsdl.org/show_bug.cgi?id=3188
As a workaround, just map those keys to 1, 2, ..., 9, 0 anyway, as those
are keys Quake2 already knows (and those chars are printed on the keys
too, for typing they're reachable via shift).
This workaround only works for SDL2, as SDL1.2 doesn't have scancodes
which we need scancodes to identify the keys.
While at it I unified handling of SDL_KEYDOWN and SDL_KEYUP, the code
is almost identical anyway, apart from one bool argument to Key_Event().
We track this problem in #81
2015-11-22 21:55:06 +00:00
|
|
|
case SDL_KEYUP:
|
|
|
|
{
|
|
|
|
qboolean down = (event.type == SDL_KEYDOWN);
|
|
|
|
|
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
2015-12-12 17:47:46 +00:00
|
|
|
/* workaround for AZERTY-keyboards, which don't have 1, 2, ..., 9, 0 in first row:
|
|
|
|
* always map those physical keys (scancodes) to those keycodes anyway
|
|
|
|
* see also https://bugzilla.libsdl.org/show_bug.cgi?id=3188 */
|
Workaround for better AZERTY-Keyboard support
The first row of AZERTY-Keyboards (used in France and Belgium) doesn't
have numbers as keys but ², &, é, ", ', (, -, è, _, ç, à, ), =
(with small differences between France and Belgium).
For some of those keys we don't have keycodes - and neither does SDL2.
See also https://bugzilla.libsdl.org/show_bug.cgi?id=3188
As a workaround, just map those keys to 1, 2, ..., 9, 0 anyway, as those
are keys Quake2 already knows (and those chars are printed on the keys
too, for typing they're reachable via shift).
This workaround only works for SDL2, as SDL1.2 doesn't have scancodes
which we need scancodes to identify the keys.
While at it I unified handling of SDL_KEYDOWN and SDL_KEYUP, the code
is almost identical anyway, apart from one bool argument to Key_Event().
We track this problem in #81
2015-11-22 21:55:06 +00:00
|
|
|
SDL_Scancode sc = event.key.keysym.scancode;
|
|
|
|
if(sc >= SDL_SCANCODE_1 && sc <= SDL_SCANCODE_0)
|
2014-01-05 17:09:26 +00:00
|
|
|
{
|
2015-12-12 17:47:46 +00:00
|
|
|
/* Note that the SDL_SCANCODEs are SDL_SCANCODE_1, _2, ..., _9, SDL_SCANCODE_0
|
|
|
|
* while in ASCII it's '0', '1', ..., '9' => handle 0 and 1-9 separately
|
|
|
|
* (quake2 uses the ASCII values for those keys) */
|
|
|
|
int key = '0'; /* implicitly handles SDL_SCANCODE_0 */
|
|
|
|
if(sc <= SDL_SCANCODE_9)
|
Workaround for better AZERTY-Keyboard support
The first row of AZERTY-Keyboards (used in France and Belgium) doesn't
have numbers as keys but ², &, é, ", ', (, -, è, _, ç, à, ), =
(with small differences between France and Belgium).
For some of those keys we don't have keycodes - and neither does SDL2.
See also https://bugzilla.libsdl.org/show_bug.cgi?id=3188
As a workaround, just map those keys to 1, 2, ..., 9, 0 anyway, as those
are keys Quake2 already knows (and those chars are printed on the keys
too, for typing they're reachable via shift).
This workaround only works for SDL2, as SDL1.2 doesn't have scancodes
which we need scancodes to identify the keys.
While at it I unified handling of SDL_KEYDOWN and SDL_KEYUP, the code
is almost identical anyway, apart from one bool argument to Key_Event().
We track this problem in #81
2015-11-22 21:55:06 +00:00
|
|
|
{
|
|
|
|
key = '1' + (sc - SDL_SCANCODE_1);
|
|
|
|
}
|
|
|
|
Key_Event(key, down, false);
|
2015-01-17 07:34:58 +00:00
|
|
|
}
|
|
|
|
else
|
2015-12-12 17:47:46 +00:00
|
|
|
#endif /* SDL2; (SDL1.2 doesn't have scancodes so nothing we can do there) */
|
|
|
|
if((event.key.keysym.sym >= SDLK_SPACE) &&
|
|
|
|
(event.key.keysym.sym < SDLK_DELETE))
|
2015-01-17 07:34:58 +00:00
|
|
|
{
|
Workaround for better AZERTY-Keyboard support
The first row of AZERTY-Keyboards (used in France and Belgium) doesn't
have numbers as keys but ², &, é, ", ', (, -, è, _, ç, à, ), =
(with small differences between France and Belgium).
For some of those keys we don't have keycodes - and neither does SDL2.
See also https://bugzilla.libsdl.org/show_bug.cgi?id=3188
As a workaround, just map those keys to 1, 2, ..., 9, 0 anyway, as those
are keys Quake2 already knows (and those chars are printed on the keys
too, for typing they're reachable via shift).
This workaround only works for SDL2, as SDL1.2 doesn't have scancodes
which we need scancodes to identify the keys.
While at it I unified handling of SDL_KEYDOWN and SDL_KEYUP, the code
is almost identical anyway, apart from one bool argument to Key_Event().
We track this problem in #81
2015-11-22 21:55:06 +00:00
|
|
|
Key_Event(event.key.keysym.sym, down, false);
|
2015-01-17 07:34:58 +00:00
|
|
|
}
|
|
|
|
else
|
2014-01-05 17:09:26 +00:00
|
|
|
{
|
Workaround for better AZERTY-Keyboard support
The first row of AZERTY-Keyboards (used in France and Belgium) doesn't
have numbers as keys but ², &, é, ", ', (, -, è, _, ç, à, ), =
(with small differences between France and Belgium).
For some of those keys we don't have keycodes - and neither does SDL2.
See also https://bugzilla.libsdl.org/show_bug.cgi?id=3188
As a workaround, just map those keys to 1, 2, ..., 9, 0 anyway, as those
are keys Quake2 already knows (and those chars are printed on the keys
too, for typing they're reachable via shift).
This workaround only works for SDL2, as SDL1.2 doesn't have scancodes
which we need scancodes to identify the keys.
While at it I unified handling of SDL_KEYDOWN and SDL_KEYUP, the code
is almost identical anyway, apart from one bool argument to Key_Event().
We track this problem in #81
2015-11-22 21:55:06 +00:00
|
|
|
Key_Event(IN_TranslateSDLtoQ2Key(event.key.keysym.sym), down, true);
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
Workaround for better AZERTY-Keyboard support
The first row of AZERTY-Keyboards (used in France and Belgium) doesn't
have numbers as keys but ², &, é, ", ', (, -, è, _, ç, à, ), =
(with small differences between France and Belgium).
For some of those keys we don't have keycodes - and neither does SDL2.
See also https://bugzilla.libsdl.org/show_bug.cgi?id=3188
As a workaround, just map those keys to 1, 2, ..., 9, 0 anyway, as those
are keys Quake2 already knows (and those chars are printed on the keys
too, for typing they're reachable via shift).
This workaround only works for SDL2, as SDL1.2 doesn't have scancodes
which we need scancodes to identify the keys.
While at it I unified handling of SDL_KEYDOWN and SDL_KEYUP, the code
is almost identical anyway, apart from one bool argument to Key_Event().
We track this problem in #81
2015-11-22 21:55:06 +00:00
|
|
|
}
|
2014-01-05 17:09:26 +00:00
|
|
|
break;
|
2015-03-31 19:23:04 +00:00
|
|
|
|
2015-04-13 22:51:38 +00:00
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
|
|
case SDL_WINDOWEVENT:
|
2016-11-08 16:37:24 +00:00
|
|
|
if(event.window.event == SDL_WINDOWEVENT_FOCUS_LOST ||
|
|
|
|
event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
2015-04-13 22:51:38 +00:00
|
|
|
{
|
|
|
|
Key_MarkAllUp();
|
|
|
|
}
|
2017-03-04 15:31:34 +00:00
|
|
|
else if(event.window.event == SDL_WINDOWEVENT_MOVED)
|
|
|
|
{
|
|
|
|
// make sure GLimp_GetRefreshRate() will query from SDL again - the window might
|
|
|
|
// be on another display now!
|
|
|
|
glimp_refreshRate = -1;
|
|
|
|
}
|
2015-04-13 22:51:38 +00:00
|
|
|
|
2015-12-12 17:47:46 +00:00
|
|
|
#else /* SDL1.2 */
|
2015-04-13 22:51:38 +00:00
|
|
|
case SDL_ACTIVEEVENT:
|
|
|
|
if(event.active.gain == 0 && (event.active.state & SDL_APPINPUTFOCUS))
|
|
|
|
{
|
|
|
|
Key_MarkAllUp();
|
|
|
|
}
|
2015-03-31 19:23:04 +00:00
|
|
|
#endif
|
2015-04-13 22:51:38 +00:00
|
|
|
break;
|
2016-07-18 08:11:54 +00:00
|
|
|
|
|
|
|
case SDL_QUIT:
|
|
|
|
Com_Quit();
|
|
|
|
|
|
|
|
break;
|
2015-04-13 22:51:38 +00:00
|
|
|
}
|
2012-06-08 10:23:01 +00:00
|
|
|
}
|
|
|
|
|
2015-01-17 07:34:58 +00:00
|
|
|
/* Grab and ungrab the mouse if the* 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));
|
2015-03-27 17:56:16 +00:00
|
|
|
/* calling GLimp_GrabInput() each is a but ugly but simple and should work.
|
|
|
|
* + the called SDL functions return after a cheap check, if there's
|
|
|
|
* nothing to do, anyway
|
|
|
|
*/
|
|
|
|
GLimp_GrabInput(want_grab);
|
2014-01-05 17:09:26 +00:00
|
|
|
}
|
2017-04-22 08:29:25 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Removes all pending events from SDLs queue.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
In_FlushQueue(void)
|
|
|
|
{
|
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
|
|
SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
|
|
|
|
#else
|
|
|
|
SDL_Event event;
|
|
|
|
while(SDL_PollEvent(&event));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Key_MarkAllUp();
|
|
|
|
}
|
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
|
|
|
/*
|
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);
|
2010-10-19 07:29:20 +00:00
|
|
|
|
2015-01-16 15:58:46 +00:00
|
|
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
2015-01-17 07:34:58 +00:00
|
|
|
SDL_StartTextInput();
|
2015-01-16 15:58:46 +00:00
|
|
|
#else
|
|
|
|
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
|
|
|
|