/* =========================================================================== Copyright (C) 1999-2005 Id Software, Inc. This file is part of Quake III Arena source code. Quake III Arena source code 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. Quake III Arena source code 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // win_input.c -- win32 mouse and joystick code // 02/21/97 JCB Added extended DirectInput code to support external controllers. #include "../client/client.h" #include "win_local.h" typedef struct { int oldButtonState; qboolean mouseActive; qboolean mouseInitialized; } WinMouseVars_t; static WinMouseVars_t s_wmv; static int window_center_x, window_center_y; cvar_t *in_mouse; cvar_t *in_logitechbug; qboolean in_appactive; /* ============================================================ WIN32 MOUSE CONTROL ============================================================ */ /* ================ IN_InitWin32Mouse ================ */ void IN_InitWin32Mouse( void ) { } /* ================ IN_ShutdownWin32Mouse ================ */ void IN_ShutdownWin32Mouse( void ) { } /* ================ IN_ActivateWin32Mouse ================ */ void IN_ActivateWin32Mouse( void ) { int width, height; RECT window_rect; width = GetSystemMetrics (SM_CXSCREEN); height = GetSystemMetrics (SM_CYSCREEN); GetWindowRect ( g_wv.hWnd, &window_rect); if (window_rect.left < 0) window_rect.left = 0; if (window_rect.top < 0) window_rect.top = 0; if (window_rect.right >= width) window_rect.right = width-1; if (window_rect.bottom >= height-1) window_rect.bottom = height-1; window_center_x = (window_rect.right + window_rect.left)/2; window_center_y = (window_rect.top + window_rect.bottom)/2; SetCursorPos (window_center_x, window_center_y); SetCapture ( g_wv.hWnd ); ClipCursor (&window_rect); while (ShowCursor (FALSE) >= 0) ; } /* ================ IN_DeactivateWin32Mouse ================ */ void IN_DeactivateWin32Mouse( void ) { ClipCursor (NULL); ReleaseCapture (); while (ShowCursor (TRUE) < 0) ; } /* ================ IN_Win32Mouse ================ */ void IN_Win32Mouse( int *mx, int *my ) { POINT current_pos; // find mouse movement GetCursorPos (¤t_pos); // force the mouse to the center, so there's room to move SetCursorPos (window_center_x, window_center_y); *mx = current_pos.x - window_center_x; *my = current_pos.y - window_center_y; } /* ============================================================ MOUSE CONTROL ============================================================ */ /* =========== IN_ActivateMouse Called when the window gains focus or changes in some way =========== */ void IN_ActivateMouse( void ) { if (!s_wmv.mouseInitialized ) { return; } if ( !in_mouse->integer ) { s_wmv.mouseActive = qfalse; return; } if ( s_wmv.mouseActive ) { return; } s_wmv.mouseActive = qtrue; IN_ActivateWin32Mouse(); } /* =========== IN_DeactivateMouse Called when the window loses focus =========== */ void IN_DeactivateMouse( void ) { if (!s_wmv.mouseInitialized ) { return; } if (!s_wmv.mouseActive ) { return; } s_wmv.mouseActive = qfalse; IN_DeactivateWin32Mouse(); } /* =========== IN_StartupMouse =========== */ void IN_StartupMouse( void ) { s_wmv.mouseInitialized = qfalse; if ( in_mouse->integer == 0 ) { Com_Printf ("Mouse control not active.\n"); return; } s_wmv.mouseInitialized = qtrue; IN_InitWin32Mouse(); Com_Printf ("Win32 mouse input initialized.\n"); } /* =========== IN_MouseEvent =========== */ void IN_MouseEvent (int mstate) { int i; if ( !s_wmv.mouseInitialized ) return; // perform button actions for (i = 0 ; i < 3 ; i++ ) { if ( (mstate & (1<modified = qfalse; } /* =========== IN_Shutdown =========== */ void IN_Shutdown( void ) { IN_DeactivateMouse(); } /* =========== IN_Init =========== */ void IN_Init( void ) { in_mouse = Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE|CVAR_LATCH); in_logitechbug = Cvar_Get ("in_logitechbug", "0", CVAR_ARCHIVE); IN_Startup(); } /* =========== IN_Activate Called when the main window gains or loses focus. The window may have been destroyed and recreated between a deactivate and an activate. =========== */ void IN_Activate (qboolean active) { in_appactive = active; if ( !active ) { IN_DeactivateMouse(); } } /* ================== IN_Frame Called every frame, even if not generating commands ================== */ void IN_Frame (void) { if ( !s_wmv.mouseInitialized ) { return; } if ( cls.keyCatchers & KEYCATCH_CONSOLE ) { // temporarily deactivate if not in the game and // running on the desktop // voodoo always counts as full screen if (Cvar_VariableValue ("r_fullscreen") == 0 ) { IN_DeactivateMouse (); return; } } if ( !in_appactive ) { IN_DeactivateMouse (); return; } IN_ActivateMouse(); // post events to the system que IN_MouseMove(); }