improved synchronization of main game loop
[rocksndiamonds.git] / src / events.c
index e82d3667b42958144a01fdce30e24a70a3b8cec9..4c71dca04ece48c1d1e0b436656b51234f4c5c90 100644 (file)
@@ -19,6 +19,7 @@
 #include "editor.h"
 #include "files.h"
 #include "tape.h"
+#include "cartoons.h"
 #include "network.h"
 
 
@@ -153,12 +154,20 @@ boolean NextValidEvent(Event *event)
 
 void EventLoop(void)
 {
+  static unsigned int sync_frame_delay = 0;
+  unsigned int sync_frame_delay_value = GAME_FRAME_DELAY;
+
   while (1)
   {
     if (PendingEvent())                /* got event */
     {
+      // use separate frame delay counter to not reset main delay counter
+      unsigned int sync_frame_delay2 = 0;
+      unsigned int sync_frame_delay_value2 = sync_frame_delay_value;
       Event event;
 
+      ResetDelayCounter(&sync_frame_delay2);
+
       while (NextValidEvent(&event))
       {
        switch (event.type)
@@ -204,9 +213,14 @@ void EventLoop(void)
            HandleOtherEvents(&event);
            break;
        }
+
+       // do not handle events for longer than standard frame delay period
+       if (DelayReached(&sync_frame_delay2, sync_frame_delay_value2))
+         break;
       }
     }
-    else
+
+    // always handle non-event game actions for every game frame interval
     {
       if (game_status == GAME_MODE_TITLE)
       {
@@ -246,18 +260,14 @@ void EventLoop(void)
        has its own synchronization and is CPU friendly, too */
 
     if (game_status == GAME_MODE_PLAYING)
-    {
       HandleGameActions();
-    }
-    else
-    {
-      if (!PendingEvent())     /* delay only if no pending events */
-       Delay(10);
-    }
 
     /* refresh window contents from drawing buffer, if needed */
     BackToFront();
 
+    if (game_status != GAME_MODE_PLAYING)
+      WaitUntilDelayReached(&sync_frame_delay, sync_frame_delay_value);
+
     if (game_status == GAME_MODE_QUIT)
       return;
   }
@@ -1567,7 +1577,8 @@ void HandleKey(Key key, int key_status)
     default:
       if (key == KSYM_Escape)
       {
-       game_status = GAME_MODE_MAIN;
+       SetGameStatus(GAME_MODE_MAIN);
+
        DrawMainMenu();
 
        return;