]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - vid_wgl.c
Add an in_releaseall command for debugging/working around stuck keys.
[xonotic/darkplaces.git] / vid_wgl.c
index 167e6ea7573dae6d708b0da50cd3e492396c8eed..7a4840886f0165fae39591890a582419c42a50a7 100644 (file)
--- a/vid_wgl.c
+++ b/vid_wgl.c
@@ -126,6 +126,7 @@ static dllfunction_t wglpixelformatfuncs[] =
 };
 
 static DEVMODE gdevmode, initialdevmode;
+static vid_mode_t desktop_mode;
 static qboolean vid_initialized = false;
 static qboolean vid_wassuspended = false;
 static qboolean vid_usingmouse = false;
@@ -152,10 +153,11 @@ static qboolean vid_isfullscreen;
 //void VID_MenuDraw (void);
 //void VID_MenuKey (int key);
 
-//LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-//void AppActivate(BOOL fActive, BOOL minimize);
-//void ClearAllStates (void);
-//void VID_UpdateWindowStatus (void);
+LONG WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+void AppActivate(BOOL fActive, BOOL minimize);
+static void ClearAllStates(void);
+qboolean VID_InitModeGL(viddef_mode_t *mode);
+qboolean VID_InitModeSOFT(viddef_mode_t *mode);
 
 //====================================
 
@@ -214,7 +216,7 @@ static HINSTANCE hInstDI;
 
 // forward-referenced functions
 static void IN_StartupMouse (void);
-
+static void AdjustWindowBounds(int fullscreen, int *width, int *height, viddef_mode_t *mode, DWORD WindowStyle, RECT *rect);
 
 //====================================
 
@@ -319,25 +321,23 @@ void VID_Finish (void)
        // without this help
        Sleep(0);
 
-       VID_UpdateGamma(false, 256);
+       VID_UpdateGamma();
 }
 
 //==========================================================================
 
 
-
-
 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
-       'q'        ,'w'   ,'e'  ,'r'  ,'t'  ,'y'    ,'u'    ,'i'   ,'o'      ,'p'   ,'['       ,']'        ,13    ,K_CTRL      ,'a'        ,'s'  ,//1
-       'd'        ,'f'   ,'g'  ,'h'  ,'j'  ,'k'    ,'l'    ,';'   ,'\''     ,'`'   ,K_SHIFT   ,'\\'       ,'z'   ,'x'         ,'c'        ,'v'  ,//2
-       'b'        ,'n'   ,'m'  ,','  ,'.'  ,'/'    ,K_SHIFT,'*'   ,K_ALT    ,' '   ,0         ,K_F1       ,K_F2  ,K_F3        ,K_F4       ,K_F5 ,//3
-       K_F6       ,K_F7  ,K_F8 ,K_F9 ,K_F10,K_PAUSE,0      ,K_HOME,K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5,K_RIGHTARROW,K_KP_PLUS  ,K_END,//4
-       K_DOWNARROW,K_PGDN,K_INS,K_DEL,0    ,0      ,0      ,K_F11 ,K_F12    ,0     ,0         ,0          ,0     ,0           ,0          ,0    ,//5
-       0          ,0     ,0    ,0    ,0    ,0      ,0      ,0     ,0        ,0     ,0         ,0          ,0     ,0           ,0          ,0    ,//6
-       0          ,0     ,0    ,0    ,0    ,0      ,0      ,0     ,0        ,0     ,0         ,0          ,0     ,0           ,0          ,0     //7
+//  0           1        2     3     4     5       6           7      8         9      A          B           C       D            E           F
+       0          ,K_ESCAPE,'1'  ,'2'  ,'3'  ,'4'    ,'5'        ,'6'   ,'7'      ,'8'   ,'9'       ,'0'        ,'-'    ,'='         ,K_BACKSPACE,K_TAB,//0
+       'q'        ,'w'     ,'e'  ,'r'  ,'t'  ,'y'    ,'u'        ,'i'   ,'o'      ,'p'   ,'['       ,']'        ,K_ENTER,K_CTRL      ,'a'        ,'s'  ,//1
+       'd'        ,'f'     ,'g'  ,'h'  ,'j'  ,'k'    ,'l'        ,';'   ,'\''     ,'`'   ,K_SHIFT   ,'\\'       ,'z'    ,'x'         ,'c'        ,'v'  ,//2
+       'b'        ,'n'     ,'m'  ,','  ,'.'  ,'/'    ,K_SHIFT    ,'*'   ,K_ALT    ,' '   ,K_CAPSLOCK,K_F1       ,K_F2   ,K_F3        ,K_F4       ,K_F5 ,//3
+       K_F6       ,K_F7    ,K_F8 ,K_F9 ,K_F10,K_PAUSE,K_SCROLLOCK,K_HOME,K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5 ,K_RIGHTARROW,K_KP_PLUS  ,K_END,//4
+       K_DOWNARROW,K_PGDN  ,K_INS,K_DEL,0    ,0      ,0          ,K_F11 ,K_F12    ,0     ,0         ,0          ,0      ,0           ,0          ,0    ,//5
+       0          ,0       ,0    ,0    ,0    ,0      ,0          ,0     ,0        ,0     ,0         ,0          ,0      ,0           ,0          ,0    ,//6
+       0          ,0       ,0    ,0    ,0    ,0      ,0          ,0     ,0        ,0     ,0         ,0          ,0      ,0           ,0          ,0     //7
 };
 
 
