diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj
index da8e17a..e99294a 100644
--- a/DDrawCompat/DDrawCompat.vcxproj
+++ b/DDrawCompat/DDrawCompat.vcxproj
@@ -227,6 +227,8 @@
+
+
@@ -293,6 +295,8 @@
+
+
diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters
index e11b4eb..6b372e6 100644
--- a/DDrawCompat/DDrawCompat.vcxproj.filters
+++ b/DDrawCompat/DDrawCompat.vcxproj.filters
@@ -363,6 +363,12 @@
Header Files\DDraw
+
+ Header Files\Win32
+
+
+ Header Files\Win32
+
@@ -557,6 +563,12 @@
Source Files\DDraw
+
+ Source Files\Win32
+
+
+ Source Files\Win32
+
diff --git a/DDrawCompat/Dll/DllMain.cpp b/DDrawCompat/Dll/DllMain.cpp
index 2153468..aa8ba92 100644
--- a/DDrawCompat/Dll/DllMain.cpp
+++ b/DDrawCompat/Dll/DllMain.cpp
@@ -18,6 +18,8 @@
#include
#include
#include
+#include
+#include
HRESULT WINAPI SetAppCompatData(DWORD, DWORD);
@@ -30,7 +32,6 @@ namespace
static bool isAlreadyInstalled = false;
if (!isAlreadyInstalled)
{
- SetProcessDPIAware();
Win32::DisplayMode::disableDwm8And16BitMitigation();
Compat::Log() << "Installing registry hooks";
Win32::Registry::installHooks();
@@ -38,6 +39,8 @@ namespace
D3dDdi::installHooks(g_origDDrawModule);
Compat::Log() << "Installing display mode hooks";
Win32::DisplayMode::installHooks();
+ Win32::TimeFunctions::installHooks();
+ Win32::WaitFunctions::installHooks();
Gdi::VirtualScreen::init();
CompatPtr dd;
@@ -138,6 +141,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
SetProcessPriorityBoost(GetCurrentProcess(), disablePriorityBoost);
SetProcessAffinityMask(GetCurrentProcess(), 1);
timeBeginPeriod(1);
+ SetProcessDPIAware();
SetThemeAppProperties(0);
Compat::redirectIatHooks("ddraw.dll", "DirectDrawCreate",
diff --git a/DDrawCompat/Win32/TimeFunctions.cpp b/DDrawCompat/Win32/TimeFunctions.cpp
new file mode 100644
index 0000000..d7b23ca
--- /dev/null
+++ b/DDrawCompat/Win32/TimeFunctions.cpp
@@ -0,0 +1,37 @@
+#include
+#include
+
+#include
+#include
+
+namespace
+{
+ typedef DWORD(WINAPI* TimeFunc)();
+
+ template
+ DWORD WINAPI getTime()
+ {
+ thread_local DWORD prevTime = 0;
+ auto origTimeFunc = Compat::getOrigFuncPtr();
+ DWORD time = origTimeFunc();
+ if (prevTime == time)
+ {
+ SwitchToThread();
+ time = origTimeFunc();
+ }
+ prevTime = time;
+ return time;
+ }
+}
+
+namespace Win32
+{
+ namespace TimeFunctions
+ {
+ void installHooks()
+ {
+ HOOK_FUNCTION(kernel32, GetTickCount, getTime<&GetTickCount>);
+ HOOK_FUNCTION(winmm, timeGetTime, getTime<&timeGetTime>);
+ }
+ }
+}
diff --git a/DDrawCompat/Win32/TimeFunctions.h b/DDrawCompat/Win32/TimeFunctions.h
new file mode 100644
index 0000000..4a2e836
--- /dev/null
+++ b/DDrawCompat/Win32/TimeFunctions.h
@@ -0,0 +1,9 @@
+#pragma once
+
+namespace Win32
+{
+ namespace TimeFunctions
+ {
+ void installHooks();
+ }
+}
diff --git a/DDrawCompat/Win32/WaitFunctions.cpp b/DDrawCompat/Win32/WaitFunctions.cpp
new file mode 100644
index 0000000..d31b74f
--- /dev/null
+++ b/DDrawCompat/Win32/WaitFunctions.cpp
@@ -0,0 +1,66 @@
+#include
+
+#include
+#include
+#include
+
+namespace
+{
+ DWORD mitigateBusyWaiting(DWORD dwMilliseconds, DWORD waitResult)
+ {
+ if (0 == dwMilliseconds && WAIT_TIMEOUT == waitResult)
+ {
+ SwitchToThread();
+ }
+ return waitResult;
+ }
+
+ DWORD WINAPI msgWaitForMultipleObjects(
+ DWORD nCount, const HANDLE* pHandles, BOOL fWaitAll, DWORD dwMilliseconds, DWORD dwWakeMask)
+ {
+ return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(MsgWaitForMultipleObjects)(
+ nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask));
+ }
+
+ DWORD WINAPI msgWaitForMultipleObjectsEx(
+ DWORD nCount, const HANDLE* pHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags)
+ {
+ return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(MsgWaitForMultipleObjectsEx)(
+ nCount, pHandles, dwMilliseconds, dwWakeMask, dwFlags));
+ }
+
+ DWORD WINAPI signalObjectAndWait(
+ HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable)
+ {
+ return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(SignalObjectAndWait)(
+ hObjectToSignal, hObjectToWaitOn, dwMilliseconds, bAlertable));
+ }
+
+ DWORD WINAPI waitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable)
+ {
+ return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(WaitForSingleObjectEx)(
+ hHandle, dwMilliseconds, bAlertable));
+ }
+
+ DWORD WINAPI waitForMultipleObjectsEx(
+ DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds, BOOL bAlertable)
+ {
+ return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(WaitForMultipleObjectsEx)(
+ nCount, lpHandles, bWaitAll, dwMilliseconds, bAlertable));
+ }
+}
+
+namespace Win32
+{
+ namespace WaitFunctions
+ {
+ void installHooks()
+ {
+ HOOK_FUNCTION(user32, MsgWaitForMultipleObjects, msgWaitForMultipleObjects);
+ HOOK_FUNCTION(user32, MsgWaitForMultipleObjectsEx, msgWaitForMultipleObjectsEx);
+ HOOK_FUNCTION(kernel32, SignalObjectAndWait, signalObjectAndWait);
+ HOOK_FUNCTION(kernel32, WaitForSingleObjectEx, waitForSingleObjectEx);
+ HOOK_FUNCTION(kernel32, WaitForMultipleObjectsEx, waitForMultipleObjectsEx);
+ }
+ }
+}
diff --git a/DDrawCompat/Win32/WaitFunctions.h b/DDrawCompat/Win32/WaitFunctions.h
new file mode 100644
index 0000000..0b095d6
--- /dev/null
+++ b/DDrawCompat/Win32/WaitFunctions.h
@@ -0,0 +1,9 @@
+#pragma once
+
+namespace Win32
+{
+ namespace WaitFunctions
+ {
+ void installHooks();
+ }
+}