*/
// gl_vidnt.c -- NT GL vid component
+// we don't need a very new dinput
+#define DIRECTINPUT_VERSION 0x0300
+
#include "quakedef.h"
#include <windows.h>
+#include <mmsystem.h>
+#ifdef SUPPORTDIRECTX
#include <dsound.h>
+#endif
#include "resource.h"
#include <commctrl.h>
+#ifdef SUPPORTDIRECTX
+#include <dinput.h>
+#endif
-extern void S_BlockSound (void);
-extern void S_UnblockSound (void);
extern HINSTANCE global_hInstance;
// Tell startup code that we have a client
int cl_available = true;
-int (WINAPI *qwglChoosePixelFormat)(HDC, CONST PIXELFORMATDESCRIPTOR *);
-int (WINAPI *qwglDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
-//int (WINAPI *qwglGetPixelFormat)(HDC);
-BOOL (WINAPI *qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
-BOOL (WINAPI *qwglSwapBuffers)(HDC);
-HGLRC (WINAPI *qwglCreateContext)(HDC);
-BOOL (WINAPI *qwglDeleteContext)(HGLRC);
-HGLRC (WINAPI *qwglGetCurrentContext)(VOID);
-HDC (WINAPI *qwglGetCurrentDC)(VOID);
-PROC (WINAPI *qwglGetProcAddress)(LPCSTR);
-BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
-BOOL (WINAPI *qwglSwapIntervalEXT)(int interval);
-const char *(WINAPI *qwglGetExtensionsStringARB)(HDC hdc);
+qboolean vid_supportrefreshrate = true;
+
+static int (WINAPI *qwglChoosePixelFormat)(HDC, CONST PIXELFORMATDESCRIPTOR *);
+static int (WINAPI *qwglDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
+//static int (WINAPI *qwglGetPixelFormat)(HDC);
+static BOOL (WINAPI *qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
+static BOOL (WINAPI *qwglSwapBuffers)(HDC);
+static HGLRC (WINAPI *qwglCreateContext)(HDC);
+static BOOL (WINAPI *qwglDeleteContext)(HGLRC);
+static HGLRC (WINAPI *qwglGetCurrentContext)(VOID);
+static HDC (WINAPI *qwglGetCurrentDC)(VOID);
+static PROC (WINAPI *qwglGetProcAddress)(LPCSTR);
+static BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
+static BOOL (WINAPI *qwglSwapIntervalEXT)(int interval);
+static const char *(WINAPI *qwglGetExtensionsStringARB)(HDC hdc);
+static BOOL (WINAPI *qwglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+static BOOL (WINAPI *qwglGetPixelFormatAttribivARB)(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
static dllfunction_t wglfuncs[] =
{
{NULL, NULL}
};
-static DEVMODE gdevmode;
+static dllfunction_t wglpixelformatfuncs[] =
+{
+ {"wglChoosePixelFormatARB", (void **) &qwglChoosePixelFormatARB},
+ {"wglGetPixelFormatAttribivARB", (void **) &qwglGetPixelFormatAttribivARB},
+ {NULL, NULL}
+};
+
+static DEVMODE gdevmode, initialdevmode;
static qboolean vid_initialized = false;
static qboolean vid_wassuspended = false;
static qboolean vid_usingmouse = false;
+static qboolean vid_usinghidecursor = false;
static qboolean vid_usingvsync = false;
-static qboolean vid_usemouse = false;
static qboolean vid_usevsync = false;
static HICON hIcon;
+// used by cd_win.c and snd_win.c
HWND mainwindow;
+
static HDC baseDC;
static HGLRC baseRC;
//HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow);
-static int vid_isfullscreen;
+static qboolean vid_isfullscreen;
//void VID_MenuDraw (void);
//void VID_MenuKey (int key);
//====================================
-int window_x, window_y, window_width, window_height;
-int window_center_x, window_center_y;
+static int window_x, window_y;
-void IN_ShowMouse (void);
-void IN_DeactivateMouse (void);
-void IN_HideMouse (void);
-void IN_ActivateMouse (void);
-void IN_MouseEvent (int mstate);
-void IN_UpdateClipCursor (void);
+static qboolean mouseinitialized;
-qboolean mouseinitialized;
+#ifdef SUPPORTDIRECTX
static qboolean dinput;
-
-// input code
-
-#include <dinput.h>
-
#define DINPUT_BUFFERSIZE 16
#define iDirectInputCreate(a,b,c,d) pDirectInputCreate(a,b,c,d)
-HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion,
- LPDIRECTINPUT * lplpDirectInput, LPUNKNOWN punkOuter);
+static HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT * lplpDirectInput, LPUNKNOWN punkOuter);
+#endif
// LordHavoc: thanks to backslash for this support for mouse buttons 4 and 5
/* backslash :: imouse explorer buttons */
#ifndef MK_XBUTTON1
#define MK_XBUTTON1 0x0020
#define MK_XBUTTON2 0x0040
+#endif
+#ifndef MK_XBUTTON3
// LordHavoc: lets hope this allows more buttons in the future...
#define MK_XBUTTON3 0x0080
#define MK_XBUTTON4 0x0100
/* :: backslash */
// mouse variables
-int mouse_buttons;
-int mouse_oldbuttonstate;
-POINT current_pos;
-int mouse_x, mouse_y, old_mouse_x, old_mouse_y;
-
-static qboolean restore_spi;
-static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1};
-
-unsigned int uiWheelMessage;
-qboolean mouseactive;
-//qboolean mouseinitialized;
-static qboolean mouseparmsvalid, mouseactivatetoggle;
-static qboolean mouseshowtoggle = 1;
+static int mouse_buttons;
+static int mouse_oldbuttonstate;
+
+static unsigned int uiWheelMessage;
+#ifdef SUPPORTDIRECTX
static qboolean dinput_acquired;
static unsigned int mstate_di;
+#endif
// joystick defines and variables
// where should defines be moved?
AxisNada = 0, AxisForward, AxisLook, AxisSide, AxisTurn
};
-DWORD dwAxisFlags[JOY_MAX_AXES] =
+static DWORD dwAxisFlags[JOY_MAX_AXES] =
{
JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV
};
-DWORD dwAxisMap[JOY_MAX_AXES];
-DWORD dwControlMap[JOY_MAX_AXES];
-PDWORD pdwRawValue[JOY_MAX_AXES];
+static DWORD dwAxisMap[JOY_MAX_AXES];
+static DWORD dwControlMap[JOY_MAX_AXES];
+static PDWORD pdwRawValue[JOY_MAX_AXES];
// none of these cvars are saved over a session
// this means that advanced controller configuration needs to be executed
// each time. this avoids any problems with getting back to a default usage
// or when changing from one controller to another. this way at least something
// works.
-cvar_t in_joystick = {CVAR_SAVE, "joystick","0"};
-cvar_t joy_name = {0, "joyname", "joystick"};
-cvar_t joy_advanced = {0, "joyadvanced", "0"};
-cvar_t joy_advaxisx = {0, "joyadvaxisx", "0"};
-cvar_t joy_advaxisy = {0, "joyadvaxisy", "0"};
-cvar_t joy_advaxisz = {0, "joyadvaxisz", "0"};
-cvar_t joy_advaxisr = {0, "joyadvaxisr", "0"};
-cvar_t joy_advaxisu = {0, "joyadvaxisu", "0"};
-cvar_t joy_advaxisv = {0, "joyadvaxisv", "0"};
-cvar_t joy_forwardthreshold = {0, "joyforwardthreshold", "0.15"};
-cvar_t joy_sidethreshold = {0, "joysidethreshold", "0.15"};
-cvar_t joy_pitchthreshold = {0, "joypitchthreshold", "0.15"};
-cvar_t joy_yawthreshold = {0, "joyyawthreshold", "0.15"};
-cvar_t joy_forwardsensitivity = {0, "joyforwardsensitivity", "-1.0"};
-cvar_t joy_sidesensitivity = {0, "joysidesensitivity", "-1.0"};
-cvar_t joy_pitchsensitivity = {0, "joypitchsensitivity", "1.0"};
-cvar_t joy_yawsensitivity = {0, "joyyawsensitivity", "-1.0"};
-cvar_t joy_wwhack1 = {0, "joywwhack1", "0.0"};
-cvar_t joy_wwhack2 = {0, "joywwhack2", "0.0"};
-
-qboolean joy_avail, joy_advancedinit, joy_haspov;
-DWORD joy_oldbuttonstate, joy_oldpovstate;
-
-int joy_id;
-DWORD joy_flags;
-DWORD joy_numbuttons;
-
+static cvar_t in_joystick = {CVAR_SAVE, "joystick","0", "enables joysticks"};
+static cvar_t joy_name = {0, "joyname", "joystick", "name of joystick to use (informational only, used only by joyadvanced 1 mode)"};
+static cvar_t joy_advanced = {0, "joyadvanced", "0", "use more than 2 axis joysticks (configuring this is very technical)"};
+static cvar_t joy_advaxisx = {0, "joyadvaxisx", "0", "axis mapping for joyadvanced 1 mode"};
+static cvar_t joy_advaxisy = {0, "joyadvaxisy", "0", "axis mapping for joyadvanced 1 mode"};
+static cvar_t joy_advaxisz = {0, "joyadvaxisz", "0", "axis mapping for joyadvanced 1 mode"};
+static cvar_t joy_advaxisr = {0, "joyadvaxisr", "0", "axis mapping for joyadvanced 1 mode"};
+static cvar_t joy_advaxisu = {0, "joyadvaxisu", "0", "axis mapping for joyadvanced 1 mode"};
+static cvar_t joy_advaxisv = {0, "joyadvaxisv", "0", "axis mapping for joyadvanced 1 mode"};
+static cvar_t joy_forwardthreshold = {0, "joyforwardthreshold", "0.15", "minimum joystick movement necessary to move forward"};
+static cvar_t joy_sidethreshold = {0, "joysidethreshold", "0.15", "minimum joystick movement necessary to move sideways (strafing)"};
+static cvar_t joy_pitchthreshold = {0, "joypitchthreshold", "0.15", "minimum joystick movement necessary to look up/down"};
+static cvar_t joy_yawthreshold = {0, "joyyawthreshold", "0.15", "minimum joystick movement necessary to turn left/right"};
+static cvar_t joy_forwardsensitivity = {0, "joyforwardsensitivity", "-1.0", "how fast the joystick moves forward"};
+static cvar_t joy_sidesensitivity = {0, "joysidesensitivity", "-1.0", "how fast the joystick moves sideways (strafing)"};
+static cvar_t joy_pitchsensitivity = {0, "joypitchsensitivity", "1.0", "how fast the joystick looks up/down"};
+static cvar_t joy_yawsensitivity = {0, "joyyawsensitivity", "-1.0", "how fast the joystick turns left/right"};
+static cvar_t joy_wwhack1 = {0, "joywwhack1", "0.0", "special hack for wingman warrior"};
+static cvar_t joy_wwhack2 = {0, "joywwhack2", "0.0", "special hack for wingman warrior"};
+
+static cvar_t vid_forcerefreshrate = {0, "vid_forcerefreshrate", "0", "try to set the given vid_refreshrate even if Windows doesn't list it as valid video mode"};
+
+static qboolean joy_avail, joy_advancedinit, joy_haspov;
+static DWORD joy_oldbuttonstate, joy_oldpovstate;
+
+static int joy_id;
+static DWORD joy_flags;
+static DWORD joy_numbuttons;
+
+#ifdef SUPPORTDIRECTX
static LPDIRECTINPUT g_pdi;
static LPDIRECTINPUTDEVICE g_pMouse;
-
-static JOYINFOEX ji;
-
static HINSTANCE hInstDI;
+#endif
-//static qboolean dinput;
-
-typedef struct MYDATA {
- LONG lX; // X axis goes here
- LONG lY; // Y axis goes here
- LONG lZ; // Z axis goes here
- BYTE bButtonA; // One button goes here
- BYTE bButtonB; // Another button goes here
- BYTE bButtonC; // Another button goes here
- BYTE bButtonD; // Another button goes here
-} MYDATA;
-
-static DIOBJECTDATAFORMAT rgodf[] = {
- { &GUID_XAxis, FIELD_OFFSET(MYDATA, lX), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,},
- { &GUID_YAxis, FIELD_OFFSET(MYDATA, lY), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,},
- { &GUID_ZAxis, FIELD_OFFSET(MYDATA, lZ), 0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,},
- { 0, FIELD_OFFSET(MYDATA, bButtonA), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
- { 0, FIELD_OFFSET(MYDATA, bButtonB), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
- { 0, FIELD_OFFSET(MYDATA, bButtonC), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
- { 0, FIELD_OFFSET(MYDATA, bButtonD), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
-};
-
-#define NUM_OBJECTS (sizeof(rgodf) / sizeof(rgodf[0]))
-
-static DIDATAFORMAT df = {
- sizeof(DIDATAFORMAT), // this structure
- sizeof(DIOBJECTDATAFORMAT), // size of object data format
- DIDF_RELAXIS, // absolute axis coordinates
- sizeof(MYDATA), // device data size
- NUM_OBJECTS, // number of objects
- rgodf, // and here they are
-};
+static JOYINFOEX ji;
// forward-referenced functions
-void IN_StartupJoystick (void);
-void Joy_AdvancedUpdate_f (void);
-void IN_JoyMove (void);
-void IN_StartupMouse (void);
-
-/*
-================
-VID_UpdateWindowStatus
-================
-*/
-void VID_UpdateWindowStatus (void)
-{
- window_center_x = window_x + window_width / 2;
- window_center_y = window_y + window_height / 2;
-
- if (mouseinitialized && mouseactive && !dinput)
- {
- RECT window_rect;
- window_rect.left = window_x;
- window_rect.top = window_y;
- window_rect.right = window_x + window_width;
- window_rect.bottom = window_y + window_height;
- ClipCursor (&window_rect);
- }
-}
+static void IN_StartupJoystick (void);
+static void Joy_AdvancedUpdate_f (void);
+static void IN_JoyMove (void);
+static void IN_StartupMouse (void);
//====================================
-/*
-=================
-VID_GetWindowSize
-=================
-*/
-void VID_GetWindowSize (int *x, int *y, int *width, int *height)
-{
- *x = 0;
- *y = 0;
- *width = window_width;
- *height = window_height;
-}
-
-
void VID_Finish (void)
{
vid_usevsync = vid_vsync.integer && !cls.timedemo && gl_videosyncavailable;
qwglSwapIntervalEXT (vid_usevsync);
}
-// handle the mouse state when windowed if that's changed
- vid_usemouse = false;
- if (vid_mouse.integer && !key_consoleactive)
- vid_usemouse = true;
- if (vid_isfullscreen)
- vid_usemouse = true;
- if (!vid_activewindow)
- vid_usemouse = false;
- if (vid_usemouse)
- {
- if (!vid_usingmouse)
- {
- vid_usingmouse = true;
- IN_ActivateMouse ();
- IN_HideMouse();
- }
- }
- else
- {
- if (vid_usingmouse)
- {
- vid_usingmouse = false;
- IN_DeactivateMouse ();
- IN_ShowMouse();
- }
- }
-
if (r_render.integer && !vid_hidden)
{
+ CHECKGLERROR
if (r_speeds.integer || gl_finish.integer)
- qglFinish();
+ {
+ qglFinish();CHECKGLERROR
+ }
SwapBuffers(baseDC);
}
+
+ // make sure a context switch can happen every frame - Logitech drivers
+ // input drivers sometimes eat cpu time every 3 seconds or lag badly
+ // without this help
+ Sleep(0);
+
+ VID_UpdateGamma(false, 256);
}
//==========================================================================
-qbyte scantokey[128] =
+static unsigned char scantokey[128] =
{
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0 ,27 ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'0' ,'-' ,'=' ,K_BACKSPACE,9 ,//0
ClearAllStates
================
*/
-void ClearAllStates (void)
+static void ClearAllStates (void)
{
Key_ClearStates ();
- IN_ClearStates ();
+ if (vid_usingmouse)
+ mouse_oldbuttonstate = 0;
}
-extern qboolean host_loopactive;
-
void AppActivate(BOOL fActive, BOOL minimize)
/****************************************************************************
*
*
****************************************************************************/
{
- static BOOL sound_active;
+ static qboolean sound_active = false; // initially blocked by Sys_InitConsole()
vid_activewindow = fActive;
vid_hidden = minimize;
-// enable/disable sound on focus gain/loss
- if (!vid_activewindow && sound_active)
+ // enable/disable sound on focus gain/loss
+ if (!vid_hidden && (vid_activewindow || !snd_mutewhenidle.integer))
{
- S_BlockSound ();
- sound_active = false;
+ if (!sound_active)
+ {
+ S_UnblockSound ();
+ sound_active = true;
+ }
}
- else if (vid_activewindow && !sound_active)
+ else
{
- S_UnblockSound ();
- sound_active = true;
+ if (sound_active)
+ {
+ S_BlockSound ();
+ sound_active = false;
+ }
}
if (fActive)
if (!fActive)
{
- vid_usingmouse = false;
- IN_DeactivateMouse ();
- IN_ShowMouse ();
+ VID_SetMouse(false, false, false);
if (vid_isfullscreen)
{
ChangeDisplaySettings (NULL, 0);
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage (&msg, NULL, 0, 0))
- Sys_Quit ();
+ Sys_Quit (1);
TranslateMessage (&msg);
DispatchMessage (&msg);
LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static keynum_t buttonremap[16] =
+{
+ K_MOUSE1,
+ K_MOUSE2,
+ K_MOUSE3,
+ K_MOUSE4,
+ K_MOUSE5,
+ K_MOUSE6,
+ K_MOUSE7,
+ K_MOUSE8,
+ K_MOUSE9,
+ K_MOUSE10,
+ K_MOUSE11,
+ K_MOUSE12,
+ K_MOUSE13,
+ K_MOUSE14,
+ K_MOUSE15,
+ K_MOUSE16,
+};
+
/* main window procedure */
LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
char state[256];
char asciichar[4];
int vkey;
+ int charlength;
qboolean down = false;
- extern unsigned int uiWheelMessage;
-
if ( uMsg == uiWheelMessage )
uMsg = WM_MOUSEWHEEL;
case WM_MOVE:
window_x = (int) LOWORD(lParam);
window_y = (int) HIWORD(lParam);
- VID_UpdateWindowStatus ();
+ VID_SetMouse(false, false, false);
break;
case WM_KEYDOWN:
GetKeyboardState (state);
// alt/ctrl/shift tend to produce funky ToAscii values,
// and if it's not a single character we don't know care about it
- if (vkey == K_ALT || vkey == K_CTRL || vkey == K_SHIFT || ToAscii (wParam, lParam >> 16, state, (unsigned short *)asciichar, 0) != 1)
+ charlength = ToAscii (wParam, lParam >> 16, state, (LPWORD)asciichar, 0);
+ if (vkey == K_ALT || vkey == K_CTRL || vkey == K_SHIFT || charlength == 0)
asciichar[0] = 0;
+ else if( charlength == 2 ) {
+ asciichar[0] = asciichar[1];
+ }
Key_Event (vkey, asciichar[0], down);
break;
// keep Alt-Space from happening
break;
+ case WM_SYSCOMMAND:
+ // prevent screensaver from occuring while the active window
+ // note: password-locked screensavers on Vista still work
+ if (vid_activewindow && ((wParam & 0xFFF0) == SC_SCREENSAVE || (wParam & 0xFFF0) == SC_MONITORPOWER))
+ lRet = 0;
+ else
+ lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
+ break;
+
// this is complicated because Win32 seems to pack multiple mouse events into
// one update sometimes, so we always check all states and look for events
case WM_LBUTTONDOWN:
if (wParam & MK_XBUTTON7)
temp |= 512;
- IN_MouseEvent (temp);
+#ifdef SUPPORTDIRECTX
+ if (vid_usingmouse && !dinput_acquired)
+#else
+ if (vid_usingmouse)
+#endif
+ {
+ // perform button actions
+ int i;
+ for (i=0 ; i<mouse_buttons && i < 16 ; i++)
+ if ((temp ^ mouse_oldbuttonstate) & (1<<i))
+ Key_Event (buttonremap[i], 0, (temp & (1<<i)) != 0);
+ mouse_oldbuttonstate = temp;
+ }
break;
case WM_CLOSE:
if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit", MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES)
- Sys_Quit ();
+ Sys_Quit (0);
break;
return lRet;
}
-int VID_SetGamma(unsigned short *ramps)
+int VID_SetGamma(unsigned short *ramps, int rampsize)
{
HDC hdc = GetDC (NULL);
int i = SetDeviceGammaRamp(hdc, ramps);
return i; // return success or failure
}
-int VID_GetGamma(unsigned short *ramps)
+int VID_GetGamma(unsigned short *ramps, int rampsize)
{
HDC hdc = GetDC (NULL);
int i = GetDeviceGammaRamp(hdc, ramps);
Con_Printf("Unable to LoadLibrary %s\n", name);
return false;
}
- strcpy(gl_driver, name);
+ strlcpy(gl_driver, name, sizeof(gl_driver));
return true;
}
return p;
}
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
+
static void IN_Init(void);
void VID_Init(void)
{
wc.lpszClassName = "DarkPlacesWindowClass";
if (!RegisterClass (&wc))
- Sys_Error("Couldn't register window class\n");
+ Con_Printf ("Couldn't register window class\n");
+
+ memset(&initialdevmode, 0, sizeof(initialdevmode));
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &initialdevmode);
IN_Init();
}
-int VID_InitMode (int fullscreen, int width, int height, int bpp)
+int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer, int samples)
{
int i;
HDC hdc;
0, // reserved
0, 0, 0 // layer masks ignored
};
- int pixelformat;
+ int windowpass;
+ int pixelformat, newpixelformat;
+ int numpixelformats;
DWORD WindowStyle, ExWindowStyle;
int CenterX, CenterY;
const char *gldrivername;
int depth;
+ DEVMODE thismode;
+ qboolean foundmode, foundgoodmode;
+ int *a;
+ float *af;
+ int attribs[128];
+ float attribsf[16];
if (vid_initialized)
- Sys_Error("VID_InitMode called when video is already initialised\n");
+ Sys_Error("VID_InitMode called when video is already initialised");
// if stencil is enabled, ask for alpha too
if (bpp >= 32)
{
- pfd.cStencilBits = 8;
+ pfd.cRedBits = 8;
+ pfd.cGreenBits = 8;
+ pfd.cBlueBits = 8;
pfd.cAlphaBits = 8;
+ pfd.cDepthBits = 24;
+ pfd.cStencilBits = 8;
}
else
{
- pfd.cStencilBits = 0;
+ pfd.cRedBits = 5;
+ pfd.cGreenBits = 5;
+ pfd.cBlueBits = 5;
pfd.cAlphaBits = 0;
+ pfd.cDepthBits = 16;
+ pfd.cStencilBits = 0;
+ }
+
+ if (stereobuffer)
+ pfd.dwFlags |= PFD_STEREO;
+
+ a = attribs;
+ af = attribsf;
+ *a++ = WGL_DRAW_TO_WINDOW_ARB;
+ *a++ = GL_TRUE;
+ *a++ = WGL_ACCELERATION_ARB;
+ *a++ = WGL_FULL_ACCELERATION_ARB;
+ *a++ = WGL_DOUBLE_BUFFER_ARB;
+ *a++ = true;
+
+ if (bpp >= 32)
+ {
+ *a++ = WGL_RED_BITS_ARB;
+ *a++ = 8;
+ *a++ = WGL_GREEN_BITS_ARB;
+ *a++ = 8;
+ *a++ = WGL_BLUE_BITS_ARB;
+ *a++ = 8;
+ *a++ = WGL_ALPHA_BITS_ARB;
+ *a++ = 8;
+ *a++ = WGL_DEPTH_BITS_ARB;
+ *a++ = 24;
+ *a++ = WGL_STENCIL_BITS_ARB;
+ *a++ = 8;
+ }
+ else
+ {
+ *a++ = WGL_RED_BITS_ARB;
+ *a++ = 1;
+ *a++ = WGL_GREEN_BITS_ARB;
+ *a++ = 1;
+ *a++ = WGL_BLUE_BITS_ARB;
+ *a++ = 1;
+ *a++ = WGL_DEPTH_BITS_ARB;
+ *a++ = 16;
}
+ if (stereobuffer)
+ {
+ *a++ = WGL_STEREO_ARB;
+ *a++ = GL_TRUE;
+ }
+
+ if (samples > 1)
+ {
+ *a++ = WGL_SAMPLE_BUFFERS_ARB;
+ *a++ = 1;
+ *a++ = WGL_SAMPLES_ARB;
+ *a++ = samples;
+ }
+
+ *a = 0;
+ *af = 0;
+
gldrivername = "opengl32.dll";
// COMMANDLINEOPTION: Windows WGL: -gl_driver <drivername> selects a GL driver library, default is opengl32.dll, useful only for 3dfxogl.dll or 3dfxvgl.dll, if you don't know what this is for, you don't need it
i = COM_CheckParm("-gl_driver");
vid_isfullscreen = false;
if (fullscreen)
{
- gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- gdevmode.dmBitsPerPel = bpp;
- gdevmode.dmPelsWidth = width;
- gdevmode.dmPelsHeight = height;
- gdevmode.dmSize = sizeof (gdevmode);
- if (ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
+ if(vid_forcerefreshrate.integer)
+ {
+ foundmode = true;
+ gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+ gdevmode.dmBitsPerPel = bpp;
+ gdevmode.dmPelsWidth = width;
+ gdevmode.dmPelsHeight = height;
+ gdevmode.dmSize = sizeof (gdevmode);
+ if(refreshrate)
+ {
+ gdevmode.dmFields |= DM_DISPLAYFREQUENCY;
+ gdevmode.dmDisplayFrequency = refreshrate;
+ }
+ }
+ else
+ {
+ if(refreshrate == 0)
+ refreshrate = initialdevmode.dmDisplayFrequency; // default vid_refreshrate to the rate of the desktop
+
+ foundmode = false;
+ foundgoodmode = false;
+
+ thismode.dmSize = sizeof(thismode);
+ thismode.dmDriverExtra = 0;
+ for(i = 0; EnumDisplaySettings(NULL, i, &thismode); ++i)
+ {
+ if(~thismode.dmFields & (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY))
+ {
+ Con_DPrintf("enumerating modes yielded a bogus item... please debug this\n");
+ continue;
+ }
+ if(developer.integer >= 100)
+ Con_Printf("Found mode %dx%dx%dbpp %dHz... ", (int)thismode.dmPelsWidth, (int)thismode.dmPelsHeight, (int)thismode.dmBitsPerPel, (int)thismode.dmDisplayFrequency);
+ if(thismode.dmBitsPerPel != (DWORD)bpp)
+ {
+ if(developer.integer >= 100)
+ Con_Printf("wrong bpp\n");
+ continue;
+ }
+ if(thismode.dmPelsWidth != (DWORD)width)
+ {
+ if(developer.integer >= 100)
+ Con_Printf("wrong width\n");
+ continue;
+ }
+ if(thismode.dmPelsHeight != (DWORD)height)
+ {
+ if(developer.integer >= 100)
+ Con_Printf("wrong height\n");
+ continue;
+ }
+
+ if(foundgoodmode)
+ {
+ // if we have a good mode, make sure this mode is better than the previous one, and allowed by the refreshrate
+ if(thismode.dmDisplayFrequency > (DWORD)refreshrate)
+ {
+ if(developer.integer >= 100)
+ Con_Printf("too high refresh rate\n");
+ continue;
+ }
+ else if(thismode.dmDisplayFrequency <= gdevmode.dmDisplayFrequency)
+ {
+ if(developer.integer >= 100)
+ Con_Printf("doesn't beat previous best match (too low)\n");
+ continue;
+ }
+ }
+ else if(foundmode)
+ {
+ // we do have one, but it isn't good... make sure it has a lower frequency than the previous one
+ if(thismode.dmDisplayFrequency >= gdevmode.dmDisplayFrequency)
+ {
+ if(developer.integer >= 100)
+ Con_Printf("doesn't beat previous best match (too high)\n");
+ continue;
+ }
+ }
+ // otherwise, take anything
+
+ memcpy(&gdevmode, &thismode, sizeof(gdevmode));
+ if(thismode.dmDisplayFrequency <= (DWORD)refreshrate)
+ foundgoodmode = true;
+ else
+ {
+ if(developer.integer >= 100)
+ Con_Printf("(out of range)\n");
+ }
+ foundmode = true;
+ if(developer.integer >= 100)
+ Con_Printf("accepted\n");
+ }
+ }
+
+ if (!foundmode)
+ {
+ VID_Shutdown();
+ Con_Printf("Unable to find the requested mode %dx%dx%dbpp\n", width, height, bpp);
+ return false;
+ }
+ else if(ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
VID_Shutdown();
Con_Printf("Unable to change to requested mode %dx%dx%dbpp\n", width, height, bpp);
// x and y may be changed by WM_MOVE messages
window_x = CenterX;
window_y = CenterY;
- window_width = width;
- window_height = height;
rect.left += CenterX;
rect.right += CenterX;
rect.top += CenterY;
rect.bottom += CenterY;
- mainwindow = CreateWindowEx (ExWindowStyle, "DarkPlacesWindowClass", gamename, WindowStyle, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, global_hInstance, NULL);
- if (!mainwindow)
+ pixelformat = 0;
+ newpixelformat = 0;
+ // start out at the final windowpass if samples is 1 as it's the only feature we need extended pixel formats for
+ for (windowpass = samples == 1;windowpass < 2;windowpass++)
{
- Con_Printf("CreateWindowEx(%d, %s, %s, %d, %d, %d, %d, %d, %p, %p, %d, %p) failed\n", ExWindowStyle, "DarkPlacesWindowClass", gamename, WindowStyle, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, global_hInstance, NULL);
- VID_Shutdown();
- return false;
+ gl_extensions = "";
+ gl_platformextensions = "";
+
+ mainwindow = CreateWindowEx (ExWindowStyle, "DarkPlacesWindowClass", gamename, WindowStyle, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, global_hInstance, NULL);
+ if (!mainwindow)
+ {
+ Con_Printf("CreateWindowEx(%d, %s, %s, %d, %d, %d, %d, %d, %p, %p, %d, %p) failed\n", (int)ExWindowStyle, "DarkPlacesWindowClass", gamename, (int)WindowStyle, (int)(rect.left), (int)(rect.top), (int)(rect.right - rect.left), (int)(rect.bottom - rect.top), NULL, NULL, (int)global_hInstance, NULL);
+ VID_Shutdown();
+ return false;
+ }
+
+ baseDC = GetDC(mainwindow);
+
+ if (!newpixelformat)
+ newpixelformat = ChoosePixelFormat(baseDC, &pfd);
+ pixelformat = newpixelformat;
+ if (!pixelformat)
+ {
+ VID_Shutdown();
+ Con_Printf("ChoosePixelFormat(%d, %p) failed\n", (int)baseDC, &pfd);
+ return false;
+ }
+
+ if (SetPixelFormat(baseDC, pixelformat, &pfd) == false)
+ {
+ VID_Shutdown();
+ Con_Printf("SetPixelFormat(%d, %d, %p) failed\n", (int)baseDC, pixelformat, &pfd);
+ return false;
+ }
+
+ if (!GL_CheckExtension("wgl", wglfuncs, NULL, false))
+ {
+ VID_Shutdown();
+ Con_Print("wgl functions not found\n");
+ return false;
+ }
+
+ baseRC = qwglCreateContext(baseDC);
+ if (!baseRC)
+ {
+ VID_Shutdown();
+ Con_Print("Could not initialize GL (wglCreateContext failed).\n\nMake sure you are in 65536 color mode, and try running -window.\n");
+ return false;
+ }
+ if (!qwglMakeCurrent(baseDC, baseRC))
+ {
+ VID_Shutdown();
+ Con_Printf("wglMakeCurrent(%d, %d) failed\n", (int)baseDC, (int)baseRC);
+ return false;
+ }
+
+ if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL)
+ {
+ VID_Shutdown();
+ Con_Print("glGetString not found\n");
+ return false;
+ }
+ if ((qwglGetExtensionsStringARB = (const char *(WINAPI *)(HDC hdc))GL_GetProcAddress("wglGetExtensionsStringARB")) == NULL)
+ Con_Print("wglGetExtensionsStringARB not found\n");
+
+ gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
+ gl_platform = "WGL";
+ gl_platformextensions = "";
+
+ if (qwglGetExtensionsStringARB)
+ gl_platformextensions = (const char *)qwglGetExtensionsStringARB(baseDC);
+
+ if (!gl_extensions)
+ gl_extensions = "";
+ if (!gl_platformextensions)
+ gl_platformextensions = "";
+
+ // now some nice Windows pain:
+ // we have created a window, we needed one to find out if there are
+ // any multisample pixel formats available, the problem is that to
+ // actually use one of those multisample formats we now have to
+ // recreate the window (yes Microsoft OpenGL really is that bad)
+
+ if (windowpass == 0)
+ {
+ if (!GL_CheckExtension("WGL_ARB_pixel_format", wglpixelformatfuncs, "-noarbpixelformat", false) || !qwglChoosePixelFormatARB(baseDC, attribs, attribsf, 1, &newpixelformat, &numpixelformats) || !newpixelformat)
+ break;
+ // ok we got one - do it all over again with newpixelformat
+ qwglMakeCurrent(NULL, NULL);
+ qwglDeleteContext(baseRC);baseRC = 0;
+ ReleaseDC(mainwindow, baseDC);baseDC = 0;
+ // eat up any messages waiting for us
+ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage (&msg);
+ DispatchMessage (&msg);
+ }
+ }
}
/*
ShowWindow (mainwindow, SW_SHOWDEFAULT);
UpdateWindow (mainwindow);
- VID_UpdateWindowStatus ();
-
// now we try to make sure we get the focus on the mode switch, because
// sometimes in some systems we don't. We grab the foreground, then
// finish setting up, pump all our messages, and sleep for a little while
// fix the leftover Alt from any Alt-Tab or the like that switched us away
ClearAllStates ();
- baseDC = GetDC(mainwindow);
-
- if ((pixelformat = ChoosePixelFormat(baseDC, &pfd)) == 0)
- {
- VID_Shutdown();
- Con_Printf("ChoosePixelFormat(%d, %p) failed\n", baseDC, &pfd);
- return false;
- }
-
- if (SetPixelFormat(baseDC, pixelformat, &pfd) == false)
- {
- VID_Shutdown();
- Con_Printf("SetPixelFormat(%d, %d, %p) failed\n", baseDC, pixelformat, &pfd);
- return false;
- }
-
- if (!GL_CheckExtension("wgl", wglfuncs, NULL, false))
- {
- VID_Shutdown();
- Con_Print("wgl functions not found\n");
- return false;
- }
-
- baseRC = qwglCreateContext(baseDC);
- if (!baseRC)
- {
- VID_Shutdown();
- Con_Print("Could not initialize GL (wglCreateContext failed).\n\nMake sure you are in 65536 color mode, and try running -window.\n");
- return false;
- }
- if (!qwglMakeCurrent(baseDC, baseRC))
- {
- VID_Shutdown();
- Con_Printf("wglMakeCurrent(%d, %d) failed\n", baseDC, baseRC);
- return false;
- }
-
- qglGetString = GL_GetProcAddress("glGetString");
- qwglGetExtensionsStringARB = GL_GetProcAddress("wglGetExtensionsStringARB");
- if (qglGetString == NULL)
- {
- VID_Shutdown();
- Con_Print("glGetString not found\n");
- return false;
- }
- gl_renderer = qglGetString(GL_RENDERER);
- gl_vendor = qglGetString(GL_VENDOR);
- gl_version = qglGetString(GL_VERSION);
- gl_extensions = qglGetString(GL_EXTENSIONS);
- gl_platform = "WGL";
- gl_platformextensions = "";
-
gl_videosyncavailable = false;
- if (qwglGetExtensionsStringARB)
- gl_platformextensions = qwglGetExtensionsStringARB(baseDC);
-
// COMMANDLINEOPTION: Windows WGL: -novideosync disables WGL_EXT_swap_control
gl_videosyncavailable = GL_CheckExtension("WGL_EXT_swap_control", wglswapintervalfuncs, "-novideosync", false);
- //ReleaseDC(mainwindow, hdc);
GL_Init ();
- // LordHavoc: special differences for ATI (broken 8bit color when also using 32bit? weird!)
- if (strncasecmp(gl_vendor,"ATI",3)==0)
- {
- if (strncasecmp(gl_renderer,"Rage Pro",8)==0)
- isRagePro = true;
- }
- if (strncasecmp(gl_renderer,"Matrox G200 Direct3D",20)==0) // a D3D driver for GL? sigh...
- isG200 = true;
-
//vid_menudrawfn = VID_MenuDraw;
//vid_menukeyfn = VID_MenuKey;
vid_usingmouse = false;
+ vid_usinghidecursor = false;
vid_usingvsync = false;
vid_hidden = false;
vid_initialized = true;
IN_StartupMouse ();
IN_StartupJoystick ();
+ if (gl_videosyncavailable)
+ {
+ vid_usevsync = vid_vsync.integer;
+ vid_usingvsync = vid_vsync.integer;
+ qwglSwapIntervalEXT (vid_usevsync);
+ }
+
return true;
}
if(vid_initialized == false)
return;
+ VID_SetMouse(false, false, false);
VID_RestoreSystemGamma();
vid_initialized = false;
vid_isfullscreen = false;
}
-
-/*
-===========
-IN_ShowMouse
-===========
-*/
-void IN_ShowMouse (void)
-{
- if (!mouseshowtoggle)
- {
- ShowCursor (true);
- mouseshowtoggle = 1;
- }
-}
-
-
-/*
-===========
-IN_HideMouse
-===========
-*/
-void IN_HideMouse (void)
-{
- if (mouseshowtoggle)
- {
- ShowCursor (false);
- mouseshowtoggle = 0;
- }
-}
-
-
-/*
-===========
-IN_ActivateMouse
-===========
-*/
-void IN_ActivateMouse (void)
+void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecursor)
{
+ static qboolean restore_spi;
+ static int originalmouseparms[3];
- mouseactivatetoggle = true;
+ if (!mouseinitialized)
+ return;
- if (mouseinitialized)
+ if (relative)
{
- if (dinput)
+ if (!vid_usingmouse)
{
- if (g_pMouse)
+ vid_usingmouse = true;
+ cl_ignoremousemoves = 2;
+#ifdef SUPPORTDIRECTX
+ if (dinput && g_pMouse)
{
- if (!dinput_acquired)
- {
- IDirectInputDevice_Acquire(g_pMouse);
- dinput_acquired = true;
- }
+ IDirectInputDevice_Acquire(g_pMouse);
+ dinput_acquired = true;
}
else
+#endif
{
- return;
+ RECT window_rect;
+ window_rect.left = window_x;
+ window_rect.top = window_y;
+ window_rect.right = window_x + vid.width;
+ window_rect.bottom = window_y + vid.height;
+
+ // change mouse settings to turn off acceleration
+// COMMANDLINEOPTION: Windows GDI Input: -noforcemparms disables setting of mouse parameters (not used with -dinput, windows only)
+ if (!COM_CheckParm ("-noforcemparms") && SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0))
+ {
+ int newmouseparms[3];
+ newmouseparms[0] = 0; // threshold to double movement (only if accel level is >= 1)
+ newmouseparms[1] = 0; // threshold to quadruple movement (only if accel level is >= 2)
+ newmouseparms[2] = 0; // maximum level of acceleration (0 = off)
+ restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0);
+ }
+ else
+ restore_spi = false;
+ SetCursorPos ((window_x + vid.width / 2), (window_y + vid.height / 2));
+
+ SetCapture (mainwindow);
+ ClipCursor (&window_rect);
}
}
- else
- {
- RECT window_rect;
- window_rect.left = window_x;
- window_rect.top = window_y;
- window_rect.right = window_x + window_width;
- window_rect.bottom = window_y + window_height;
-
- if (mouseparmsvalid)
- restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0);
-
- SetCursorPos (window_center_x, window_center_y);
- SetCapture (mainwindow);
- ClipCursor (&window_rect);
- }
-
- mouseactive = true;
}
-}
-
-
-/*
-===========
-IN_DeactivateMouse
-===========
-*/
-void IN_DeactivateMouse (void)
-{
-
- mouseactivatetoggle = false;
-
- if (mouseinitialized)
+ else
{
- if (dinput)
+ if (vid_usingmouse)
{
- if (g_pMouse)
+ vid_usingmouse = false;
+ cl_ignoremousemoves = 2;
+#ifdef SUPPORTDIRECTX
+ if (dinput_acquired)
{
- if (dinput_acquired)
- {
- IDirectInputDevice_Unacquire(g_pMouse);
- dinput_acquired = false;
- }
+ IDirectInputDevice_Unacquire(g_pMouse);
+ dinput_acquired = false;
+ }
+ else
+#endif
+ {
+ // restore system mouseparms if we changed them
+ if (restore_spi)
+ SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0);
+ restore_spi = false;
+ ClipCursor (NULL);
+ ReleaseCapture ();
}
}
- else
- {
- if (restore_spi)
- SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0);
-
- ClipCursor (NULL);
- ReleaseCapture ();
- }
+ }
- mouseactive = false;
+ if (vid_usinghidecursor != hidecursor)
+ {
+ vid_usinghidecursor = hidecursor;
+ ShowCursor (!hidecursor);
}
}
+#ifdef SUPPORTDIRECTX
/*
===========
IN_InitDInput
===========
*/
-qboolean IN_InitDInput (void)
+static qboolean IN_InitDInput (void)
{
HRESULT hr;
DIPROPDWORD dipdw = {
}
// set the data format to "mouse format".
- hr = IDirectInputDevice_SetDataFormat(g_pMouse, &df);
+ hr = IDirectInputDevice_SetDataFormat(g_pMouse, &c_dfDIMouse);
if (FAILED(hr))
{
return true;
}
+#endif
/*
IN_StartupMouse
===========
*/
-void IN_StartupMouse (void)
+static void IN_StartupMouse (void)
{
- if (COM_CheckParm ("-nomouse") || COM_CheckParm("-safe"))
+ if (COM_CheckParm ("-nomouse"))
return;
mouseinitialized = true;
+#ifdef SUPPORTDIRECTX
// COMMANDLINEOPTION: Windows Input: -dinput enables DirectInput for mouse/joystick input
if (COM_CheckParm ("-dinput"))
- {
dinput = IN_InitDInput ();
- if (dinput)
- {
- Con_Print("DirectInput initialized\n");
- }
- else
- {
- Con_Print("DirectInput not initialized\n");
- }
- }
-
- if (!dinput)
- {
- mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0);
-
- if (mouseparmsvalid)
- {
-// COMMANDLINEOPTION: Windows GDI Input: -noforcemspd disables setting of mouse speed (not used with -dinput, windows only)
- if ( COM_CheckParm ("-noforcemspd") )
- newmouseparms[2] = originalmouseparms[2];
-
-// COMMANDLINEOPTION: Windows GDI Input: -noforcemaccel disables setting of mouse acceleration (not used with -dinput, windows only)
- if ( COM_CheckParm ("-noforcemaccel") )
- {
- newmouseparms[0] = originalmouseparms[0];
- newmouseparms[1] = originalmouseparms[1];
- }
-
-// COMMANDLINEOPTION: Windows GDI Input: -noforcemparms disables setting of mouse parameters (not used with -dinput, windows only)
- if ( COM_CheckParm ("-noforcemparms") )
- {
- newmouseparms[0] = originalmouseparms[0];
- newmouseparms[1] = originalmouseparms[1];
- newmouseparms[2] = originalmouseparms[2];
- }
- }
- }
+ if (dinput)
+ Con_Print("DirectInput initialized\n");
+ else
+ Con_Print("DirectInput not initialized\n");
+#endif
mouse_buttons = 10;
-
-// if a fullscreen video mode was set before the mouse was initialized,
-// set the mouse state appropriately
- if (mouseactivatetoggle)
- IN_ActivateMouse ();
-}
-
-
-/*
-===========
-IN_MouseEvent
-===========
-*/
-void IN_MouseEvent (int mstate)
-{
- int i;
-
- if (mouseactive && !dinput)
- {
- // perform button actions
- for (i=0 ; i<mouse_buttons ; i++)
- {
- if ( (mstate & (1<<i)) &&
- !(mouse_oldbuttonstate & (1<<i)) )
- {
- Key_Event (K_MOUSE1 + i, 0, true);
- }
-
- if ( !(mstate & (1<<i)) &&
- (mouse_oldbuttonstate & (1<<i)) )
- {
- Key_Event (K_MOUSE1 + i, 0, false);
- }
- }
-
- mouse_oldbuttonstate = mstate;
- }
}
IN_MouseMove
===========
*/
-void IN_MouseMove (void)
+static void IN_MouseMove (void)
{
- int i, mx, my;
- DIDEVICEOBJECTDATA od;
- DWORD dwElements;
- HRESULT hr;
+ POINT current_pos;
- if (!mouseactive)
- {
- GetCursorPos (¤t_pos);
- //ui_mouseupdate(current_pos.x - window_x, current_pos.y - window_y);
- IN_Mouse( 0, 0 );
+ GetCursorPos (¤t_pos);
+ in_windowmouse_x = current_pos.x - window_x;
+ in_windowmouse_y = current_pos.y - window_y;
+
+ if (!vid_usingmouse)
return;
- }
- if (dinput)
+#ifdef SUPPORTDIRECTX
+ if (dinput_acquired)
{
- mx = 0;
- my = 0;
+ int i;
+ DIDEVICEOBJECTDATA od;
+ DWORD dwElements;
+ HRESULT hr;
for (;;)
{
if ((hr == DIERR_INPUTLOST) || (hr == DIERR_NOTACQUIRED))
{
- dinput_acquired = true;
IDirectInputDevice_Acquire(g_pMouse);
break;
}
switch (od.dwOfs)
{
case DIMOFS_X:
- mx += od.dwData;
+ in_mouse_x += (LONG) od.dwData;
break;
case DIMOFS_Y:
- my += od.dwData;
+ in_mouse_y += (LONG) od.dwData;
+ break;
+
+ case DIMOFS_Z:
+ if((LONG) od.dwData < 0)
+ {
+ Key_Event (K_MWHEELDOWN, 0, true);
+ Key_Event (K_MWHEELDOWN, 0, false);
+ }
+ else if((LONG) od.dwData > 0)
+ {
+ Key_Event (K_MWHEELUP, 0, true);
+ Key_Event (K_MWHEELUP, 0, false);
+ }
break;
case DIMOFS_BUTTON0:
else
mstate_di &= ~(1<<2);
break;
- }
- }
-
- // perform button actions
- for (i=0 ; i<mouse_buttons ; i++)
- {
- if ( (mstate_di & (1<<i)) &&
- !(mouse_oldbuttonstate & (1<<i)) )
- {
- Key_Event (K_MOUSE1 + i, 0, true);
- }
- if ( !(mstate_di & (1<<i)) &&
- (mouse_oldbuttonstate & (1<<i)) )
- {
- Key_Event (K_MOUSE1 + i, 0, false);
+ case DIMOFS_BUTTON3:
+ if (od.dwData & 0x80)
+ mstate_di |= (1<<3);
+ else
+ mstate_di &= ~(1<<3);
+ break;
}
}
+ // perform button actions
+ for (i=0 ; i<mouse_buttons && i < 16 ; i++)
+ if ((mstate_di ^ mouse_oldbuttonstate) & (1<<i))
+ Key_Event (buttonremap[i], 0, (mstate_di & (1<<i)) != 0);
mouse_oldbuttonstate = mstate_di;
}
else
+#endif
{
- GetCursorPos (¤t_pos);
- mx = current_pos.x - window_center_x;
- my = current_pos.y - window_center_y;
- }
-
- IN_Mouse(mx, my);
+ in_mouse_x += in_windowmouse_x - (int)(vid.width / 2);
+ in_mouse_y += in_windowmouse_y - (int)(vid.height / 2);
- // if the mouse has moved, force it to the center, so there's room to move
- if (!dinput && (mx || my))
- SetCursorPos (window_center_x, window_center_y);
+ // if the mouse has moved, force it to the center, so there's room to move
+ if (in_mouse_x || in_mouse_y)
+ SetCursorPos ((window_x + vid.width / 2), (window_y + vid.height / 2));
+ }
}
}
-/*
-===================
-IN_ClearStates
-===================
-*/
-void IN_ClearStates (void)
-{
- if (mouseactive)
- mouse_oldbuttonstate = 0;
-}
-
-
/*
===============
IN_StartupJoystick
===============
*/
-void IN_StartupJoystick (void)
+static void IN_StartupJoystick (void)
{
int numdevs;
JOYCAPS jc;
// abort startup if user requests no joystick
// COMMANDLINEOPTION: Windows Input: -nojoy disables joystick support, may be a small speed increase
- if (COM_CheckParm ("-nojoy") || COM_CheckParm("-safe"))
+ if (COM_CheckParm ("-nojoy"))
return;
// verify joystick driver is present
RawValuePointer
===========
*/
-PDWORD RawValuePointer (int axis)
+static PDWORD RawValuePointer (int axis)
{
switch (axis)
{
Joy_AdvancedUpdate_f
===========
*/
-void Joy_AdvancedUpdate_f (void)
+static void Joy_AdvancedUpdate_f (void)
{
// called once by IN_ReadJoystick and by user whenever an update is needed
}
}
-/*
-===========
-IN_Commands
-===========
-*/
-void IN_Commands (void)
-{
- int i, key_index;
- DWORD buttonstate, povstate;
-
- if (!joy_avail)
- {
- return;
- }
-
-
- // loop through the joystick buttons
- // key a joystick event or auxillary event for higher number buttons for each state change
- buttonstate = ji.dwButtons;
- for (i=0 ; i < (int) joy_numbuttons ; i++)
- {
- if ( (buttonstate & (1<<i)) && !(joy_oldbuttonstate & (1<<i)) )
- {
- key_index = (i < 16) ? K_JOY1 : K_AUX1;
- Key_Event (key_index + i, 0, true);
- }
-
- if ( !(buttonstate & (1<<i)) && (joy_oldbuttonstate & (1<<i)) )
- {
- key_index = (i < 16) ? K_JOY1 : K_AUX1;
- Key_Event (key_index + i, 0, false);
- }
- }
- joy_oldbuttonstate = buttonstate;
-
- if (joy_haspov)
- {
- // convert POV information into 4 bits of state information
- // this avoids any potential problems related to moving from one
- // direction to another without going through the center position
- povstate = 0;
- if(ji.dwPOV != JOY_POVCENTERED)
- {
- if (ji.dwPOV == JOY_POVFORWARD)
- povstate |= 0x01;
- if (ji.dwPOV == JOY_POVRIGHT)
- povstate |= 0x02;
- if (ji.dwPOV == JOY_POVBACKWARD)
- povstate |= 0x04;
- if (ji.dwPOV == JOY_POVLEFT)
- povstate |= 0x08;
- }
- // determine which bits have changed and key an auxillary event for each change
- for (i=0 ; i < 4 ; i++)
- {
- if ( (povstate & (1<<i)) && !(joy_oldpovstate & (1<<i)) )
- {
- Key_Event (K_AUX29 + i, 0, true);
- }
-
- if ( !(povstate & (1<<i)) && (joy_oldpovstate & (1<<i)) )
- {
- Key_Event (K_AUX29 + i, 0, false);
- }
- }
- joy_oldpovstate = povstate;
- }
-}
-
-
/*
===============
IN_ReadJoystick
===============
*/
-qboolean IN_ReadJoystick (void)
+static qboolean IN_ReadJoystick (void)
{
memset (&ji, 0, sizeof(ji));
IN_JoyMove
===========
*/
-void IN_JoyMove (void)
+static void IN_JoyMove (void)
{
float speed, aspeed;
float fAxisValue, fTemp;
joy_advancedinit = true;
}
+ if (joy_avail)
+ {
+ int i, key_index;
+ DWORD buttonstate, povstate;
+
+ // loop through the joystick buttons
+ // key a joystick event or auxillary event for higher number buttons for each state change
+ buttonstate = ji.dwButtons;
+ for (i=0 ; i < (int) joy_numbuttons ; i++)
+ {
+ if ( (buttonstate & (1<<i)) && !(joy_oldbuttonstate & (1<<i)) )
+ {
+ key_index = (i < 16) ? K_JOY1 : K_AUX1;
+ Key_Event (key_index + i, 0, true);
+ }
+
+ if ( !(buttonstate & (1<<i)) && (joy_oldbuttonstate & (1<<i)) )
+ {
+ key_index = (i < 16) ? K_JOY1 : K_AUX1;
+ Key_Event (key_index + i, 0, false);
+ }
+ }
+ joy_oldbuttonstate = buttonstate;
+
+ if (joy_haspov)
+ {
+ // convert POV information into 4 bits of state information
+ // this avoids any potential problems related to moving from one
+ // direction to another without going through the center position
+ povstate = 0;
+ if(ji.dwPOV != JOY_POVCENTERED)
+ {
+ if (ji.dwPOV == JOY_POVFORWARD)
+ povstate |= 0x01;
+ if (ji.dwPOV == JOY_POVRIGHT)
+ povstate |= 0x02;
+ if (ji.dwPOV == JOY_POVBACKWARD)
+ povstate |= 0x04;
+ if (ji.dwPOV == JOY_POVLEFT)
+ povstate |= 0x08;
+ }
+ // determine which bits have changed and key an auxillary event for each change
+ for (i=0 ; i < 4 ; i++)
+ {
+ if ( (povstate & (1<<i)) && !(joy_oldpovstate & (1<<i)) )
+ {
+ Key_Event (K_AUX29 + i, 0, true);
+ }
+
+ if ( !(povstate & (1<<i)) && (joy_oldpovstate & (1<<i)) )
+ {
+ Key_Event (K_AUX29 + i, 0, false);
+ }
+ }
+ joy_oldpovstate = povstate;
+ }
+ }
+
// verify joystick is available and that the user wants to use it
if (!joy_avail || !in_joystick.integer)
{
else
speed = 1;
// LordHavoc: viewzoom affects sensitivity for sniping
- aspeed = speed * host_realframetime * cl.viewzoom;
+ aspeed = speed * cl.realframetime * cl.viewzoom;
// loop through the axes
for (i = 0; i < JOY_MAX_AXES; i++)
Cvar_RegisterVariable (&joy_yawsensitivity);
Cvar_RegisterVariable (&joy_wwhack1);
Cvar_RegisterVariable (&joy_wwhack2);
- Cmd_AddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f);
+ Cvar_RegisterVariable (&vid_forcerefreshrate);
+ Cmd_AddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f, "applies current joyadv* cvar settings to the joystick driver");
}
static void IN_Shutdown(void)
{
- IN_DeactivateMouse ();
- IN_ShowMouse ();
-
+#ifdef SUPPORTDIRECTX
if (g_pMouse)
IDirectInputDevice_Release(g_pMouse);
g_pMouse = NULL;
if (g_pdi)
IDirectInput_Release(g_pdi);
g_pdi = NULL;
+#endif
}