using SDL for timekeeping
authorJavier S. Pedro <javier@javispedro.com>
Sun, 23 Aug 2009 18:45:39 +0000 (20:45 +0200)
committerJavier S. Pedro <javier@javispedro.com>
Sun, 23 Aug 2009 18:45:39 +0000 (20:45 +0200)
platform/config.cpp
platform/sdl.cpp

index 34f6d91..e925a1d 100644 (file)
@@ -175,8 +175,8 @@ static void loadDefaults()
        Settings.H_Max = SNES_CYCLES_PER_SCANLINE;
        Settings.SkipFrames = AUTO_FRAMERATE;
        Settings.Shutdown = Settings.ShutdownMaster = TRUE;
-       Settings.FrameTimePAL = 20000;  // in usecs
-       Settings.FrameTimeNTSC = 16667;
+       Settings.FrameTimePAL = 20;     // in msecs
+       Settings.FrameTimeNTSC = 16;
        Settings.FrameTime = Settings.FrameTimeNTSC;
        Settings.DisableSampleCaching = FALSE;
        Settings.DisableMasterVolume = FALSE;
index 0978504..a6f1fde 100644 (file)
@@ -118,9 +118,6 @@ static void pauseGame()
 
 /* This comes nearly straight from snes9x */
 static void frameSync() {
-       static struct timeval next1 = {0, 0};
-       struct timeval now;
-       
        if (Settings.TurboMode)
        {
                if(Settings.SkipFrames == AUTO_FRAMERATE || 
@@ -136,77 +133,50 @@ static void frameSync() {
                        IPPU.RenderThisFrame = FALSE;
                }
                return;
+       } else {
+               static Uint32 next1 = 0;
+               Uint32 now = SDL_GetTicks();
+
+               // If there is no known "next" frame, initialize it now
+               if (next1 == 0) {
+                       next1 = now + 1;
+               }
+
+               // If we're on AUTO_FRAMERATE, we'll display frames always
+               // only if there's excess time.
+               // Otherwise we'll display around 1 frame every 10.
+               unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE
+                                       ? (next1 < now ? 10 : 1)
+                                       : Settings.SkipFrames;
+
+               IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit;
+               if (IPPU.RenderThisFrame) {
+                       IPPU.SkippedFrames = 0;
+               } else {
+                       // If we were behind the schedule, check how much it is
+                       if (next1 < now)
+                       {
+                       unsigned long lag = now - next1;
+                       if (lag >= 500)
+                               {
+                                       // More than a half-second behind means probably
+                                       // pause. The next line prevents the magic
+                                       // fast-forward effect.
+                                       next1 = now;
+                               }
+                       }
+               }
+
+               // If we're now ahead of time, sleep a while
+               if (next1 > now)
+               {
+                       SDL_Delay(next1 - now);
+                       // SDL will take care if a signal arrives, restarting sleep.
+               }
+
+               // Calculate the timestamp of the next frame.
+               next1 += Settings.FrameTime;
        }
-       
-       /* Normal mode */
-       
-       while (gettimeofday(&now, 0) < 0);
-       
-       /* If there is no known "next" frame, initialize it now */
-       if (next1.tv_sec == 0) { next1 = now; ++next1.tv_usec; }
-       
-    /* If we're on AUTO_FRAMERATE, we'll display frames always
-     * only if there's excess time.
-     * Otherwise we'll display the defined amount of frames.
-     */
-    unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE
-                     ? (timercmp(&next1, &now, <) ? 10 : 1)
-                     : Settings.SkipFrames;
-                     
-    IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit;
-    if(IPPU.RenderThisFrame)
-    {
-        IPPU.SkippedFrames = 0;
-    }
-    else
-    {
-        /* If we were behind the schedule, check how much it is */
-        if(timercmp(&next1, &now, <))
-        {
-            unsigned lag =
-                (now.tv_sec - next1.tv_sec) * 1000000
-               + now.tv_usec - next1.tv_usec;
-            if(lag >= 500000)
-            {
-                /* More than a half-second behind means probably
-                 * pause. The next line prevents the magic
-                 * fast-forward effect.
-                 */
-                next1 = now;
-            }
-        }
-    }
-    
-    /* Delay until we're completed this frame */
-
-    /* Can't use setitimer because the sound code already could
-     * be using it. We don't actually need it either.
-     */
-
-    while(timercmp(&next1, &now, >))
-    {
-        /* If we're ahead of time, sleep a while */
-        unsigned timeleft =
-            (next1.tv_sec - now.tv_sec) * 1000000
-           + next1.tv_usec - now.tv_usec;
-
-        usleep(timeleft);
-
-        // XXX : CHECK_SOUND(); S9xProcessEvents(FALSE);
-
-        while (gettimeofday(&now, 0) < 0);
-        /* Continue with a while-loop because usleep()
-         * could be interrupted by a signal
-         */
-    }
-
-    /* Calculate the timestamp of the next frame. */
-    next1.tv_usec += Settings.FrameTime;
-    if (next1.tv_usec >= 1000000)
-    {
-        next1.tv_sec += next1.tv_usec / 1000000;
-        next1.tv_usec %= 1000000;
-    }
 }
 
 /** Wraps s9xProcessEvents, taking care of kPollEveryNFrames */