@@ -367,6 +367,9 @@ static int MapKey (int key, int virtualkey)
 
        if ( !is_extended )
        {
+               if(((GetKeyState(VK_NUMLOCK)) & 0xffff) == 0)
+                       return result;
+
                switch ( result )
                {
                case K_HOME:
@@ -395,6 +398,9 @@ static int MapKey (int key, int virtualkey)
        }
        else
        {
+               if(virtualkey == VK_NUMLOCK)
+                       return K_NUMLOCK;
+
                switch ( result )
                {
                case 0x0D:
@@ -423,7 +429,7 @@ ClearAllStates
 */
 static void ClearAllStates (void)
 {
-       Key_ClearStates ();
+       Key_ReleaseAll();
        if (vid_usingmouse)
                mouse_oldbuttonstate = 0;
 }
@@ -489,10 +495,9 @@ void AppActivate(BOOL fActive, BOOL minimize)
                if (vid_isfullscreen)
                {
                        if (gldll)
-                               ChangeDisplaySettings (NULL, 0);
+                               ChangeDisplaySettings (NULL, CDS_FULLSCREEN);
                        vid_wassuspended = true;
                }
-               VID_RestoreSystemGamma();
        }
 }
 
@@ -511,7 +516,9 @@ void Sys_SendKeyEvents (void)
        }
 }
 
+#ifdef CONFIG_CD
 LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#endif
 
 static keynum_t buttonremap[16] =
 {
@@ -539,7 +546,8 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM  wParam, LPARAM lParam)
        LONG    lRet = 1;
        int             fActive, fMinimized, temp;
        unsigned char state[256];
-       unsigned char asciichar[4];
+       const unsigned int UNICODE_BUFFER_LENGTH = 4;
+       WCHAR unicode[UNICODE_BUFFER_LENGTH];
        int             vkey;
        int             charlength;
        qboolean down = false;
@@ -558,8 +566,8 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM  wParam, LPARAM lParam)
                        break;
 
                case WM_MOVE:
-                       window_x = (int) LOWORD(lParam);
-                       window_y = (int) HIWORD(lParam);
+                       window_x = (short) LOWORD(lParam);
+                       window_y = (short) HIWORD(lParam);
                        VID_SetMouse(false, false, false);
                        break;
 
@@ -572,14 +580,13 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM  wParam, LPARAM lParam)
                        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, (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];
