1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-24 17:49:52 +01:00

add support for WaitForVerticalBlank

This commit is contained in:
FunkyFr3sh 2020-10-04 18:07:59 +02:00
parent 1303d105f3
commit ab06a682bb
2 changed files with 41 additions and 34 deletions

View File

@ -1747,11 +1747,49 @@ HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DW
return DD_OK; 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 #if _DEBUG_X
printf("??? DirectDraw::WaitForVerticalBlank(This=%p, ...)\n", This); printf("DirectDraw::WaitForVerticalBlank(This=%p, flags=%08X, handle=%p)\n", This, dwFlags, h);
#endif #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; return DD_OK;
} }

View File

@ -681,10 +681,6 @@ HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWS
if(This->caps & DDSCAPS_PRIMARYSURFACE && ddraw->render.run) if(This->caps & DDSCAPS_PRIMARYSURFACE && ddraw->render.run)
{ {
FILETIME lastFlipFT = { 0 };
if (ddraw->flipLimiter.hTimer)
GetSystemTimeAsFileTime(&lastFlipFT);
This->lastFlipTick = timeGetTime(); This->lastFlipTick = timeGetTime();
InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE); InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE);
@ -693,34 +689,7 @@ HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWS
if (flags & DDFLIP_WAIT) if (flags & DDFLIP_WAIT)
{ {
if (ddraw->flipLimiter.hTimer) IDirectDraw_WaitForVerticalBlank(ddraw, DDWAITVB_BLOCKEND, NULL);
{
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);
}
} }
if (ddraw->ticksLimiter.ticklength > 0) if (ddraw->ticksLimiter.ticklength > 0)