From b03c7d5ebd083997cb907273c9544b66e9ed7d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reimar=20D=C3=B6ffinger?= Date: Sat, 2 Feb 2019 15:50:14 +0100 Subject: [PATCH] Implement generic CPU time limiter. --- impl11/ddraw/config.cpp | 16 ++++++++++++++++ impl11/ddraw/joystick.cpp | 26 ++++++++++++++++++++++++++ impl11/ddraw/joystick.h | 1 + 3 files changed, 43 insertions(+) diff --git a/impl11/ddraw/config.cpp b/impl11/ddraw/config.cpp index 9089d28f..841ef246 100644 --- a/impl11/ddraw/config.cpp +++ b/impl11/ddraw/config.cpp @@ -22,6 +22,14 @@ static int isspace_wrapper(char c) return std::isspace(static_cast(c)); } +static void patchTimeGetTime(unsigned *addr) +{ + DWORD old, dummy; + VirtualProtect(addr, 4, PAGE_READWRITE, &old); + *addr = reinterpret_cast(emulGetTime); + VirtualProtect(addr, 4, old, &dummy); +} + Config g_config; Config::Config() @@ -219,6 +227,14 @@ Config::Config() *(unsigned *)0x4f3e54 = 0; } + if (AutoPatch >= 2 && RefreshLimit == 1) + { + if (isBoP) patchTimeGetTime((unsigned *)0xbb96b8); + if (isXvT) patchTimeGetTime((unsigned *)0x86070c); + if (isXWing) patchTimeGetTime((unsigned *)0x4c31ec); + if (isTIE) patchTimeGetTime((unsigned *)0x4dc264); + } + if (this->JoystickEmul != 0 && isXWing) { // TODO: How to check if this is a supported binary? diff --git a/impl11/ddraw/joystick.cpp b/impl11/ddraw/joystick.cpp index c6101035..5f9773fc 100755 --- a/impl11/ddraw/joystick.cpp +++ b/impl11/ddraw/joystick.cpp @@ -16,6 +16,32 @@ #undef max #include +// timeGetTime emulation. +// if it is called in a tight loop it will call Sleep() +// prevents high CPU usage due to busy loop +DWORD emulGetTime() +{ + static DWORD oldtime; + static DWORD count; + DWORD time = timeGetTime(); + if (time != oldtime) + { + oldtime = time; + count = 0; + } + // Trigger value and sleep value derived by trial and error. + // Trigger values down to 10 with sleep value 8 do not seem to affect performance + // even at 60 FPS, and trigger values up to 1000 with sleep value 1 still seem effective + // to reduce CPU load on fast modern computers. + if (++count >= 20) + { + Sleep(2); + time = timeGetTime(); + count = 0; + } + return time; +} + static int needsJoyEmul() { JOYCAPS caps = {}; diff --git a/impl11/ddraw/joystick.h b/impl11/ddraw/joystick.h index d9dd0c96..921c20d6 100755 --- a/impl11/ddraw/joystick.h +++ b/impl11/ddraw/joystick.h @@ -5,6 +5,7 @@ #include "common.h" +extern "C" DWORD emulGetTime(void); extern "C" UINT WINAPI emulJoyGetNumDevs(void); extern "C" UINT WINAPI emulJoyGetDevCaps(UINT_PTR, struct tagJOYCAPSA *, UINT); extern "C" UINT WINAPI emulJoyGetPosEx(UINT, struct joyinfoex_tag *);