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;