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(); + } +}