From 64c4b73853a2328a25c52a6b5b98fa2d7abfacec Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 4 May 2024 07:19:02 +0200 Subject: [PATCH] Add workaround for alt+tab issues on windows 7 SP1 (opengl) --- inc/versionhelpers.h | 98 ++++++++++++++++++++++++++++++++++++++++++++ src/dd.c | 14 ++++++- src/fps_limiter.c | 16 +++++++- 3 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 inc/versionhelpers.h diff --git a/inc/versionhelpers.h b/inc/versionhelpers.h new file mode 100644 index 0000000..5cb0d97 --- /dev/null +++ b/inc/versionhelpers.h @@ -0,0 +1,98 @@ +/** + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ + +#ifndef _INC_VERSIONHELPERS +#define _INC_VERSIONHELPERS + +#if 1 + +#ifdef __cplusplus +#define VERSIONHELPERAPI inline bool +#else +#define VERSIONHELPERAPI FORCEINLINE BOOL +#endif + +#ifndef _WIN32_WINNT_WIN8 +#define _WIN32_WINNT_WIN8 0x0602 +#endif +#ifndef _WIN32_WINNT_WINBLUE +#define _WIN32_WINNT_WINBLUE 0x0603 +#endif +#ifndef _WIN32_WINNT_WINTHRESHOLD +#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 /* ABRACADABRA_THRESHOLD*/ +#endif +#ifndef _WIN32_WINNT_WIN10 +#define _WIN32_WINNT_WIN10 0x0A00 /* ABRACADABRA_THRESHOLD*/ +#endif + +VERSIONHELPERAPI IsWindowsVersionOrGreater(WORD major, WORD minor, WORD servpack) +{ + OSVERSIONINFOEXW vi = {sizeof(vi),major,minor,0,0,{0},servpack}; + return VerifyVersionInfoW(&vi, VER_MAJORVERSION|VER_MINORVERSION|VER_SERVICEPACKMAJOR, + VerSetConditionMask(VerSetConditionMask(VerSetConditionMask(0, + VER_MAJORVERSION,VER_GREATER_EQUAL), + VER_MINORVERSION,VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL)); +} + +VERSIONHELPERAPI IsWindowsXPOrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0); +} + +VERSIONHELPERAPI IsWindowsXPSP1OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1); +} + +VERSIONHELPERAPI IsWindowsXPSP2OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2); +} + +VERSIONHELPERAPI IsWindowsXPSP3OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3); +} + +VERSIONHELPERAPI IsWindowsVistaOrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); +} + +VERSIONHELPERAPI IsWindowsVistaSP1OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1); +} + +VERSIONHELPERAPI IsWindowsVistaSP2OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2); +} + +VERSIONHELPERAPI IsWindows7OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0); +} + +VERSIONHELPERAPI IsWindows7SP1OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1); +} + +VERSIONHELPERAPI IsWindows8OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); +} + +VERSIONHELPERAPI IsWindows8Point1OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0); +} + +VERSIONHELPERAPI IsWindowsThresholdOrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINTHRESHOLD), LOBYTE(_WIN32_WINNT_WINTHRESHOLD), 0); +} + +VERSIONHELPERAPI IsWindows10OrGreater(void) { + return IsWindowsThresholdOrGreater(); +} + +VERSIONHELPERAPI IsWindowsServer(void) { + OSVERSIONINFOEXW vi = {sizeof(vi),0,0,0,0,{0},0,0,0,VER_NT_WORKSTATION}; + return !VerifyVersionInfoW(&vi, VER_PRODUCT_TYPE, VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL)); +} + +#endif +#endif diff --git a/src/dd.c b/src/dd.c index 6398cc7..68f0810 100644 --- a/src/dd.c +++ b/src/dd.c @@ -14,6 +14,7 @@ #include "debug.h" #include "utils.h" #include "blt.h" +#include "versionhelpers.h" CNCDDRAW g_ddraw; @@ -1271,8 +1272,17 @@ HRESULT dd_WaitForVerticalBlank(DWORD dwFlags, HANDLE hEvent) { if (g_config.maxgameticks == -2) { - if (fpsl_dwm_flush() || fpsl_wait_for_vblank()) - return DD_OK; + /* Workaround for DwmFlush() freeze (e.g. slow alt+tab) issue on windows 7 SP1 */ + if (g_ddraw.renderer == ogl_render_main && !g_config.is_wine && !IsWindows8OrGreater()) + { + if (fpsl_wait_for_vblank()) + return DD_OK; + } + else + { + if (fpsl_dwm_flush() || fpsl_wait_for_vblank()) + return DD_OK; + } } if (!g_ddraw.flip_limiter.tick_length) diff --git a/src/fps_limiter.c b/src/fps_limiter.c index a6014bf..9d74fc5 100644 --- a/src/fps_limiter.c +++ b/src/fps_limiter.c @@ -4,6 +4,9 @@ #include "debug.h" #include "hook.h" #include "config.h" +#include "render_ogl.h" +#include "versionhelpers.h" + FPSLIMITER g_fpsl; @@ -153,8 +156,17 @@ void fpsl_frame_end() if (g_config.maxfps < 0 || (g_config.vsync && (!g_config.maxfps || g_config.maxfps >= g_ddraw.mode.dmDisplayFrequency))) { - if (fpsl_dwm_flush() || fpsl_wait_for_vblank()) - return; + /* Workaround for DwmFlush() freeze (e.g. slow alt+tab) issue on windows 7 SP1 */ + if (g_ddraw.renderer == ogl_render_main && !g_config.is_wine && !IsWindows8OrGreater()) + { + if (fpsl_wait_for_vblank()) + return; + } + else + { + if (fpsl_dwm_flush() || fpsl_wait_for_vblank()) + return; + } } if (g_fpsl.tick_length > 0)