#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;
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_usevsync = false;
static HICON hIcon;
static int window_x, window_y;
-static void IN_Activate (qboolean grab);
-
static qboolean mouseinitialized;
-static qboolean dinput;
-
-// input code
+#ifdef SUPPORTDIRECTX
+static qboolean dinput;
#define DINPUT_BUFFERSIZE 16
#define iDirectInputCreate(a,b,c,d) pDirectInputCreate(a,b,c,d)
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
static int mouse_buttons;
static int mouse_oldbuttonstate;
-static qboolean restore_spi;
-static int originalmouseparms[3], newmouseparms[3] = {0, 0, 0};
-
static unsigned int uiWheelMessage;
-static qboolean mouseparmsvalid;
+#ifdef SUPPORTDIRECTX
static qboolean dinput_acquired;
static unsigned int mstate_di;
+#endif
// joystick defines and variables
// where should defines be moved?
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 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
static void IN_StartupJoystick (void);
//====================================
-void VID_Finish (qboolean allowmousegrab)
+void VID_Finish (void)
{
- qboolean vid_usemouse;
-
vid_usevsync = vid_vsync.integer && !cls.timedemo && gl_videosyncavailable;
if (vid_usingvsync != vid_usevsync && gl_videosyncavailable)
{
qwglSwapIntervalEXT (vid_usevsync);
}
-// handle the mouse state when windowed if that's changed
- vid_usemouse = false;
- if (allowmousegrab && vid_mouse.integer && !key_consoleactive && !cls.demoplayback)
- vid_usemouse = true;
- if (vid_isfullscreen)
- vid_usemouse = true;
- if (!vid_activewindow)
- vid_usemouse = false;
- IN_Activate(vid_usemouse);
-
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);
}
*
****************************************************************************/
{
- 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)
{
- IN_Activate (false);
+ 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 lRet = 1;
int fActive, fMinimized, temp;
- char state[256];
- char asciichar[4];
+ unsigned char state[256];
+ unsigned char asciichar[4];
int vkey;
int charlength;
qboolean down = false;
case WM_MOVE:
window_x = (int) LOWORD(lParam);
window_y = (int) HIWORD(lParam);
- IN_Activate(false);
+ 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
- charlength = ToAscii (wParam, lParam >> 16, state, (unsigned short *)asciichar, 0);
+ 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 ) {
// 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;
- if (vid_usingmouse && !dinput_acquired)
+#ifdef SUPPORTDIRECTX
+ if (!dinput_acquired)
+#endif
{
// perform button actions
int i;
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;
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)
{
if (!RegisterClass (&wc))
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 refreshrate)
+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;
+ UINT 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");
// 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 | DM_DISPLAYFREQUENCY;
- gdevmode.dmBitsPerPel = bpp;
- gdevmode.dmPelsWidth = width;
- gdevmode.dmPelsHeight = height;
- gdevmode.dmDisplayFrequency = refreshrate;
- 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 change to requested mode %dx%dx%dbpp\n", width, height, bpp);
+ 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);
return false;
}
rect.top = 0;
rect.left = 0;
- rect.right = width;
- rect.bottom = height;
+ rect.right = *width;
+ rect.bottom = *height;
AdjustWindowRectEx(&rect, WindowStyle, false, 0);
if (fullscreen)
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);
+ }
+ }
}
/*
// 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;
- }
-
- 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_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;
if(vid_initialized == false)
return;
+ VID_SetMouse(false, false, false);
VID_RestoreSystemGamma();
vid_initialized = false;
vid_isfullscreen = false;
}
-static void IN_Activate (qboolean grab)
+void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecursor)
{
+ static qboolean restore_spi;
+ static int originalmouseparms[3];
+
if (!mouseinitialized)
return;
- if (grab)
+ if (relative)
{
if (!vid_usingmouse)
{
vid_usingmouse = true;
- cl_ignoremousemove = true;
+ cl_ignoremousemoves = 2;
+#ifdef SUPPORTDIRECTX
if (dinput && g_pMouse)
{
IDirectInputDevice_Acquire(g_pMouse);
dinput_acquired = true;
}
else
+#endif
{
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;
- if (mouseparmsvalid)
+
+ // 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);
}
- ShowCursor (false);
}
}
else
if (vid_usingmouse)
{
vid_usingmouse = false;
- cl_ignoremousemove = true;
+ cl_ignoremousemoves = 2;
+#ifdef SUPPORTDIRECTX
if (dinput_acquired)
{
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 ();
}
- ShowCursor (true);
}
}
+
+ if (vid_usinghidecursor != hidecursor)
+ {
+ vid_usinghidecursor = hidecursor;
+ ShowCursor (!hidecursor);
+ }
}
+#ifdef SUPPORTDIRECTX
/*
===========
IN_InitDInput
}
// 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
/*
*/
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 ();
Con_Print("DirectInput initialized\n");
else
Con_Print("DirectInput not initialized\n");
-
- 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];
- }
- }
+#endif
mouse_buttons = 10;
}
*/
static void IN_MouseMove (void)
{
- int i, mx, my;
POINT current_pos;
+ GetCursorPos (¤t_pos);
+ in_windowmouse_x = current_pos.x - window_x;
+ in_windowmouse_y = current_pos.y - window_y;
+
if (!vid_usingmouse)
- {
- //GetCursorPos (¤t_pos);
- //ui_mouseupdate(current_pos.x - window_x, current_pos.y - window_y);
return;
- }
+#ifdef SUPPORTDIRECTX
if (dinput_acquired)
{
+ int i;
DIDEVICEOBJECTDATA od;
DWORD dwElements;
HRESULT hr;
- mx = 0;
- my = 0;
for (;;)
{
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;
+
+ case DIMOFS_BUTTON3:
+ if (od.dwData & 0x80)
+ mstate_di |= (1<<3);
+ else
+ mstate_di &= ~(1<<3);
+ break;
}
}
if ((mstate_di ^ mouse_oldbuttonstate) & (1<<i))
Key_Event (buttonremap[i], 0, (mstate_di & (1<<i)) != 0);
mouse_oldbuttonstate = mstate_di;
-
- in_mouse_x = mx;
- in_mouse_y = my;
}
else
+#endif
{
- GetCursorPos (¤t_pos);
- mx = current_pos.x - (window_x + vid.width / 2);
- my = current_pos.y - (window_y + vid.height / 2);
-
- in_mouse_x = mx;
- in_mouse_y = 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 (!cl.csqc_wantsmousemove)
- if (mx || my)
+ if (in_mouse_x || in_mouse_y)
SetCursorPos ((window_x + vid.width / 2), (window_y + vid.height / 2));
}
}
// 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
Cvar_RegisterVariable (&joy_yawsensitivity);
Cvar_RegisterVariable (&joy_wwhack1);
Cvar_RegisterVariable (&joy_wwhack2);
+ 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_Activate (false);
-
+#ifdef SUPPORTDIRECTX
if (g_pMouse)
IDirectInputDevice_Release(g_pMouse);
g_pMouse = NULL;
if (g_pdi)
IDirectInput_Release(g_pdi);
g_pdi = NULL;
+#endif
}