/* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2005 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske 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. */ #include "quakedef.h" #include "SDL.h" static qboolean no_mouse = false; // mouse variables cvar_t m_filter = {"m_filter","0"}; // total accumulated mouse movement since last frame // this gets updated from the main game loop via IN_MouseMove static int total_dx, total_dy = 0; static int FilterMouseEvents (const SDL_Event *event) { switch (event->type) { case SDL_MOUSEMOTION: case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: return 0; } return 1; } void IN_Activate (void) { if (no_mouse) return; if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON) { SDL_WM_GrabInput(SDL_GRAB_ON); if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON) Con_Printf("WARNING: SDL_WM_GrabInput(SDL_GRAB_ON) failed.\n"); } if (SDL_ShowCursor(SDL_QUERY) != SDL_DISABLE) { SDL_ShowCursor(SDL_DISABLE); if (SDL_ShowCursor(SDL_QUERY) != SDL_DISABLE) Con_Printf("WARNING: SDL_ShowCursor(SDL_DISABLE) failed.\n"); } if (SDL_GetEventFilter() != NULL) SDL_SetEventFilter(NULL); total_dx = 0; total_dy = 0; } void IN_Deactivate (qboolean free_cursor) { if (no_mouse) return; if (free_cursor) { if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_OFF) { SDL_WM_GrabInput(SDL_GRAB_OFF); if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_OFF) Con_Printf("WARNING: SDL_WM_GrabInput(SDL_GRAB_OFF) failed.\n"); } if (SDL_ShowCursor(SDL_QUERY) != SDL_ENABLE) { SDL_ShowCursor(SDL_ENABLE); if (SDL_ShowCursor(SDL_QUERY) != SDL_ENABLE) Con_Printf("WARNING: SDL_ShowCursor(SDL_ENABLE) failed.\n"); } } // discard all mouse events when input is deactivated if (SDL_GetEventFilter() != FilterMouseEvents) SDL_SetEventFilter(FilterMouseEvents); } void IN_Init (void) { BuildKeyMaps(); if (SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL) == -1) Con_Printf("Warning: SDL_EnableKeyRepeat() failed.\n"); if (safemode || COM_CheckParm("-nomouse")) { no_mouse = true; // discard all mouse events when input is deactivated SDL_SetEventFilter(FilterMouseEvents); } IN_Activate(); } void IN_Shutdown (void) { IN_Deactivate(true); } void IN_Commands (void) { // TODO: implement this for joystick support } extern cvar_t cl_maxpitch; //johnfitz -- variable pitch clamping extern cvar_t cl_minpitch; //johnfitz -- variable pitch clamping void IN_MouseMove(int dx, int dy) { total_dx += dx; total_dy += dy; } void IN_Move (usercmd_t *cmd) { int dmx, dmy; /* TODO: fix this if (m_filter.value) { dmx = (2*mx - dmx) * 0.5; dmy = (2*my - dmy) * 0.5; } */ dmx = total_dx * sensitivity.value; dmy = total_dy * sensitivity.value; total_dx = 0; total_dy = 0; if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) cmd->sidemove += m_side.value * dmx; else cl.viewangles[YAW] -= m_yaw.value * dmx; if (in_mlook.state & 1) V_StopPitchDrift (); if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) { cl.viewangles[PITCH] += m_pitch.value * dmy; //johnfitz -- variable pitch clamping if (cl.viewangles[PITCH] > cl_maxpitch.value) cl.viewangles[PITCH] = cl_maxpitch.value; if (cl.viewangles[PITCH] < cl_minpitch.value) cl.viewangles[PITCH] = cl_minpitch.value; //johnfitz } else { if ((in_strafe.state & 1) && noclip_anglehack) cmd->upmove -= m_forward.value * dmy; else cmd->forwardmove -= m_forward.value * dmy; } } void IN_ClearStates (void) { } /* ================================= SDL to quake keynum mapping =================================*/ static byte key_map[SDLK_LAST]; void BuildKeyMaps (void) { int i; for (i = 0; i < SDLK_LAST; i++) key_map[i] = 0; key_map[SDLK_BACKSPACE] = K_BACKSPACE; key_map[SDLK_TAB] = K_TAB; key_map[SDLK_RETURN] = K_ENTER; key_map[SDLK_PAUSE] = K_PAUSE; key_map[SDLK_ESCAPE] = K_ESCAPE; key_map[SDLK_SPACE] = K_SPACE; key_map[SDLK_EXCLAIM] = '!'; key_map[SDLK_QUOTEDBL] = '"'; key_map[SDLK_HASH] = '#'; key_map[SDLK_DOLLAR] = '$'; key_map[SDLK_AMPERSAND] = '&'; key_map[SDLK_QUOTE] = '\''; key_map[SDLK_LEFTPAREN] = '('; key_map[SDLK_RIGHTPAREN] = ')'; key_map[SDLK_ASTERISK] = '*'; key_map[SDLK_PLUS] = '+'; key_map[SDLK_COMMA] = ','; key_map[SDLK_MINUS] = '-'; key_map[SDLK_PERIOD] = '.'; key_map[SDLK_SLASH] = '/'; key_map[SDLK_0] = '0'; key_map[SDLK_1] = '1'; key_map[SDLK_2] = '2'; key_map[SDLK_3] = '3'; key_map[SDLK_4] = '4'; key_map[SDLK_5] = '5'; key_map[SDLK_6] = '6'; key_map[SDLK_7] = '7'; key_map[SDLK_8] = '8'; key_map[SDLK_9] = '9'; key_map[SDLK_COLON] = ':'; key_map[SDLK_SEMICOLON] = ';'; key_map[SDLK_LESS] = '<'; key_map[SDLK_EQUALS] = '='; key_map[SDLK_GREATER] = '>'; key_map[SDLK_QUESTION] = '?'; key_map[SDLK_AT] = '@'; key_map[SDLK_LEFTBRACKET] = '['; key_map[SDLK_BACKSLASH] = '\\'; key_map[SDLK_RIGHTBRACKET] = ']'; key_map[SDLK_CARET] = '^'; key_map[SDLK_UNDERSCORE] = '_'; key_map[SDLK_BACKQUOTE] = '`'; key_map[SDLK_a] = 'a'; key_map[SDLK_b] = 'b'; key_map[SDLK_c] = 'c'; key_map[SDLK_d] = 'd'; key_map[SDLK_e] = 'e'; key_map[SDLK_f] = 'f'; key_map[SDLK_g] = 'g'; key_map[SDLK_h] = 'h'; key_map[SDLK_i] = 'i'; key_map[SDLK_j] = 'j'; key_map[SDLK_k] = 'k'; key_map[SDLK_l] = 'l'; key_map[SDLK_m] = 'm'; key_map[SDLK_n] = 'n'; key_map[SDLK_o] = 'o'; key_map[SDLK_p] = 'p'; key_map[SDLK_q] = 'q'; key_map[SDLK_r] = 'r'; key_map[SDLK_s] = 's'; key_map[SDLK_t] = 't'; key_map[SDLK_u] = 'u'; key_map[SDLK_v] = 'v'; key_map[SDLK_w] = 'w'; key_map[SDLK_x] = 'x'; key_map[SDLK_y] = 'y'; key_map[SDLK_z] = 'z'; key_map[SDLK_DELETE] = K_DEL; key_map[SDLK_KP0] = KP_INS; key_map[SDLK_KP1] = KP_END; key_map[SDLK_KP2] = KP_DOWNARROW; key_map[SDLK_KP3] = KP_PGDN; key_map[SDLK_KP4] = KP_LEFTARROW; key_map[SDLK_KP5] = KP_5; key_map[SDLK_KP6] = KP_RIGHTARROW; key_map[SDLK_KP7] = KP_HOME; key_map[SDLK_KP8] = KP_UPARROW; key_map[SDLK_KP9] = KP_PGUP; key_map[SDLK_KP_PERIOD] = KP_DEL; key_map[SDLK_KP_DIVIDE] = KP_SLASH; key_map[SDLK_KP_MULTIPLY] = KP_STAR; key_map[SDLK_KP_MINUS] = KP_MINUS; key_map[SDLK_KP_PLUS] = KP_PLUS; key_map[SDLK_KP_ENTER] = KP_ENTER; key_map[SDLK_KP_EQUALS] = 0; key_map[SDLK_UP] = K_UPARROW; key_map[SDLK_DOWN] = K_DOWNARROW; key_map[SDLK_RIGHT] = K_RIGHTARROW; key_map[SDLK_LEFT] = K_LEFTARROW; key_map[SDLK_INSERT] = K_INS; key_map[SDLK_HOME] = K_HOME; key_map[SDLK_END] = K_END; key_map[SDLK_PAGEUP] = K_PGUP; key_map[SDLK_PAGEDOWN] = K_PGDN; key_map[SDLK_F1] = K_F1; key_map[SDLK_F2] = K_F2; key_map[SDLK_F3] = K_F3; key_map[SDLK_F4] = K_F4; key_map[SDLK_F5] = K_F5; key_map[SDLK_F6] = K_F6; key_map[SDLK_F7] = K_F7; key_map[SDLK_F8] = K_F8; key_map[SDLK_F9] = K_F9; key_map[SDLK_F10] = K_F10; key_map[SDLK_F11] = K_F11; key_map[SDLK_F12] = K_F12; key_map[SDLK_F13] = 0; key_map[SDLK_F14] = 0; key_map[SDLK_F15] = 0; key_map[SDLK_NUMLOCK] = KP_NUMLOCK; key_map[SDLK_CAPSLOCK] = 0; key_map[SDLK_SCROLLOCK] = 0; key_map[SDLK_RSHIFT] = K_SHIFT; key_map[SDLK_LSHIFT] = K_SHIFT; key_map[SDLK_RCTRL] = K_CTRL; key_map[SDLK_LCTRL] = K_CTRL; key_map[SDLK_RALT] = K_ALT; key_map[SDLK_LALT] = K_ALT; key_map[SDLK_RMETA] = 0; key_map[SDLK_LMETA] = 0; key_map[SDLK_LSUPER] = 0; key_map[SDLK_RSUPER] = 0; key_map[SDLK_MODE] = 0; key_map[SDLK_COMPOSE] = 0; key_map[SDLK_HELP] = 0; key_map[SDLK_PRINT] = 0; key_map[SDLK_SYSREQ] = 0; key_map[SDLK_BREAK] = 0; key_map[SDLK_MENU] = 0; key_map[SDLK_POWER] = 0; key_map[SDLK_EURO] = 0; key_map[SDLK_UNDO] = 0; } /* ======= MapKey Map from SDL to quake keynums ======= */ int Key_Map (void *event) /* SDL_KeyboardEvent *event */ { return key_map[(*(SDL_KeyboardEvent *)event).keysym.sym]; /* TODO: keypad handling if (cl_keypad.value) { if (extended) { switch (key) { case K_ENTER: return KP_ENTER; case '/': return KP_SLASH; case K_PAUSE: return KP_NUMLOCK; }; } else { switch (key) { case K_HOME: return KP_HOME; case K_UPARROW: return KP_UPARROW; case K_PGUP: return KP_PGUP; case K_LEFTARROW: return KP_LEFTARROW; case K_RIGHTARROW: return KP_RIGHTARROW; case K_END: return KP_END; case K_DOWNARROW: return KP_DOWNARROW; case K_PGDN: return KP_PGDN; case K_INS: return KP_INS; case K_DEL: return KP_DEL; } } } else { // cl_keypad 0, compatibility mode switch (key) { case KP_STAR: return '*'; case KP_MINUS: return '-'; case KP_5: return '5'; case KP_PLUS: return '+'; } } */ }