]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - vid_wgl.c
implemented vid_samples cvar (antialiasing samples per pixel)
[xonotic/darkplaces.git] / vid_wgl.c
index 79505efd6d429ef06420c41744cb62560ad4704d..88cc6814fa86a398ffc597527827e271902c17f1 100644 (file)
--- a/vid_wgl.c
+++ b/vid_wgl.c
@@ -55,6 +55,8 @@ 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[] =
 {
@@ -78,7 +80,14 @@ static dllfunction_t wglswapintervalfuncs[] =
        {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;
@@ -131,6 +140,8 @@ static HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, LP
 #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
@@ -144,11 +155,7 @@ static HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, LP
 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;
 static qboolean        dinput_acquired;
 
 static unsigned int            mstate_di;
@@ -204,6 +211,8 @@ static cvar_t joy_yawsensitivity = {0, "joyyawsensitivity", "-1.0", "how fast th
 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;
 
@@ -218,39 +227,6 @@ static JOYINFOEX   ji;
 
 static HINSTANCE hInstDI;
 
-//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
-};
-
 // forward-referenced functions
 static void IN_StartupJoystick (void);
 static void Joy_AdvancedUpdate_f (void);
@@ -417,16 +393,22 @@ void AppActivate(BOOL fActive, BOOL minimize)
        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)
@@ -546,6 +528,12 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM  wParam, LPARAM lParam)
                // keep Alt-Space from happening
                        break;
 
+               case WM_SYSCOMMAND:
+                       // prevent screensaver from occuring while the active window
+                       if (vid_activewindow && ((wParam & 0xFFF0) == SC_SCREENSAVE || (wParam & 0xFFF0) == SC_MONITORPOWER))
+                               lRet = 0;; // note: password-locked screensavers on Vista still work
+                       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:
@@ -702,6 +690,64 @@ void *GL_GetProcAddress(const char *name)
        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)
 {
@@ -725,10 +771,13 @@ 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 stereobuffer)
+int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer, int samples)
 {
        int i;
        HDC hdc;
@@ -755,11 +804,19 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrat
                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");
@@ -779,6 +836,59 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrat
        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++ = 1;
+               *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");
@@ -795,13 +905,107 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrat
        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 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);
@@ -862,14 +1066,106 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrat
        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;
+       for (windowpass = 0;windowpass < 2;windowpass++)
        {
-               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;
+               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_renderer = qglGetString(GL_RENDERER);
+               gl_vendor = qglGetString(GL_VENDOR);
+               gl_version = qglGetString(GL_VERSION);
+               gl_extensions = qglGetString(GL_EXTENSIONS);
+               gl_platform = "WGL";
+               gl_platformextensions = "";
+
+               if (qwglGetExtensionsStringARB)
+                       gl_platformextensions = qwglGetExtensionsStringARB(baseDC);
+
+               // 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);
+                       }
+               }
        }
 
+       Con_DPrintf("GL_VENDOR: %s\n", gl_vendor);
+       Con_DPrintf("GL_RENDERER: %s\n", gl_renderer);
+       Con_DPrintf("GL_VERSION: %s\n", gl_version);
+       Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
+       Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
+
        /*
        if (!fullscreen)
                SetWindowPos (mainwindow, NULL, CenterX, CenterY, 0, 0,SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME);
@@ -901,78 +1197,13 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrat
        // 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", (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_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;
@@ -1022,6 +1253,9 @@ void VID_Shutdown (void)
 
 static void IN_Activate (qboolean grab)
 {
+       static qboolean restore_spi;
+       static int originalmouseparms[3];
+
        if (!mouseinitialized)
                return;
 
@@ -1030,7 +1264,7 @@ static void IN_Activate (qboolean grab)
                if (!vid_usingmouse)
                {
                        vid_usingmouse = true;
-                       cl_ignoremousemove = true;
+                       cl_ignoremousemoves = 2;
                        if (dinput && g_pMouse)
                        {
                                IDirectInputDevice_Acquire(g_pMouse);
@@ -1043,9 +1277,21 @@ static void IN_Activate (qboolean grab)
                                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);
                        }
@@ -1057,7 +1303,7 @@ static void IN_Activate (qboolean grab)
                if (vid_usingmouse)
                {
                        vid_usingmouse = false;
-                       cl_ignoremousemove = true;
+                       cl_ignoremousemoves = 2;
                        if (dinput_acquired)
                        {
                                IDirectInputDevice_Unacquire(g_pMouse);
@@ -1065,8 +1311,10 @@ static void IN_Activate (qboolean grab)
                        }
                        else
                        {
+                               // restore system mouseparms if we changed them
                                if (restore_spi)
                                        SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0);
+                               restore_spi = false;
                                ClipCursor (NULL);
                                ReleaseCapture ();
                        }
@@ -1134,7 +1382,7 @@ static qboolean IN_InitDInput (void)
        }
 
 // set the data format to "mouse format".
-       hr = IDirectInputDevice_SetDataFormat(g_pMouse, &df);
+       hr = IDirectInputDevice_SetDataFormat(g_pMouse, &c_dfDIMouse);
 
        if (FAILED(hr))
        {
@@ -1188,30 +1436,6 @@ static void IN_StartupMouse (void)
        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];
-               }
-       }
-
        mouse_buttons = 10;
 }
 
@@ -1263,11 +1487,24 @@ static void IN_MouseMove (void)
                        switch (od.dwOfs)
                        {
                                case DIMOFS_X:
-                                       mx += od.dwData;
+                                       mx += (LONG) od.dwData;
                                        break;
 
                                case DIMOFS_Y:
-                                       my += od.dwData;
+                                       my += (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:
@@ -1290,6 +1527,13 @@ static void IN_MouseMove (void)
                                        else
                                                mstate_di &= ~(1<<2);
                                        break;
+
+                               case DIMOFS_BUTTON3:
+                                       if (od.dwData & 0x80)
+                                               mstate_di |= (1<<3);
+                                       else
+                                               mstate_di &= ~(1<<3);
+                                       break;
                        }
                }
 
@@ -1790,6 +2034,7 @@ static void IN_Init(void)
        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");
 }