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)