From edb0f430916cd81ff73305a026f12e351214b4a9 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 31 May 2024 21:43:33 +0200 Subject: [PATCH] tweak ticks limiter for nancy drew games --- inc/config.h | 2 +- inc/dd.h | 7 ++++++- src/IDirectDraw/IDirectDraw.c | 2 +- src/config.c | 18 ++++++++++-------- src/dd.c | 11 +++++++++++ src/ddsurface.c | 24 +++++++----------------- 6 files changed, 36 insertions(+), 28 deletions(-) diff --git a/inc/config.h b/inc/config.h index abaa180..0e9f89d 100644 --- a/inc/config.h +++ b/inc/config.h @@ -47,6 +47,7 @@ typedef struct CNCDDRAWCONFIG BOOL noactivateapp; int maxgameticks; + int limiter_type; int minfps; BOOL nonexclusive; BOOL singlecpu; @@ -62,7 +63,6 @@ typedef struct CNCDDRAWCONFIG int hook; int guard_lines; int max_resolutions; - BOOL limit_bltfast; BOOL lock_surfaces; BOOL allow_wmactivate; BOOL flipclear; diff --git a/inc/dd.h b/inc/dd.h index 01e535e..e28249a 100644 --- a/inc/dd.h +++ b/inc/dd.h @@ -24,6 +24,7 @@ HRESULT dd_GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc); HRESULT dd_GetMonitorFrequency(LPDWORD lpdwFreq); HRESULT dd_GetAvailableVidMem(LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree); HRESULT dd_GetVerticalBlankStatus(LPBOOL lpbIsInVB); +HRESULT dd_TestCooperativeLevel(); HRESULT dd_GetDeviceIdentifier(LPDDDEVICEIDENTIFIER pDDDI, DWORD dwFlags, REFIID riid); HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOuter); @@ -45,13 +46,17 @@ HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOute #define SDM_LEAVE_WINDOWED 0x00000002l #define SDM_LEAVE_FULLSCREEN 0x00000004l +#define LIMIT_AUTO 0 +#define LIMIT_TESTCOOP 1 +#define LIMIT_BLTFAST 2 + typedef struct SPEEDLIMITER { DWORD tick_length; LONGLONG tick_length_ns; HANDLE htimer; LARGE_INTEGER due_time; - BOOL use_blt_or_flip; + BOOL dds_unlock_limiter_disabled; } SPEEDLIMITER; struct IDirectDrawSurfaceImpl; diff --git a/src/IDirectDraw/IDirectDraw.c b/src/IDirectDraw/IDirectDraw.c index 3bd8379..3de9572 100644 --- a/src/IDirectDraw/IDirectDraw.c +++ b/src/IDirectDraw/IDirectDraw.c @@ -487,7 +487,7 @@ HRESULT __stdcall IDirectDraw__RestoreAllSurfaces(IDirectDrawImpl* This) HRESULT __stdcall IDirectDraw__TestCooperativeLevel(IDirectDrawImpl* This) { TRACE_EXT("-> %s(This=%p)\n", __FUNCTION__, This); - HRESULT ret = g_config.tlc_hack ? DDERR_NOEXCLUSIVEMODE : DD_OK; + HRESULT ret = dd_TestCooperativeLevel(); TRACE_EXT("<- %s\n", __FUNCTION__); return ret; } diff --git a/src/config.c b/src/config.c index 37d7f0e..0b4c5a3 100644 --- a/src/config.c +++ b/src/config.c @@ -59,6 +59,7 @@ void cfg_load() GET_BOOL(g_config.noactivateapp, "noactivateapp", FALSE); GET_INT(g_config.maxgameticks, "maxgameticks", 0); + GET_INT(g_config.limiter_type, "limiter_type", LIMIT_AUTO); GET_INT(g_config.minfps, "minfps", 0); GET_BOOL(g_config.nonexclusive, "nonexclusive", FALSE); GET_BOOL(g_config.singlecpu, "singlecpu", TRUE); @@ -75,7 +76,6 @@ void cfg_load() GET_INT(g_config.hook, "hook", 4); GET_INT(g_config.guard_lines, "guard_lines", 200); GET_INT(g_config.max_resolutions, "max_resolutions", 0); - GET_BOOL(g_config.limit_bltfast, "limit_bltfast", FALSE); GET_BOOL(g_config.lock_surfaces, "lock_surfaces", FALSE); GET_BOOL(g_config.allow_wmactivate, "allow_wmactivate", FALSE); GET_BOOL(g_config.flipclear, "flipclear", FALSE); @@ -262,6 +262,9 @@ static void cfg_create_ini() "; Note: Usually one of the following values will work: 60 / 30 / 25 / 20 / 15 (lower value = slower game speed)\n" "maxgameticks=0\n" "\n" + "; Method that should be used to limit game ticks (maxgameticks=): 0 = Automatic, 1 = TestCooperativeLevel, 2 = BltFast\n" + "limiter_type=0\n" + "\n" "; Force minimum FPS, possible values: 0 = disabled, -1 = use 'maxfps=' value, -2 = same as -1 but force full redraw, 1-1000 = custom FPS\n" "; Note: Set this to a low value such as 5 or 10 if some parts of the game are not being displayed (e.g. menus or loading screens)\n" "minfps=0\n" @@ -295,7 +298,6 @@ static void cfg_create_ini() "hook=4\n" "guard_lines=200\n" "max_resolutions=0\n" - "limit_bltfast=false\n" "lock_surfaces=false\n" "allow_wmactivate=false\n" "flipclear=false\n" @@ -779,7 +781,7 @@ static void cfg_create_ini() "[AdSanguo]\n" "maxgameticks=60\n" "noactivateapp=true\n" - "limit_bltfast=true\n" + "limiter_type=2\n" "\n" "; Dark Reign: The Future of War\n" "[DKReign]\n" @@ -983,12 +985,12 @@ static void cfg_create_ini() "\n" "; Knights and Merchants The Shattered Kingdom\n" "[KaM_800]\n" - "limit_bltfast=true\n" + "limiter_type=2\n" "maxgameticks=60\n" "\n" "; Knights and Merchants The Shattered Kingdom\n" "[KaM_1024]\n" - "limit_bltfast=true\n" + "limiter_type=2\n" "maxgameticks=60\n" "\n" "; Little Bear Kindergarten/Preschool Thinking Adventures: Parent's Progress Report\n" @@ -1083,13 +1085,13 @@ static void cfg_create_ini() "; Nancy Drew: Message in a Haunted Mansion\n" "[Game/3]\n" "checkfile=.\\DataFiles\\ASABYBD.cal\n" - "limit_bltfast=true\n" + "limiter_type=2\n" "maxgameticks=600\n" "\n" "; Nancy Drew: Secret of Shadow Ranch\n" "[Game/4]\n" "checkfile=.\\DataFiles\\DGEBody.cal\n" - "limit_bltfast=true\n" + "limiter_type=2\n" "maxgameticks=1000\n" "\n" "; Nox\n" @@ -1382,7 +1384,7 @@ static void cfg_create_ini() "[sanguo]\n" "maxgameticks=60\n" "noactivateapp=true\n" - "limit_bltfast=true\n" + "limiter_type=2\n" "\n" "; RollerCoaster Tycoon\n" "[rct]\n" diff --git a/src/dd.c b/src/dd.c index fe94379..20203fe 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1531,6 +1531,17 @@ HRESULT dd_GetVerticalBlankStatus(LPBOOL lpbIsInVB) return DD_OK; } +HRESULT dd_TestCooperativeLevel() +{ + if (g_config.limiter_type == LIMIT_TESTCOOP && g_ddraw.ticks_limiter.tick_length > 0) + { + g_ddraw.ticks_limiter.dds_unlock_limiter_disabled = TRUE; + util_limit_game_ticks(); + } + + return g_config.tlc_hack ? DDERR_NOEXCLUSIVEMODE : DD_OK; +} + HRESULT dd_GetDeviceIdentifier(LPDDDEVICEIDENTIFIER pDDDI, DWORD dwFlags, REFIID riid) { if (!pDDDI) diff --git a/src/ddsurface.c b/src/ddsurface.c index 5c52221..2c14a2a 100644 --- a/src/ddsurface.c +++ b/src/ddsurface.c @@ -429,7 +429,7 @@ HRESULT dds_Blt( if (g_ddraw.ticks_limiter.tick_length > 0) { - g_ddraw.ticks_limiter.use_blt_or_flip = TRUE; + g_ddraw.ticks_limiter.dds_unlock_limiter_disabled = TRUE; util_limit_game_ticks(); } } @@ -659,9 +659,9 @@ HRESULT dds_BltFast( if (!(This->flags & DDSD_BACKBUFFERCOUNT) || (This->last_flip_tick + FLIP_REDRAW_TIMEOUT < time && This->last_blt_tick + FLIP_REDRAW_TIMEOUT < time)) { - if (g_config.limit_bltfast && g_ddraw.ticks_limiter.tick_length > 0) + if (g_config.limiter_type == LIMIT_BLTFAST && g_ddraw.ticks_limiter.tick_length > 0) { - g_ddraw.ticks_limiter.use_blt_or_flip = TRUE; + g_ddraw.ticks_limiter.dds_unlock_limiter_disabled = TRUE; util_limit_game_ticks(); } } @@ -810,7 +810,7 @@ HRESULT dds_Flip(IDirectDrawSurfaceImpl* This, IDirectDrawSurfaceImpl* lpDDSurfa if (g_ddraw.ticks_limiter.tick_length > 0) { - g_ddraw.ticks_limiter.use_blt_or_flip = TRUE; + g_ddraw.ticks_limiter.dds_unlock_limiter_disabled = TRUE; util_limit_game_ticks(); } } @@ -1133,12 +1133,7 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect) if (erase) { - BOOL x = g_ddraw.ticks_limiter.use_blt_or_flip; - - DDBLTFX fx = { .dwFillColor = 0xFE }; - IDirectDrawSurface_Blt(This, NULL, NULL, NULL, DDBLT_COLORFILL, &fx); - - g_ddraw.ticks_limiter.use_blt_or_flip = x; + blt_clear(This->surface, 0xFE, This->size); } } @@ -1172,12 +1167,7 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect) ReleaseDC(hwnd, hdc); } - BOOL x = g_ddraw.ticks_limiter.use_blt_or_flip; - - DDBLTFX fx = { .dwFillColor = 0 }; - IDirectDrawSurface_Blt(This, NULL, NULL, NULL, DDBLT_COLORFILL, &fx); - - g_ddraw.ticks_limiter.use_blt_or_flip = x; + blt_clear(This->surface, 0x00, This->size); } @@ -1191,7 +1181,7 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect) if (!(This->flags & DDSD_BACKBUFFERCOUNT) || (This->last_flip_tick + FLIP_REDRAW_TIMEOUT < time && This->last_blt_tick + FLIP_REDRAW_TIMEOUT < time)) { - if (g_ddraw.ticks_limiter.tick_length > 0 && !g_ddraw.ticks_limiter.use_blt_or_flip) + if (g_ddraw.ticks_limiter.tick_length > 0 && !g_ddraw.ticks_limiter.dds_unlock_limiter_disabled) util_limit_game_ticks(); } }