diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp index bdec745d45..e4f46d2ef8 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp @@ -371,6 +371,13 @@ void GameEngine::init( int argc, char *argv[] ) #endif///////////////////////////////////////////////////////////////////////////////////////////// + // TheSuperHackers @bugfix helmutbuhler 04/14/2025 + // Pump messages during startup to avoid "(Not responding)" in the window title + // on slower computers and in debug build. + // This also ensures that the window is correctly positioned, because Windows + // apparently ignores the SetWindowPos call when the window is not responding. + serviceWindowsOS(); + #if defined(_DEBUG) || defined(_INTERNAL) // If we're in Debug or Internal, load the Debug info as well. diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp index 61983ce7f1..1570ddb3fd 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp @@ -44,7 +44,8 @@ //#define CREATE_DX8_MULTI_THREADED //#define CREATE_DX8_FPU_PRESERVE #define WW3D_DEVTYPE D3DDEVTYPE_HAL - +#undef WINVER +#define WINVER 0x0500 #include "dx8wrapper.h" #include "dx8webbrowser.h" #include "dx8fvf.h" @@ -242,6 +243,26 @@ void Non_Fatal_Log_DX8_ErrorCode(unsigned res,const char * file,int line) } } +// TheSuperHackers @info helmutbuhler 04/14/2025 +// Helper function that moves x and y such that the inner rect fits into the outer rect. +// If inner already is in outer, this does nothing. +void MoveRectIntoOtherRect(const RECT& inner, const RECT& outer, int* x, int* y) +{ + int dx = 0; + if (inner.right > outer.right) + dx = outer.right-inner.right; + if (inner.left < outer.left) + dx = outer.left-inner.left; + + int dy = 0; + if (inner.bottom > outer.bottom) + dy = outer.bottom-inner.bottom; + if (inner.top < outer.top) + dy = outer.top-inner.top; + + *x += dx; + *y += dy; +} bool DX8Wrapper::Init(void * hwnd, bool lite) @@ -885,6 +906,60 @@ void DX8Wrapper::Get_Format_Name(unsigned int format, StringClass *tex_format) } } +void DX8Wrapper::Resize_And_Position_Window() +{ + // Get the current dimensions of the 'render area' of the window + RECT rect = { 0 }; + ::GetClientRect (_Hwnd, &rect); + + // Is the window the correct size for this resolution? + if ((rect.right-rect.left) != ResolutionWidth || + (rect.bottom-rect.top) != ResolutionHeight) { + + // Calculate what the main window's bounding rectangle should be to + // accomodate this resolution + rect.left = 0; + rect.top = 0; + rect.right = ResolutionWidth; + rect.bottom = ResolutionHeight; + DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE); + AdjustWindowRect (&rect, dwstyle, FALSE); + int width = rect.right-rect.left; + int height = rect.bottom-rect.top; + + // Resize the window to fit this resolution + if (!IsWindowed) + ::SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOSIZE | SWP_NOMOVE); + else + { + // TheSuperHackers @feature helmutbuhler 04/14/2025 + // Center the window in the workarea of the monitor it is on. + MONITORINFO mi = {sizeof(MONITORINFO)}; + GetMonitorInfo(MonitorFromWindow(_Hwnd, MONITOR_DEFAULTTOPRIMARY), &mi); + int left = (mi.rcWork.left + mi.rcWork.right - width) / 2; + int top = (mi.rcWork.top + mi.rcWork.bottom - height) / 2; + + // TheSuperHackers @feature helmutbuhler 04/14/2025 + // In case part of the resulting client area is off monitor, move it. + // This can happen when the window is larger than the work area. + RECT rectClient; + rectClient.left = left - rect.left; + rectClient.top = top - rect.top; + rectClient.right = rectClient.left + ResolutionWidth; + rectClient.bottom = rectClient.top + ResolutionHeight; + MoveRectIntoOtherRect(rectClient, mi.rcMonitor, &left, &top); + + ::SetWindowPos (_Hwnd, + NULL, + left, + top, + width, + height, + SWP_NOZORDER); + } + } +} + bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int windowed, bool resize_window,bool reset_device, bool restore_assets) { @@ -926,36 +1001,7 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int // push the client area to be the size you really want. // if ( resize_window && windowed ) { if (resize_window) { - - // Get the current dimensions of the 'render area' of the window - RECT rect = { 0 }; - ::GetClientRect (_Hwnd, &rect); - - // Is the window the correct size for this resolution? - if ((rect.right-rect.left) != ResolutionWidth || - (rect.bottom-rect.top) != ResolutionHeight) { - - // Calculate what the main window's bounding rectangle should be to - // accomodate this resolution - rect.left = 0; - rect.top = 0; - rect.right = ResolutionWidth; - rect.bottom = ResolutionHeight; - DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE); - AdjustWindowRect (&rect, dwstyle, FALSE); - - // Resize the window to fit this resolution - if (!windowed) - ::SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0, rect.right-rect.left, rect.bottom-rect.top,SWP_NOSIZE |SWP_NOMOVE); - else - ::SetWindowPos (_Hwnd, - NULL, - 0, - 0, - rect.right-rect.left, - rect.bottom-rect.top, - SWP_NOZORDER | SWP_NOMOVE); - } + Resize_And_Position_Window(); } #endif //must be either resetting existing device or creating a new one. @@ -1204,37 +1250,7 @@ bool DX8Wrapper::Set_Device_Resolution(int width,int height,int bits,int windowe } if (resize_window) { - - // Get the current dimensions of the 'render area' of the window - RECT rect = { 0 }; - ::GetClientRect (_Hwnd, &rect); - - // Is the window the correct size for this resolution? - if ((rect.right-rect.left) != ResolutionWidth || - (rect.bottom-rect.top) != ResolutionHeight) - { - - // Calculate what the main window's bounding rectangle should be to - // accomodate this resolution - rect.left = 0; - rect.top = 0; - rect.right = ResolutionWidth; - rect.bottom = ResolutionHeight; - DWORD dwstyle = ::GetWindowLong (_Hwnd, GWL_STYLE); - AdjustWindowRect (&rect, dwstyle, FALSE); - - // Resize the window to fit this resolution - if (!windowed) - ::SetWindowPos(_Hwnd, HWND_TOPMOST, 0, 0, rect.right-rect.left, rect.bottom-rect.top,SWP_NOSIZE |SWP_NOMOVE); - else - ::SetWindowPos (_Hwnd, - NULL, - 0, - 0, - rect.right-rect.left, - rect.bottom-rect.top, - SWP_NOZORDER | SWP_NOMOVE); - } + Resize_And_Position_Window(); } #pragma message("TODO: support changing windowed status and changing the bit depth") return Reset_Device(); diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h index 835aa0ba47..4ffba54a31 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h @@ -613,6 +613,7 @@ class DX8Wrapper /* ** Internal functions */ + static void Resize_And_Position_Window(); static bool Find_Color_And_Z_Mode(int resx,int resy,int bitdepth,D3DFORMAT * set_colorbuffer,D3DFORMAT * set_backbuffer, D3DFORMAT * set_zmode); static bool Find_Color_Mode(D3DFORMAT colorbuffer, int resx, int resy, UINT *mode); static bool Find_Z_Mode(D3DFORMAT colorbuffer,D3DFORMAT backbuffer, D3DFORMAT *zmode);