From 30de4d7df42380c4850fbbf6f8a12529d6a30183 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 15 Jun 2024 05:28:06 +0200 Subject: [PATCH] use high resolutuion timer by default --- inc/dd.h | 4 ++++ inc/versionhelpers.h | 4 ++++ src/dd.c | 25 ++++++++++++++++++++++--- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/inc/dd.h b/inc/dd.h index e28249a..8a074da 100644 --- a/inc/dd.h +++ b/inc/dd.h @@ -50,6 +50,10 @@ HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOute #define LIMIT_TESTCOOP 1 #define LIMIT_BLTFAST 2 +#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION +#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002 +#endif + typedef struct SPEEDLIMITER { DWORD tick_length; diff --git a/inc/versionhelpers.h b/inc/versionhelpers.h index 8acf6f5..3aa5742 100644 --- a/inc/versionhelpers.h +++ b/inc/versionhelpers.h @@ -119,6 +119,10 @@ VERSIONHELPERAPI IsWindows10OrGreater(void) { return IsWindowsThresholdOrGreater(); } +VERSIONHELPERAPI IsWindows10Version1803OrGreater(void) { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN10), LOBYTE(_WIN32_WINNT_WIN10), 17134, 0); +} + VERSIONHELPERAPI IsWindows11OrGreater(void) { return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN11), LOBYTE(_WIN32_WINNT_WIN11), 22000, 0); } diff --git a/src/dd.c b/src/dd.c index db0623f..c6dfc7e 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1578,12 +1578,28 @@ HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOute if (g_config.minfps > 0) g_ddraw.minfps_tick_len = (DWORD)(1000.0f / g_config.minfps); + + HANDLE (WINAPI *createTimerExW)(LPSECURITY_ATTRIBUTES, LPCWSTR, DWORD, DWORD) = NULL; + + if (!IsWine() && IsWindows10Version1803OrGreater()) + { + createTimerExW = (void*)real_GetProcAddress(real_LoadLibraryA("Kernel32.dll"), "CreateWaitableTimerExW"); + } + + DWORD timer_flags = CREATE_WAITABLE_TIMER_MANUAL_RESET | CREATE_WAITABLE_TIMER_HIGH_RESOLUTION; + /* can't fully set it up here due to missing g_ddraw.mode.dmDisplayFrequency */ - g_fpsl.htimer = CreateWaitableTimer(NULL, TRUE, NULL); + g_fpsl.htimer = createTimerExW ? createTimerExW(NULL, NULL, timer_flags, TIMER_ALL_ACCESS) : NULL; + + if (!g_fpsl.htimer) + g_fpsl.htimer = CreateWaitableTimer(NULL, TRUE, NULL); if (g_config.maxgameticks > 0 && g_config.maxgameticks <= 1000) { - g_ddraw.ticks_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL); + g_ddraw.ticks_limiter.htimer = createTimerExW ? createTimerExW(NULL, NULL, timer_flags, TIMER_ALL_ACCESS) : NULL; + + if (!g_ddraw.ticks_limiter.htimer) + g_ddraw.ticks_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL); float len = 1000.0f / g_config.maxgameticks; g_ddraw.ticks_limiter.tick_length_ns = (LONGLONG)(len * 10000); @@ -1593,7 +1609,10 @@ HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOute if (g_config.maxgameticks >= 0 || g_config.maxgameticks == -2) { /* always using 60 fps for flip... */ - g_ddraw.flip_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL); + g_ddraw.flip_limiter.htimer = createTimerExW ? createTimerExW(NULL, NULL, timer_flags, TIMER_ALL_ACCESS) : NULL; + + if (!g_ddraw.flip_limiter.htimer) + g_ddraw.flip_limiter.htimer = CreateWaitableTimer(NULL, TRUE, NULL); float flip_len = 1000.0f / 60; g_ddraw.flip_limiter.tick_length_ns = (LONGLONG)(flip_len * 10000);