diff --git a/inc/main.h b/inc/main.h
index 67d92dd..cef61b7 100644
--- a/inc/main.h
+++ b/inc/main.h
@@ -32,6 +32,7 @@ extern BOOL ShowDriverWarning;
 extern RECT WindowRect;
 
 BOOL detect_cutscene();
+void LimitGameTicks();
 DWORD WINAPI render_main(void);
 DWORD WINAPI render_soft_main(void);
 
@@ -104,8 +105,8 @@ typedef struct IDirectDrawImpl
     BOOL hidemouse;
     char shader[MAX_PATH];
     BOOL wine;
-    int sleep;
     LONG minimized;
+    DWORD ticklength;
     
 } IDirectDrawImpl;
 
diff --git a/src/main.c b/src/main.c
index 35d66a7..8a1cf37 100644
--- a/src/main.c
+++ b/src/main.c
@@ -131,6 +131,24 @@ BOOL detect_cutscene()
     return FALSE;
 }
 
+void LimitGameTicks()
+{
+    static DWORD nextGameTick;
+    if (!nextGameTick)
+    {
+        nextGameTick = timeGetTime();
+        return;
+    }
+    nextGameTick += ddraw->ticklength;
+    DWORD tickCount = timeGetTime();
+
+    int sleepTime = nextGameTick - tickCount;
+    if (sleepTime <= 0 || sleepTime > ddraw->ticklength)
+        nextGameTick = tickCount;
+    else
+        Sleep(sleepTime);
+}
+
 HRESULT __stdcall ddraw_Compact(IDirectDrawImpl *This)
 {
     printf("DirectDraw::Compact(This=%p) ???\n", This);
diff --git a/src/settings.c b/src/settings.c
index f2e1d70..7ef9709 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -43,13 +43,16 @@ void Settings_Load()
     ddraw->vhack = GetBool("vhack", FALSE);
     ddraw->hidemouse = GetBool("hidemouse", TRUE);
 
-    ddraw->sleep = GetInt("sleep", 0);
     ddraw->render.maxfps = GetInt("maxfps", 125);
     WindowRect.right = GetInt("width", 0);
     WindowRect.bottom = GetInt("height", 0);
     WindowRect.left = GetInt("posX", -32000);
     WindowRect.top = GetInt("posY", -32000);
 
+    int maxTicks = GetInt("maxgameticks", 0);
+    if (maxTicks > 0 && maxTicks < 1000)
+        ddraw->ticklength = 1000.0f / maxTicks;
+
     GetString("screenshotKey", "G", tmp, sizeof(tmp));
     ddraw->screenshotKey = toupper(tmp[0]);
 
@@ -195,18 +198,18 @@ static void CreateSettingsIni()
             "devmode=false\n"
             "; preliminary libretro shader support - e.g. cubic.glsl (OpenGL only) https://github.com/libretro/glsl-shaders\n"
             "shader=\n"
-            "; Sleep for X ms after drawing each frame (Slows down scrollrate on C&C95 / Prevents visual glitches on Carmageddon)\n"
-            "sleep=0\n"
+            "; Max game ticks per second (Can be used to slow down a too fast running game)\n"
+            "maxgameticks=0\n"
             "; Hide/Show the mouse cursor on lock/unlock (Ctrl+Tab)\n"
             "hidemouse=true\n"
             "\n"
             "[CARMA95]\n"
             "fakecursorpos=false\n"
             "noactivateapp=true\n"
-            "sleep=33\n"
+            "maxgameticks=30\n"
             "\n"
             "[C&C95]\n"
-            "sleep=10\n"
+            "maxgameticks=60\n"
             "\n"
             "[empires]\n"
             "hidemouse=false\n"
@@ -234,7 +237,7 @@ static void CreateSettingsIni()
             "\n"
             "[olwin]\n"
             "noactivateapp=true\n"
-            "sleep=10\n"
+            "maxgameticks=60\n"
             "\n"
             "[KEEPER95]\n"
             "border=false\n"
@@ -242,7 +245,7 @@ static void CreateSettingsIni()
             "posY=0\n"
             "\n"
             "[DKReign]\n"
-            "sleep=10\n"
+            "maxgameticks=60\n"
             "\n"
 
             , fh);
diff --git a/src/surface.c b/src/surface.c
index 8d79e44..36b5d28 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -199,8 +199,8 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR
             SwitchToThread();
         }
 
-        if (ddraw->sleep > 0)
-            Sleep(ddraw->sleep);
+        if (ddraw->ticklength > 0)
+            LimitGameTicks();
     }
 
     return DD_OK;
@@ -366,8 +366,8 @@ HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWS
             SwitchToThread();
         }
 
-        if (ddraw->sleep > 0)
-            Sleep(ddraw->sleep);
+        if (ddraw->ticklength > 0)
+            LimitGameTicks();
     }
 
     return DD_OK;