-                       }
+                       charlength = ToUnicode(wParam, lParam >> 16, state, unicode, UNICODE_BUFFER_LENGTH, 0);
+                       if(vkey == K_ALT || vkey == K_CTRL || vkey == K_SHIFT || charlength == 0)
+                               unicode[0] = 0;
+                       else if(charlength == 2)
+                               unicode[0] = unicode[1];
                        if (!VID_JoyBlockEmulatedKeys(vkey))
-                               Key_Event (vkey, asciichar[0], down);
+                               Key_Event(vkey, unicode[0], down);
                        break;
 
                case WM_SYSCHAR:
@@ -688,7 +695,9 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM  wParam, LPARAM lParam)
                //      break;
 
                case MM_MCINOTIFY:
+#ifdef CONFIG_CD
                        lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam);
+#endif
                        break;
 
                default:
@@ -701,32 +710,6 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM  wParam, LPARAM lParam)
        return lRet;
 }
 
-int VID_SetGamma(unsigned short *ramps, int rampsize)
-{
-       if (qwglMakeCurrent)
-       {
-               HDC hdc = GetDC (NULL);
-               int i = SetDeviceGammaRamp(hdc, ramps);
-               ReleaseDC (NULL, hdc);
-               return i; // return success or failure
-       }
-       else
-               return 0;
-}
-
-int VID_GetGamma(unsigned short *ramps, int rampsize)
-{
-       if (qwglMakeCurrent)
-       {
-               HDC hdc = GetDC (NULL);
-               int i = GetDeviceGammaRamp(hdc, ramps);
-               ReleaseDC (NULL, hdc);
-               return i; // return success or failure
-       }
-       else
-               return 0;
-}
-
 static void GL_CloseLibrary(void)
 {
        if (gldll)
@@ -862,6 +845,13 @@ void VID_Init(void)
        memset(&initialdevmode, 0, sizeof(initialdevmode));
        EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &initialdevmode);
 
+       desktop_mode.width = initialdevmode.dmPelsWidth;
+       desktop_mode.height = initialdevmode.dmPelsHeight;
+       desktop_mode.bpp = initialdevmode.dmBitsPerPel;
+       desktop_mode.refreshrate = initialdevmode.dmDisplayFrequency;
+       desktop_mode.pixelheight_num = 1;
+       desktop_mode.pixelheight_denom = 1; // Win32 apparently does not provide this (FIXME)
+
        IN_Init();
 }
 
@@ -896,7 +886,6 @@ qboolean VID_InitModeGL(viddef_mode_t *mode)
        int pixelformat, newpixelformat;
        UINT numpixelformats;
        DWORD WindowStyle, ExWindowStyle;
-       int CenterX, CenterY;
        const char *gldrivername;
        int depth;
        DEVMODE thismode;
@@ -1008,7 +997,15 @@ qboolean VID_InitModeGL(viddef_mode_t *mode)
        vid_isfullscreen = false;
        if (fullscreen)
        {
-               if(vid_forcerefreshrate.integer)
+               if(vid_desktopfullscreen.integer)
+               {
+                       foundmode = true;
+                       gdevmode = initialdevmode;
+                       width = mode->width = gdevmode.dmPelsWidth;
+                       height = mode->height = gdevmode.dmPelsHeight;
+                       bpp = mode->bitsperpixel = gdevmode.dmBitsPerPel;
+               }
+               else if(vid_forcerefreshrate.integer)
                {
                        foundmode = true;
                        gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
@@ -1142,32 +1139,7 @@ qboolean VID_InitModeGL(viddef_mode_t *mode)
                ExWindowStyle = 0;
        }
 
-       rect.top = 0;
-       rect.left = 0;
-       rect.right = width;
-       rect.bottom = height;
-       AdjustWindowRectEx(&rect, WindowStyle, false, 0);
-
-       if (fullscreen)
-       {
-               CenterX = 0;
-               CenterY = 0;
-       }
-       else
-       {
-               CenterX = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
-               CenterY = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
-       }
-       CenterX = max(0, CenterX);
-       CenterY = max(0, CenterY);
-
-       // x and y may be changed by WM_MOVE messages
-       window_x = CenterX;
-       window_y = CenterY;
-       rect.left += CenterX;
-       rect.right += CenterX;
-       rect.top += CenterY;
-       rect.bottom += CenterY;
+       AdjustWindowBounds(fullscreen, &width, &height, mode, WindowStyle, &rect);
 
        pixelformat = 0;
        newpixelformat = 0;
@@ -1325,6 +1297,56 @@ qboolean VID_InitModeGL(viddef_mode_t *mode)
        return true;
 }
 
