# HG changeset patch
# User Jordon Moss <mossj32@gmail.com>
# Date 1527979593 10800
#      Sat Jun 02 19:46:33 2018 -0300
# Node ID cb9a3974f2eea27206df920736b7e6d960da5a3e
# Parent  74fbeac6dbf639cab55754fe651f601a3466d0cd
Backport dpJudas' fix for the horribly broken model interpolation, with some tweaks for compatibility with Zandronum's older code.
Had to pull in the conversion of I_GetTimeFrac from fixed_t to double for this to work.

GZDoom Commits:
4a7960232594fef677f4053df2b07d6b128e9b2b - floatification of g_shared. (r_utility.cpp/h)
09d8b4af80713c4a176c4d4be0ab31deed724371 - changed I_GetTimeFrac to return a double instead of a fixed_t.
cc4a09a3d2977685753c51b6df039d2c3883cb34 - fix model interpolation bug
359b13b783c036d1b6dd944ca8370d4ebcf51649 - fix rotationSpeed being ignored after the model interpolation fix
0dbcdc8a9ce428e42a1394fdb730ea444930b764 - fix negative rotation speed not working

diff -r 74fbeac6dbf6 -r cb9a3974f2ee src/gl/models/gl_models.cpp
--- a/src/gl/models/gl_models.cpp	Sun May 20 22:34:05 2018 +0300
+++ b/src/gl/models/gl_models.cpp	Sat Jun 02 19:46:33 2018 -0300
@@ -699,14 +699,13 @@
 			// [BB] In case the tic counter is frozen we have to leave ticFraction at zero.
 			if ( ConsoleState == c_up && menuactive != MENU_On && !(level.flags2 & LEVEL2_FROZEN) )
 			{
-				float time = GetTimeFloat();
-				ticFraction = (time - static_cast<int>(time));
+				ticFraction = I_GetTimeFrac(NULL);
 			}
-			inter = static_cast<double>(curState->Tics - curTics - ticFraction)/static_cast<double>(curState->Tics);
+			inter = static_cast<double>(curState->Tics - curTics + ticFraction) / static_cast<double>(curState->Tics);
 
 			// [BB] For some actors (e.g. ZPoisonShroom) spr->actor->tics can be bigger than curState->Tics.
 			// In this case inter is negative and we need to set it to zero.
-			if ( inter < 0. )
+			if (curState->Tics < curTics)
 				inter = 0.;
 			else
 			{
@@ -815,8 +814,16 @@
 
 	if( smf->flags & MDL_ROTATING )
 	{
-		const float time = smf->rotationSpeed*GetTimeFloat()/200.f;
-		rotateOffset = float((time - xs_FloorToInt(time)) *360.f );
+		if (smf->rotationSpeed > 0.0000000001 || smf->rotationSpeed < -0.0000000001)
+		{
+			double turns = (I_GetTime(false) + I_GetTimeFrac(NULL)) / (200.0 / smf->rotationSpeed);
+			turns -= std::floor(turns);
+			rotateOffset = turns * 360.0;
+		}
+		else
+		{
+			rotateOffset = 0.0;
+		}
 	}
 
 	// Added MDL_INHERITACTORPITCH and MDL_INHERITACTORROLL flags processing.
diff -r 74fbeac6dbf6 -r cb9a3974f2ee src/gl/scene/gl_scene.cpp
--- a/src/gl/scene/gl_scene.cpp	Sun May 20 22:34:05 2018 +0300
+++ b/src/gl/scene/gl_scene.cpp	Sat Jun 02 19:46:33 2018 -0300
@@ -1025,8 +1025,8 @@
 	ResetProfilingData();
 
 	// Get this before everything else
-	if (cl_capfps || r_NoInterpolate) r_TicFrac = FRACUNIT;
-	else r_TicFrac = I_GetTimeFrac (&r_FrameTime);
+	if (cl_capfps || r_NoInterpolate) r_TicFracF = 1.;
+	else r_TicFracF = I_GetTimeFrac(&r_FrameTime);
 	gl_frameMS = I_MSTime();
 
 	P_FindParticleSubsectors ();
diff -r 74fbeac6dbf6 -r cb9a3974f2ee src/r_utility.cpp
--- a/src/r_utility.cpp	Sun May 20 22:34:05 2018 +0300
+++ b/src/r_utility.cpp	Sat Jun 02 19:46:33 2018 -0300
@@ -130,6 +130,7 @@
 AActor			*camera;	// [RH] camera to draw from. doesn't have to be a player
 
 fixed_t			r_TicFrac;			// [RH] Fractional tic to render
+double			r_TicFracF;			// same as floating point
 DWORD			r_FrameTime;		// [RH] Time this frame started drawing (in ms)
 bool			r_NoInterpolate;
 bool			r_showviewer;
@@ -818,11 +819,12 @@
 		iview->otic = nowtic;
 	}
 
