From 1882e13c5ff05fb5ba7635ae742447173a2e0908 Mon Sep 17 00:00:00 2001
From: johns <>
Date: Sun, 31 Mar 2002 02:38:02 +0000
Subject: [PATCH] Better handling with slow game speeds.

---
 src/include/video.h        |  3 ++
 src/stratagus/mainloop.cpp |  8 +++--
 src/ui/interface.cpp       | 21 +++++--------
 src/ui/mainscr.cpp         |  3 +-
 src/video/sdl.cpp          | 62 ++++++++++++++++++++++++++++++--------
 5 files changed, 68 insertions(+), 29 deletions(-)

diff --git a/src/include/video.h b/src/include/video.h
index 37e9d29b5..62feba5d9 100644
--- a/src/include/video.h
+++ b/src/include/video.h
@@ -1359,6 +1359,9 @@ extern void CheckVideoInterrupts(void);
     /// Toggle mouse grab mode
 extern void ToggleGrabMouse(void);
 
+    /// Toggle full screen mode
+extern void ToggleFullScreen(void);
+
     ///	Lock the screen for display
 extern void VideoLockScreen(void);
 
diff --git a/src/stratagus/mainloop.cpp b/src/stratagus/mainloop.cpp
index e82b1b0b4..fcce313f6 100644
--- a/src/stratagus/mainloop.cpp
+++ b/src/stratagus/mainloop.cpp
@@ -308,8 +308,10 @@ global void UpdateDisplay(void)
 	//
 	{ int f;
 
-	f=(168*(NextFrameTicks-GetTicks()))
-	    /((100*1000/CYCLES_PER_SECOND)/VideoSyncSpeed);
+	f=168*(NextFrameTicks-GetTicks());
+	if( VideoSyncSpeed ) {
+	    f/=(100*1000/CYCLES_PER_SECOND)/VideoSyncSpeed;
+	}
 	if( f<0 || f>168 ) {
 	    f=168;
 	}
@@ -503,7 +505,7 @@ global void GameMainLoop(void)
 	//
 	//	Game logic part
 	//
-	if (!GamePaused && NetworkInSync) {
+	if (!GamePaused && NetworkInSync && !SkipGameCycle) {
 	    if( !++GameCycle ) {
 		// FIXME: tests with game cycle counter now fails :(
 		// FIXME: Should happen in 68 years :)
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 871933432..e290efd15 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -50,6 +50,7 @@
 #include "network.h"
 #include "font.h"
 #include "campaign.h"
+#include "video.h"
 
 /*----------------------------------------------------------------------------
 --	Declaration
@@ -315,9 +316,12 @@ local void UiIncrementGameSpeed(void)
 */
 local void UiDecrementGameSpeed(void)
 {
-    VideoSyncSpeed-=10;
-    if( VideoSyncSpeed<=10 ) {
-	VideoSyncSpeed=10;
+    if( VideoSyncSpeed<=0 ) {
+	VideoSyncSpeed=0;
+    } else if( VideoSyncSpeed<11 ) {
+	VideoSyncSpeed-=1;
+    } else {
+	VideoSyncSpeed-=10;
     }
     SetVideoSync();
     SetStatusLine("Slower");
@@ -540,16 +544,7 @@ local int CommandKey(int key)
 	    if( !(KeyModifiers&(ModifierAlt|ModifierControl)) ) {
 		break;
 	    }
-#ifdef USE_SDL
-	    {
-	    #include <SDL.h>
-	    // FIXME: move to system api part!
-	    extern SDL_Surface *Screen;	// internal screen
-
-	    DebugLevel0Fn("%x\n",KeyModifiers);
-	    SDL_WM_ToggleFullScreen(Screen);
-	    }
-#endif
+	    ToggleFullScreen();
 	    break;
 
         case ' ':			// center on last action
diff --git a/src/ui/mainscr.cpp b/src/ui/mainscr.cpp
index c11b551c4..1d808f56a 100644
--- a/src/ui/mainscr.cpp
+++ b/src/ui/mainscr.cpp
@@ -1045,7 +1045,8 @@ global void DrawInfoPanel(void)
 	y+=16;
 	VideoDrawText(x,y,GameFont,"Cycle:");
 	VideoDrawNumber(x+48,y,GameFont,GameCycle);
-	VideoDrawNumber(x+110,y,GameFont,CYCLES_PER_SECOND*VideoSyncSpeed/100);
+	VideoDrawNumber(x+110,y,GameFont,
+	    CYCLES_PER_SECOND*VideoSyncSpeed/100);
 	y+=20;
 
 	for( i=0; i<PlayerMax; ++i ) {
diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp
index 5cdfa42ec..6b6d9d65f 100644
--- a/src/video/sdl.cpp
+++ b/src/video/sdl.cpp
@@ -34,8 +34,9 @@
 #ifdef USE_SDL	// {
 
 #include <stdlib.h>
+#include <limits.h>
 #ifndef _MSC_VER
-#include <sys/time.h>
+//#include <sys/time.h>
 #endif
 #include <SDL.h>
 
@@ -66,6 +67,10 @@
 ----------------------------------------------------------------------------*/
 
 global SDL_Surface *Screen;		/// internal screen
+local int FrameTicks;			/// Frame length in ms
+local int FrameRemainder;		/// Frame remainder 0.1 ms
+local int FrameFraction;		/// Frame fractional term
+local int SkipFrames;			/// Skip this frames
 
 /*----------------------------------------------------------------------------
 --	Functions
@@ -77,12 +82,28 @@ global SDL_Surface *Screen;		/// internal screen
 
 /**
 **	Initialise video sync.
+**	Calculate the length of video frame and any simulation skips.
 **
-**	@see VideoSyncSpeed
+**	@see VideoSyncSpeed @see SkipFrames @see FrameTicks @see FrameRemainder
 */
 global void SetVideoSync(void)
 {
-    DebugLevel0Fn("%d\n",(100*1000/CYCLES_PER_SECOND)/VideoSyncSpeed);
+    int ms;
+
+    if( VideoSyncSpeed ) {
+	ms = (1000 * 1000 / CYCLES_PER_SECOND) / VideoSyncSpeed;
+    } else {
+	ms = INT_MAX;
+    }
+    SkipFrames = ms / 400;
+    while (SkipFrames && ms / SkipFrames < 200) {
+	--SkipFrames;
+    }
+    ms /= SkipFrames + 1;
+
+    FrameTicks = ms / 10;
+    FrameRemainder = ms % 10;
+    DebugLevel0Fn("frames %d - %d.%dms\n", SkipFrames, ms / 10, ms % 10);
 }
 
 /*----------------------------------------------------------------------------
@@ -531,6 +552,10 @@ global void WaitEventsOneFrame(const EventCallback* callbacks)
 
     ticks=SDL_GetTicks();
     if( ticks>NextFrameTicks ) {	// We are too slow :(
+	IfDebug(
+	    // FIXME: need locking!
+	    //VideoDrawText(TheUI.MapX+10,TheUI.MapY+10,GameFont,"SLOW FRAME!!");
+	);
 	++SlowFrameCounter;
     }
 
@@ -545,7 +570,12 @@ global void WaitEventsOneFrame(const EventCallback* callbacks)
 	}
 	while( ticks>=NextFrameTicks ) {
 	    ++VideoInterrupts;
-	    NextFrameTicks+=(100*1000/CYCLES_PER_SECOND)/VideoSyncSpeed;
+	    FrameFraction+=FrameRemainder;
+	    if( FrameFraction>10 ) {
+		FrameFraction-=10;
+		++NextFrameTicks;
+	    }
+	    NextFrameTicks+=FrameTicks;
 	}
 
 	//
@@ -635,6 +665,11 @@ global void WaitEventsOneFrame(const EventCallback* callbacks)
     //	Prepare return, time for one frame is over.
     //
     VideoInterrupts=0;
+
+    
+    if( !SkipGameCycle-- ) {
+	SkipGameCycle=SkipFrames;
+    }
 }
 
 /**
@@ -767,14 +802,6 @@ global VMemType *VideoCreateNewPalette(const Palette * palette)
 */
 global void CheckVideoInterrupts(void)
 {
-    if( VideoInterrupts ) {
-        //DebugLevel1("Slow frame\n");
-	// FIXME: need locking!
-	IfDebug(
-	    //VideoDrawText(TheUI.MapX+10,TheUI.MapY+10,GameFont,"SLOW FRAME!!");
-	);
-        ++SlowFrameCounter;
-    }
 }
 
 /**
@@ -801,6 +828,17 @@ global void ToggleGrabMouse(void)
     }
 }
 
+/**
+**	Toggle full screen mode.
+**
+**	@todo FIXME: didn't work with windows,
+**		must quit video system and restart it.
+*/
+global void ToggleFullScreen(void)
+{
+    SDL_WM_ToggleFullScreen(Screen);
+}
+
 #endif // } USE_SDL
 
 //@}