+static void AdjustWindowBounds(int fullscreen, int *width, int *height, viddef_mode_t *mode, DWORD WindowStyle, RECT *rect)
+{
+       int CenterX, CenterY;
+
+       rect->top = 0;
+       rect->left = 0;
+       rect->right = *width;
+       rect->bottom = *height;
+       AdjustWindowRectEx(rect, WindowStyle, false, 0);
+
+       if (fullscreen)
+       {
+               CenterX = 0;
+               CenterY = 0;
+       }
+       else
+       {
+               RECT workArea;
+               SystemParametersInfo(SPI_GETWORKAREA, NULL, &workArea, 0);
+               int workWidth = workArea.right - workArea.left;
+               int workHeight = workArea.bottom - workArea.top;
+
+               // if height/width matches physical screen height/width, adjust it to available desktop size
+               // and allow 2 pixels on top for the title bar so the window can be moved
+               const int titleBarPixels = 2;
+               if (*width == GetSystemMetrics(SM_CXSCREEN) && (*height == GetSystemMetrics(SM_CYSCREEN) || *height == workHeight - titleBarPixels))
+               {
+                       rect->right -= *width - workWidth;
+                       *width = mode->width = workWidth;
+                       rect->bottom -= *height - (workHeight - titleBarPixels);
+                       *height = mode->height = workHeight - titleBarPixels;
+                       CenterX = 0;
+                       CenterY = titleBarPixels;
+               }
+               else
+               {
+                       CenterX = max(0, (workWidth - *width) / 2);
+                       CenterY = max(0, (workHeight - *height) / 2);
+               }
+       }
+
+       // x and y may be changed by WM_MOVE messages
+       window_x = CenterX;
+       window_y = CenterY;
+       rect->left += CenterX;
+       rect->right += CenterX;
+       rect->top += CenterY;
+       rect->bottom += CenterY;
+}
+
 #ifdef SUPPORTD3D
 static D3DADAPTER_IDENTIFIER9 d3d9adapteridentifier;
 
@@ -1340,7 +1362,6 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version)
        RECT rect;
        MSG msg;
        DWORD WindowStyle, ExWindowStyle;
-       int CenterX, CenterY;
        int bpp = mode->bitsperpixel;
        int width = mode->width;
        int height = mode->height;
@@ -1365,32 +1386,7 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version)
                ExWindowStyle = 0;
        }
 
-       rect.top = 0;
-       rect.left = 0;
-       rect.right = width;
-       rect.bottom = height;
-       AdjustWindowRectEx(&rect, WindowStyle, false, 0);
-
-       if (fullscreen)
-       {
-               CenterX = 0;
-               CenterY = 0;
-       }
-       else
-       {
-               CenterX = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
-               CenterY = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
-       }
-       CenterX = max(0, CenterX);
-       CenterY = max(0, CenterY);
-
-       // x and y may be changed by WM_MOVE messages
-       window_x = CenterX;
-       window_y = CenterY;
-       rect.left += CenterX;
-       rect.right += CenterX;
-       rect.top += CenterY;
-       rect.bottom += CenterY;
+       AdjustWindowBounds(fullscreen, &width, &height, mode, WindowStyle, &rect);
 
        gl_extensions = "";
        gl_platformextensions = "";
@@ -1500,6 +1496,7 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version)
        vid.support.arb_depth_texture = true;
        vid.support.arb_draw_buffers = vid_d3d9caps.NumSimultaneousRTs > 1;
        vid.support.arb_occlusion_query = true; // can't find a cap for this
