From 156ed5790ed2d98354c5d08e2a90a41ed4506d7e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 21 Jul 2018 21:32:02 +0200 Subject: [PATCH] - added vid_setsize CCMD and fixed some issues with window restoration when switching from fullscreen. Windows apparently cannot both undo borderless fullscreen and resize the window at the same time, so this must delay the resizing one frame. --- src/d_main.cpp | 4 +-- src/v_video.cpp | 14 ++++++++ src/v_video.h | 1 + src/win32/base_sysfb.cpp | 72 ++++++++++++++++++++++++++++++++++++++-- src/win32/base_sysfb.h | 3 +- 5 files changed, 88 insertions(+), 6 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index ab0828009..6d16ccc4b 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -680,10 +680,10 @@ void D_Display () // fullscreen toggle has been requested if (setmodeneeded) { + setmodeneeded = false; screen->ToggleFullscreen(fullscreen); V_OutputResized(screen->GetWidth(), screen->GetHeight()); - setmodeneeded = false; - } + } // change the view size if needed if (setsizeneeded) diff --git a/src/v_video.cpp b/src/v_video.cpp index fbb0109a2..77d13d1a9 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -857,6 +857,20 @@ void ScaleWithAspect (int &w, int &h, int Width, int Height) h = static_cast(y); } +CCMD(vid_setsize) +{ + if (argv.argc() < 2) + { + Printf("Usage: vid_setsize width height\n"); + } + else + { + screen->SetWindowSize((int)strtol(argv[1], nullptr, 0), (int)strtol(argv[2], nullptr, 0)); + V_OutputResized(screen->GetClientWidth(), screen->GetClientHeight()); + } +} + + void IVideo::DumpAdapters () { Printf("Multi-monitor support unavailable.\n"); diff --git a/src/v_video.h b/src/v_video.h index 2e6c0cd30..74d0b0db7 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -423,6 +423,7 @@ public: virtual void UnbindTexUnit(int no) {} virtual void TextureFilterChanged() {} virtual void BeginFrame() {} + virtual void SetWindowSize(int w, int h) {} virtual int GetClientWidth() = 0; virtual int GetClientHeight() = 0; diff --git a/src/win32/base_sysfb.cpp b/src/win32/base_sysfb.cpp index 5e2f5c21e..550eb9639 100644 --- a/src/win32/base_sysfb.cpp +++ b/src/win32/base_sysfb.cpp @@ -52,6 +52,7 @@ #include "doomerrors.h" #include "base_sysfb.h" #include "win32basevideo.h" +#include "c_dispatch.h" extern HWND Window; @@ -69,6 +70,7 @@ CVAR(Bool, win_maximized, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) EXTERN_CVAR(Int, vid_defwidth) EXTERN_CVAR(Int, vid_defheight) +EXTERN_CVAR(Bool, fullscreen) //========================================================================== @@ -226,6 +228,64 @@ void SystemBaseFrameBuffer::RestoreWindowedPos() // //========================================================================== +void SystemBaseFrameBuffer::SetWindowSize(int w, int h) +{ + if (w < 0 || h < 0) + { + RestoreWindowedPos(); + } + else + { + LONG style = WS_VISIBLE | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW; + LONG exStyle = WS_EX_WINDOWEDGE; + SetWindowLong(Window, GWL_STYLE, style); + SetWindowLong(Window, GWL_EXSTYLE, exStyle); + + int winx, winy, winw, winh, scrwidth, scrheight; + + RECT r = { 0, 0, w, h }; + AdjustWindowRectEx(&r, style, false, exStyle); + w = int(r.right - r.left); + h = int(r.bottom - r.top); + + GetCenteredPos(w, h, winx, winy, winw, winh, scrwidth, scrheight); + + // Just move to (0,0) if we were run with the -0 option. + if (Args->CheckParm("-0")) + { + winx = winy = 0; + } + else + { + KeepWindowOnScreen(winx, winy, winw, winh, scrwidth, scrheight); + } + + if (!fullscreen) + { + ShowWindow(Window, SW_SHOWNORMAL); + SetWindowPos(Window, nullptr, winx, winy, winw, winh, SWP_NOZORDER | SWP_FRAMECHANGED); + win_maximized = false; + SetSize(GetClientWidth(), GetClientHeight()); + SaveWindowedPos(); + } + else + { + win_x = winx; + win_y = winy; + win_w = winw; + win_h = winh; + win_maximized = false; + fullscreen = false; + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + void SystemBaseFrameBuffer::PositionWindow(bool fullscreen) { RECT r; @@ -233,7 +293,7 @@ void SystemBaseFrameBuffer::PositionWindow(bool fullscreen) RECT monRect; - if (!m_Fullscreen) SaveWindowedPos(); + if (!m_Fullscreen && fullscreen) SaveWindowedPos(); if (m_Monitor) { MONITORINFOEX mi; @@ -264,7 +324,6 @@ void SystemBaseFrameBuffer::PositionWindow(bool fullscreen) SetWindowLong(Window, GWL_STYLE, style); SetWindowLong(Window, GWL_EXSTYLE, exStyle); - m_Fullscreen = fullscreen; if (fullscreen) { SetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); @@ -275,7 +334,14 @@ void SystemBaseFrameBuffer::PositionWindow(bool fullscreen) else { RestoreWindowedPos(); + // This doesn't restore the window size properly so we must force a set size the next tic. + if (m_Fullscreen) + { + ::fullscreen = false; + } + } + m_Fullscreen = fullscreen; SetSize(GetClientWidth(), GetClientHeight()); } @@ -306,7 +372,7 @@ SystemBaseFrameBuffer::SystemBaseFrameBuffer(void *hMonitor, bool fullscreen) : SystemBaseFrameBuffer::~SystemBaseFrameBuffer() { ResetGammaTable(); - SaveWindowedPos(); + if (!m_Fullscreen) SaveWindowedPos(); ShowWindow (Window, SW_SHOW); SetWindowLong(Window, GWL_STYLE, WS_VISIBLE | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW); diff --git a/src/win32/base_sysfb.h b/src/win32/base_sysfb.h index 01672c280..84eb5c981 100644 --- a/src/win32/base_sysfb.h +++ b/src/win32/base_sysfb.h @@ -21,6 +21,7 @@ public: bool IsFullscreen() override; void ToggleFullscreen(bool yes) override; + void SetWindowSize(int client_w, int client_h); protected: @@ -35,7 +36,7 @@ protected: float m_Gamma, m_Brightness, m_Contrast; uint16_t m_origGamma[768]; bool m_supportsGamma; - bool m_Fullscreen; + bool m_Fullscreen = false; char m_displayDeviceNameBuffer[32/*CCHDEVICENAME*/]; // do not use windows.h constants here! char *m_displayDeviceName; void *m_Monitor;