From 0e6d415f636250e5594b3f23623d04270669e13c Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Wed, 31 Oct 2018 11:48:41 +0100 Subject: [PATCH] remove sleep hack and add a smarter game speed limiter that takes the games performance into account --- inc/main.h | 3 ++- src/main.c | 18 ++++++++++++++++++ src/settings.c | 17 ++++++++++------- src/surface.c | 8 ++++---- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/inc/main.h b/inc/main.h index 67d92dd..cef61b7 100644 --- a/inc/main.h +++ b/inc/main.h @@ -32,6 +32,7 @@ extern BOOL ShowDriverWarning; extern RECT WindowRect; BOOL detect_cutscene(); +void LimitGameTicks(); DWORD WINAPI render_main(void); DWORD WINAPI render_soft_main(void); @@ -104,8 +105,8 @@ typedef struct IDirectDrawImpl BOOL hidemouse; char shader[MAX_PATH]; BOOL wine; - int sleep; LONG minimized; + DWORD ticklength; } IDirectDrawImpl; diff --git a/src/main.c b/src/main.c index 35d66a7..8a1cf37 100644 --- a/src/main.c +++ b/src/main.c @@ -131,6 +131,24 @@ BOOL detect_cutscene() return FALSE; } +void LimitGameTicks() +{ + static DWORD nextGameTick; + if (!nextGameTick) + { + nextGameTick = timeGetTime(); + return; + } + nextGameTick += ddraw->ticklength; + DWORD tickCount = timeGetTime(); + + int sleepTime = nextGameTick - tickCount; + if (sleepTime <= 0 || sleepTime > ddraw->ticklength) + nextGameTick = tickCount; + else + Sleep(sleepTime); +} + HRESULT __stdcall ddraw_Compact(IDirectDrawImpl *This) { printf("DirectDraw::Compact(This=%p) ???\n", This); diff --git a/src/settings.c b/src/settings.c index f2e1d70..7ef9709 100644 --- a/src/settings.c +++ b/src/settings.c @@ -43,13 +43,16 @@ void Settings_Load() ddraw->vhack = GetBool("vhack", FALSE); ddraw->hidemouse = GetBool("hidemouse", TRUE); - ddraw->sleep = GetInt("sleep", 0); ddraw->render.maxfps = GetInt("maxfps", 125); WindowRect.right = GetInt("width", 0); WindowRect.bottom = GetInt("height", 0); WindowRect.left = GetInt("posX", -32000); WindowRect.top = GetInt("posY", -32000); + int maxTicks = GetInt("maxgameticks", 0); + if (maxTicks > 0 && maxTicks < 1000) + ddraw->ticklength = 1000.0f / maxTicks; + GetString("screenshotKey", "G", tmp, sizeof(tmp)); ddraw->screenshotKey = toupper(tmp[0]); @@ -195,18 +198,18 @@ static void CreateSettingsIni() "devmode=false\n" "; preliminary libretro shader support - e.g. cubic.glsl (OpenGL only) https://github.com/libretro/glsl-shaders\n" "shader=\n" - "; Sleep for X ms after drawing each frame (Slows down scrollrate on C&C95 / Prevents visual glitches on Carmageddon)\n" - "sleep=0\n" + "; Max game ticks per second (Can be used to slow down a too fast running game)\n" + "maxgameticks=0\n" "; Hide/Show the mouse cursor on lock/unlock (Ctrl+Tab)\n" "hidemouse=true\n" "\n" "[CARMA95]\n" "fakecursorpos=false\n" "noactivateapp=true\n" - "sleep=33\n" + "maxgameticks=30\n" "\n" "[C&C95]\n" - "sleep=10\n" + "maxgameticks=60\n" "\n" "[empires]\n" "hidemouse=false\n" @@ -234,7 +237,7 @@ static void CreateSettingsIni() "\n" "[olwin]\n" "noactivateapp=true\n" - "sleep=10\n" + "maxgameticks=60\n" "\n" "[KEEPER95]\n" "border=false\n" @@ -242,7 +245,7 @@ static void CreateSettingsIni() "posY=0\n" "\n" "[DKReign]\n" - "sleep=10\n" + "maxgameticks=60\n" "\n" , fh); diff --git a/src/surface.c b/src/surface.c index 8d79e44..36b5d28 100644 --- a/src/surface.c +++ b/src/surface.c @@ -199,8 +199,8 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR SwitchToThread(); } - if (ddraw->sleep > 0) - Sleep(ddraw->sleep); + if (ddraw->ticklength > 0) + LimitGameTicks(); } return DD_OK; @@ -366,8 +366,8 @@ HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWS SwitchToThread(); } - if (ddraw->sleep > 0) - Sleep(ddraw->sleep); + if (ddraw->ticklength > 0) + LimitGameTicks(); } return DD_OK;