+       vid.support.arb_query_buffer_object = true;
        vid.support.arb_shadow = true;
        vid.support.arb_texture_compression = true;
        vid.support.arb_texture_cube_map = true;
@@ -1508,6 +1505,7 @@ qboolean VID_InitModeDX(viddef_mode_t *mode, int version)
        vid.support.ext_blend_subtract = true;
        vid.support.ext_draw_range_elements = true;
        vid.support.ext_framebuffer_object = true;
+
        vid.support.ext_texture_3d = true;
        vid.support.ext_texture_compression_s3tc = true;
        vid.support.ext_texture_filter_anisotropic = true;
@@ -1572,7 +1570,6 @@ qboolean VID_InitModeSOFT(viddef_mode_t *mode)
        MSG msg;
        int pixelformat, newpixelformat;
        DWORD WindowStyle, ExWindowStyle;
-       int CenterX, CenterY;
        int depth;
        DEVMODE thismode;
        qboolean foundmode, foundgoodmode;
@@ -1724,32 +1721,7 @@ qboolean VID_InitModeSOFT(viddef_mode_t *mode)
                ExWindowStyle = 0;
        }
 
-       rect.top = 0;
-       rect.left = 0;
-       rect.right = width;
-       rect.bottom = height;
-       AdjustWindowRectEx(&rect, WindowStyle, false, 0);
-
-       if (fullscreen)
-       {
-               CenterX = 0;
-               CenterY = 0;
-       }
-       else
-       {
-               CenterX = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
-               CenterY = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
-       }
-       CenterX = max(0, CenterX);
-       CenterY = max(0, CenterY);
-
-       // x and y may be changed by WM_MOVE messages
-       window_x = CenterX;
-       window_y = CenterY;
-       rect.left += CenterX;
-       rect.right += CenterX;
-       rect.top += CenterY;
-       rect.bottom += CenterY;
+       AdjustWindowBounds(fullscreen, &width, &height, mode, WindowStyle, &rect);
 
        pixelformat = 0;
        newpixelformat = 0;
@@ -1871,7 +1843,6 @@ void VID_Shutdown (void)
 
        VID_EnableJoystick(false);
        VID_SetMouse(false, false, false);
-       VID_RestoreSystemGamma();
 
        vid_initialized = false;
        isgl = gldll != NULL;
@@ -1900,8 +1871,8 @@ void VID_Shutdown (void)
                if (vid_begunscene)
                        IDirect3DDevice9_EndScene(vid_d3d9dev);
                vid_begunscene = false;
-//             Cmd_ExecuteString("r_texturestats", src_command);
-//             Cmd_ExecuteString("memlist", src_command);
+//             Cmd_ExecuteString("r_texturestats", src_command, true);
+//             Cmd_ExecuteString("memlist", src_command, true);
                IDirect3DDevice9_Release(vid_d3d9dev);
        }
        vid_d3d9dev = NULL;
@@ -1925,7 +1896,7 @@ void VID_Shutdown (void)
                DestroyWindow(mainwindow);
        mainwindow = 0;
        if (vid_isfullscreen && isgl)
-               ChangeDisplaySettings (NULL, 0);
+               ChangeDisplaySettings (NULL, CDS_FULLSCREEN);
        vid_isfullscreen = false;
 }
 
@@ -2028,7 +1999,8 @@ void VID_EnableJoystick(qboolean enable)
        if (joy_detected.integer != sharedcount)
                Cvar_SetValueQuick(&joy_detected, sharedcount);
 
-       Cvar_SetValueQuick(&joy_active, success ? 1 : 0);
+       if (joy_active.integer != (success ? 1 : 0))
+               Cvar_SetValueQuick(&joy_active, success ? 1 : 0);
 }
 
 #ifdef SUPPORTDIRECTX
@@ -2279,6 +2251,11 @@ static void IN_Shutdown(void)
 #endif
 }
 
+vid_mode_t *VID_GetDesktopMode(void)
+{
+       return &desktop_mode;
+}
+
 size_t VID_ListModes(vid_mode_t *modes, size_t maxcount)
 {
        int i;