From da09069d7b2b0d443eafd618dd9acc65da1a17f7 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Wed, 22 Jan 2020 11:35:04 +0100 Subject: [PATCH] adjust fps limiter for gdi renderer --- inc/main.h | 1 - src/main.c | 7 ------- src/render_soft.c | 47 ++++++++++++++++++++++++++++++++--------------- src/surface.c | 24 +++--------------------- 4 files changed, 35 insertions(+), 44 deletions(-) diff --git a/inc/main.h b/inc/main.h index d2b968e..17e11d5 100644 --- a/inc/main.h +++ b/inc/main.h @@ -94,7 +94,6 @@ typedef struct IDirectDrawImpl HANDLE thread; BOOL run; - HANDLE ev; HANDLE sem; DEVMODE mode; struct { int width; int height; int x; int y; } viewport; diff --git a/src/main.c b/src/main.c index 25baa8d..82c13fe 100644 --- a/src/main.c +++ b/src/main.c @@ -1777,12 +1777,6 @@ ULONG __stdcall ddraw_Release(IDirectDrawImpl *This) ReleaseDC(This->hWnd, This->render.hDC); This->render.hDC = NULL; } - - if(This->render.ev) - { - CloseHandle(This->render.ev); - ddraw->render.ev = NULL; - } if (This->ticksLimiter.hTimer) { @@ -1919,7 +1913,6 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk } InitializeCriticalSection(&This->cs); - This->render.ev = CreateEvent(NULL, TRUE, FALSE, NULL); This->render.sem = CreateSemaphore(NULL, 0, 1, NULL); This->wine = GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0; diff --git a/src/render_soft.c b/src/render_soft.c index f36ef4b..e09a480 100644 --- a/src/render_soft.c +++ b/src/render_soft.c @@ -42,7 +42,8 @@ DWORD WINAPI render_soft_main(void) Sleep(500); - DWORD lastTick = 0; + DWORD tickStart = 0; + DWORD tickEnd = 0; int maxFPS = ddraw->render.maxfps; ddraw->fpsLimiter.tickLengthNs = 0; ddraw->fpsLimiter.ticklength = 0; @@ -62,23 +63,13 @@ DWORD WINAPI render_soft_main(void) while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) { - if (ddraw->fpsLimiter.ticklength > 0) - { - DWORD curTick = timeGetTime(); - if (lastTick + ddraw->fpsLimiter.ticklength > curTick) - { - ReleaseSemaphore(ddraw->render.sem, 1, NULL); - SetEvent(ddraw->render.ev); - SwitchToThread(); - continue; - } - lastTick = curTick; - } - #if _DEBUG DrawFrameInfoStart(); #endif + if (ddraw->fpsLimiter.ticklength > 0) + tickStart = timeGetTime(); + EnterCriticalSection(&ddraw->cs); if (ddraw->primary && (ddraw->bpp == 16 || (ddraw->primary->palette && ddraw->primary->palette->data_rgb))) @@ -168,7 +159,33 @@ DWORD WINAPI render_soft_main(void) DrawFrameInfoEnd(); #endif - SetEvent(ddraw->render.ev); + if (ddraw->fpsLimiter.ticklength > 0) + { + if (ddraw->fpsLimiter.hTimer) + { + FILETIME ft = { 0 }; + GetSystemTimeAsFileTime(&ft); + + if (CompareFileTime((FILETIME*)&ddraw->fpsLimiter.dueTime, &ft) == -1) + { + memcpy(&ddraw->fpsLimiter.dueTime, &ft, sizeof(LARGE_INTEGER)); + } + else + { + WaitForSingleObject(ddraw->fpsLimiter.hTimer, ddraw->fpsLimiter.ticklength * 2); + } + + ddraw->fpsLimiter.dueTime.QuadPart += ddraw->fpsLimiter.tickLengthNs; + SetWaitableTimer(ddraw->fpsLimiter.hTimer, &ddraw->fpsLimiter.dueTime, 0, NULL, NULL, FALSE); + } + else + { + tickEnd = timeGetTime(); + + if (tickEnd - tickStart < ddraw->fpsLimiter.ticklength) + Sleep(ddraw->fpsLimiter.ticklength - (tickEnd - tickStart)); + } + } } return TRUE; diff --git a/src/surface.c b/src/surface.c index a78acc7..e9b2d19 100644 --- a/src/surface.c +++ b/src/surface.c @@ -466,15 +466,7 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR { InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE); ReleaseSemaphore(ddraw->render.sem, 1, NULL); - if (ddraw->renderer == render_soft_main) - { - WaitForSingleObject(ddraw->render.ev, INFINITE); - ResetEvent(ddraw->render.ev); - } - else - { - SwitchToThread(); - } + SwitchToThread(); if (ddraw->ticksLimiter.ticklength > 0) { @@ -696,18 +688,8 @@ HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWS This->lastFlipTick = timeGetTime(); InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE); - - if (ddraw->renderer == render_soft_main) - { - ResetEvent(ddraw->render.ev); - ReleaseSemaphore(ddraw->render.sem, 1, NULL); - WaitForSingleObject(ddraw->render.ev, INFINITE); - } - else - { - ReleaseSemaphore(ddraw->render.sem, 1, NULL); - SwitchToThread(); - } + ReleaseSemaphore(ddraw->render.sem, 1, NULL); + SwitchToThread(); if (flags & DDFLIP_WAIT) {