diff --git a/src/main.c b/src/main.c index b74f1e8..a40c00c 100644 --- a/src/main.c +++ b/src/main.c @@ -1747,11 +1747,49 @@ HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DW return DD_OK; } -HRESULT __stdcall ddraw_WaitForVerticalBlank(IDirectDrawImpl *This, DWORD a, HANDLE b) +HRESULT __stdcall ddraw_WaitForVerticalBlank(IDirectDrawImpl *This, DWORD dwFlags, HANDLE h) { #if _DEBUG_X - printf("??? DirectDraw::WaitForVerticalBlank(This=%p, ...)\n", This); + printf("DirectDraw::WaitForVerticalBlank(This=%p, flags=%08X, handle=%p)\n", This, dwFlags, h); #endif + + FILETIME lastFlipFT = { 0 }; + if (ddraw->flipLimiter.hTimer) + GetSystemTimeAsFileTime(&lastFlipFT); + + if (ddraw->flipLimiter.hTimer) + { + if (!ddraw->flipLimiter.dueTime.QuadPart) + { + memcpy(&ddraw->flipLimiter.dueTime, &lastFlipFT, sizeof(LARGE_INTEGER)); + } + else + { + while (CompareFileTime((FILETIME*)&ddraw->flipLimiter.dueTime, &lastFlipFT) == -1) + ddraw->flipLimiter.dueTime.QuadPart += ddraw->flipLimiter.tickLengthNs; + + SetWaitableTimer(ddraw->flipLimiter.hTimer, &ddraw->flipLimiter.dueTime, 0, NULL, NULL, FALSE); + WaitForSingleObject(ddraw->flipLimiter.hTimer, ddraw->flipLimiter.ticklength * 2); + } + } + else + { + static DWORD nextGameTick; + if (!nextGameTick) + { + nextGameTick = timeGetTime(); + return; + } + nextGameTick += ddraw->flipLimiter.ticklength; + DWORD tickCount = timeGetTime(); + + int sleepTime = nextGameTick - tickCount; + if (sleepTime <= 0 || sleepTime > ddraw->flipLimiter.ticklength) + nextGameTick = tickCount; + else + Sleep(sleepTime); + } + return DD_OK; } diff --git a/src/surface.c b/src/surface.c index 64c94b9..6055a4a 100644 --- a/src/surface.c +++ b/src/surface.c @@ -681,10 +681,6 @@ HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWS if(This->caps & DDSCAPS_PRIMARYSURFACE && ddraw->render.run) { - FILETIME lastFlipFT = { 0 }; - if (ddraw->flipLimiter.hTimer) - GetSystemTimeAsFileTime(&lastFlipFT); - This->lastFlipTick = timeGetTime(); InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE); @@ -693,34 +689,7 @@ HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWS if (flags & DDFLIP_WAIT) { - if (ddraw->flipLimiter.hTimer) - { - if (!ddraw->flipLimiter.dueTime.QuadPart) - { - memcpy(&ddraw->flipLimiter.dueTime, &lastFlipFT, sizeof(LARGE_INTEGER)); - } - else - { - while (CompareFileTime((FILETIME *)&ddraw->flipLimiter.dueTime, &lastFlipFT) == -1) - ddraw->flipLimiter.dueTime.QuadPart += ddraw->flipLimiter.tickLengthNs; - - SetWaitableTimer(ddraw->flipLimiter.hTimer, &ddraw->flipLimiter.dueTime, 0, NULL, NULL, FALSE); - WaitForSingleObject(ddraw->flipLimiter.hTimer, ddraw->flipLimiter.ticklength * 2); - } - } - else - { - DWORD tick = This->lastFlipTick; - while (tick % ddraw->flipLimiter.ticklength) tick++; - int sleepTime = tick - This->lastFlipTick; - - int renderTime = timeGetTime() - This->lastFlipTick; - if (renderTime > 0) - sleepTime -= renderTime; - - if (sleepTime > 0 && sleepTime <= ddraw->flipLimiter.ticklength) - Sleep(sleepTime); - } + IDirectDraw_WaitForVerticalBlank(ddraw, DDWAITVB_BLOCKEND, NULL); } if (ddraw->ticksLimiter.ticklength > 0)