-	r_TicFrac = I_GetTimeFrac (&r_FrameTime);
-	if (cl_capfps || r_NoInterpolate)
-	{
-		r_TicFrac = FRACUNIT;
-	}
+	r_TicFracF = I_GetTimeFrac(&r_FrameTime);
+	if (cl_capfps || r_NoInterpolate)
+	{
+		r_TicFracF = 1.;
+	}
+	r_TicFrac = FLOAT2FIXED(r_TicFracF);
 
 	R_InterpolateView (player, r_TicFrac, iview);
 
diff -r 74fbeac6dbf6 -r cb9a3974f2ee src/r_utility.h
--- a/src/r_utility.h	Sun May 20 22:34:05 2018 +0300
+++ b/src/r_utility.h	Sat Jun 02 19:46:33 2018 -0300
@@ -34,6 +34,7 @@
 extern int				WidescreenRatio;
 
 extern fixed_t			r_TicFrac;
+extern double			r_TicFracF;
 extern DWORD			r_FrameTime;
 extern int				extralight;
 extern unsigned int		R_OldBlend;
diff -r 74fbeac6dbf6 -r cb9a3974f2ee src/sdl/i_system.cpp
--- a/src/sdl/i_system.cpp	Sun May 20 22:34:05 2018 +0300
+++ b/src/sdl/i_system.cpp	Sat Jun 02 19:46:33 2018 -0300
@@ -310,20 +310,18 @@
 }
 
 // Returns the fractional amount of a tic passed since the most recent tic
-fixed_t I_GetTimeFrac (uint32 *ms)
-{
-	DWORD now = SDL_GetTicks ();
-	if (ms) *ms = TicNext;
-	DWORD step = TicNext - TicStart;
-	if (step == 0)
-	{
-		return FRACUNIT;
-	}
-	else
-	{
-		fixed_t frac = clamp<fixed_t> ((now - TicStart)*FRACUNIT/step, 0, FRACUNIT);
-		return frac;
-	}
+double I_GetTimeFrac (uint32 *ms)
+{
+	DWORD now = SDL_GetTicks ();
+	if (ms) *ms = TicStart + (1000 / TICRATE);
+	if (TicStart == 0)
+	{
+		return FRACUNIT;
+	}
+	else
+	{
+		return clamp<double>((now - TicStart) * TICRATE / 1000., 0, 1);
+	}
 }
 
 void I_WaitVBL (int count)
diff -r 74fbeac6dbf6 -r cb9a3974f2ee src/sdl/i_system.h
--- a/src/sdl/i_system.h	Sun May 20 22:34:05 2018 +0300
+++ b/src/sdl/i_system.h	Sat Jun 02 19:46:33 2018 -0300
@@ -62,7 +62,7 @@
 // tic will never arrive (unless it's the current one).
 extern void (*I_FreezeTime) (bool frozen);
 
-fixed_t I_GetTimeFrac (uint32 *ms);
+double I_GetTimeFrac (uint32 *ms);
 
 // Return a seed value for the RNG.
 unsigned int I_MakeRNGSeed();
diff -r 74fbeac6dbf6 -r cb9a3974f2ee src/win32/i_system.cpp
--- a/src/win32/i_system.cpp	Sun May 20 22:34:05 2018 +0300
+++ b/src/win32/i_system.cpp	Sat Jun 02 19:46:33 2018 -0300
@@ -530,23 +530,22 @@
 //
 //==========================================================================
 
-fixed_t I_GetTimeFrac(uint32 *ms)
-{
-	DWORD now = timeGetTime();
-	if (ms != NULL)
-	{
-		*ms = TicNext;
-	}
-	DWORD step = TicNext - TicStart;
-	if (step == 0)
-	{
-		return FRACUNIT;
-	}
-	else
-	{
-		fixed_t frac = clamp<fixed_t> ((now - TicStart)*FRACUNIT/step, 0, FRACUNIT);
-		return frac;
-	}
+double I_GetTimeFrac(uint32 *ms)
+{
+	DWORD now = timeGetTime();
+	if (ms != NULL)
+	{
+		*ms = TicNext;
+	}
+	DWORD step = TicNext - TicStart;
+	if (step == 0)
+	{
+		return 1.;
+	}
+	else
+	{
+		return clamp<double>(double(now - TicStart) / step, 0, 1);
+	}
 }
 
 //==========================================================================
diff -r 74fbeac6dbf6 -r cb9a3974f2ee src/win32/i_system.h
--- a/src/win32/i_system.h	Sun May 20 22:34:05 2018 +0300
+++ b/src/win32/i_system.h	Sat Jun 02 19:46:33 2018 -0300
@@ -67,7 +67,7 @@
 // tic will never arrive (unless it's the current one).
 extern void (*I_FreezeTime) (bool frozen);
 
-fixed_t I_GetTimeFrac (uint32 *ms);
+double I_GetTimeFrac (uint32 *ms);
 
 // Return a seed value for the RNG.
 unsigned int I_MakeRNGSeed();
