diff --git a/src/d_main.c b/src/d_main.c
index 244d960bc02c51033247914ce6aabc22e719c17a..5195c243b1ddd46afaa374e5088ba9fa63b5a000 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -721,7 +721,7 @@ void D_SRB2Loop(void)
 #define caninterpolate (cv_frameinterpolation.value && !(gamestate == GS_CUTSCENE || gamestate == GS_INTRO || gamestate == GS_CREDITS || gamestate == GS_INTERMISSION))
 		if (!d_realtics && !singletics)
 		{
-			if (caninterpolate)
+			if (caninterpolate && firsttics == 0)
 			{
 				fixed_t oldrendertimefrac = 0;
 
@@ -774,13 +774,17 @@ void D_SRB2Loop(void)
 		if (d_realtics || singletics)
 			TryRunTics(d_realtics);
 
+		if (d_realtics)
+			if (firsttics)
+				firsttics--;
+
 		if (lastdraw || singletics || gametic > rendergametic)
 		{
 			rendergametic = gametic;
 			rendertimeout = entertic+TICRATE/17;
 
 			// Update display, next frame, with current state.
-			if (caninterpolate)
+			if (caninterpolate && firsttics == 0)
 			{
 				rendertimefrac = I_GetTimeFrac();
 				R_DoThinkerLerp(rendertimefrac);
diff --git a/src/doomdef.h b/src/doomdef.h
index 9dc44d3bb92ad9cc7344344f7db26d47b8b79115..e16da218c56f72ff1e6aa5bcdf2c22a760a2221a 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -124,6 +124,9 @@ extern char logfilename[1024];
 /* A mod name to further distinguish versions. */
 #define SRB2APPLICATION "SRB2"
 
+// uncapped ver
+#define UNCAPPEDVERSION "2.0"
+
 //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3
 #ifdef DEVELOP
 #define VERSIONSTRING "Development EXE"
@@ -134,8 +137,11 @@ extern char logfilename[1024];
 #ifdef BETAVERSION
 #define VERSIONSTRING "v"SRB2VERSION" "BETAVERSION
 #define VERSIONSTRING_RC SRB2VERSION " " BETAVERSION "\0"
+#elif defined (UNCAPPEDVERSION)
+#define VERSIONSTRING "v"SRB2VERSION" (Uncapped v"UNCAPPEDVERSION")"
+#define VERSIONSTRING_RC SRB2VERSION " (Uncapped v" UNCAPPEDVERSION ")\0"
 #else
-#define VERSIONSTRING "v"SRB2VERSION
+#define VERSIONSTRING "v"SRB2VERSION" "
 #define VERSIONSTRING_RC SRB2VERSION "\0"
 #endif
 // Hey! If you change this, add 1 to the MODVERSION below!
diff --git a/src/p_setup.c b/src/p_setup.c
index 5a8248a288fe80a4b97774a99bc47da953729ede..df997589dadcb08d0fe76ae6a86687db22bad219 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -4174,6 +4174,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
 
 	P_ResetWaypoints();
 
+	R_ResetFirstLerp();
+
 	P_MapStart();
 
 	if (!P_LoadMapFromFile())
diff --git a/src/r_fps.c b/src/r_fps.c
index 5fa2a91c6740e82d02580151a7e4a4c593e27c1a..b46c9ee46c1eba84efe4f0531ebdc53c78cb0031 100644
--- a/src/r_fps.c
+++ b/src/r_fps.c
@@ -366,7 +366,7 @@ void R_SetThinkerOldStates(void)
 					mo->old_z = mo->new_z;
 				}
 			}
-			else if (i == THINK_POLYOBJ)
+			/*else if (i == THINK_POLYOBJ)
 			{
 				if (ISA(T_PolyObjRotate))
 				{
@@ -383,14 +383,13 @@ void R_SetThinkerOldStates(void)
 					if (pobj == NULL) continue;
 					SetPolyobjOldState(pobj);
 				}
-				// FIXME: waypoints are too buggy on DSZ2
-				/*else if (ISA(T_PolyObjWaypoint))
+				else if (ISA(T_PolyObjWaypoint))
 				{
 					CAST(p, polywaypoint_t);
 					polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 					if (pobj == NULL) continue;
 					SetPolyobjOldState(pobj);
-				}*/
+				}
 				else if (ISA(T_PolyDoorSlide))
 				{
 					CAST(p, polyslidedoor_t);
@@ -414,15 +413,16 @@ void R_SetThinkerOldStates(void)
 					if (pobj == NULL) continue;
 					SetPolyobjOldState(pobj);
 				}
-				/*else if (ISA(T_PolyObjRotDisplace))
+				else if (ISA(T_PolyObjRotDisplace))
 				{
 					CAST(p, polyrotdisplace_t);
 					polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 					if (pobj == NULL) continue;
 					SetPolyobjOldState(pobj);
-				}*/
-			}
-			else // Other thinkers
+				}
+			}*/
+			// Other thinkers
+			//else
 			{
 				if (ISA(T_MoveCeiling) || ISA(T_CrushCeiling))
 				{
@@ -558,6 +558,8 @@ void R_ResetFirstLerp(void)
 	thinker_t *th;
 	thinklistnum_t i;
 
+	firsttics = 2;
+
 	for (i = 0; i <= NUM_THINKERLISTS-1; i++)
 	{
 		for (th = thlist[i].next; th != &thlist[i]; th = th->next)
@@ -575,7 +577,7 @@ void R_ResetFirstLerp(void)
 				CAST(mo, precipmobj_t);
 				mo->firstlerp = 0;
 			}
-			else if (i == THINK_POLYOBJ)
+			/*else if (i == THINK_POLYOBJ)
 			{
 				if (ISA(T_PolyObjRotate))
 				{
@@ -592,14 +594,13 @@ void R_ResetFirstLerp(void)
 					if (pobj == NULL) continue;
 					pobj->firstlerp = 0;
 				}
-				// FIXME: waypoints are too buggy on DSZ2
-				/*else if (ISA(T_PolyObjWaypoint))
+				else if (ISA(T_PolyObjWaypoint))
 				{
 					CAST(p, polywaypoint_t);
 					polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 					if (pobj == NULL) continue;
 					pobj->firstlerp = 0;
-				}*/
+				}
 				else if (ISA(T_PolyDoorSlide))
 				{
 					CAST(p, polyslidedoor_t);
@@ -622,16 +623,16 @@ void R_ResetFirstLerp(void)
 					if (pobj == NULL) continue;
 					pobj->firstlerp = 0;
 				}
-				/*else if (ISA(T_PolyObjRotDisplace))
+				else if (ISA(T_PolyObjRotDisplace))
 				{
 					CAST(p, polyrotdisplace_t);
 					polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 					if (pobj == NULL) continue;
 					pobj->firstlerp = 0;
-				}*/
-			}
+				}
+			}*/
 			// Other thinkers
-			else
+			//else
 			{
 				if (ISA(T_MoveCeiling) || ISA(T_CrushCeiling))
 				{
@@ -782,7 +783,7 @@ void R_SetThinkerNewStates(void)
 					mo->new_z = mo->z;
 				}
 			}
-			else if (i == THINK_POLYOBJ)
+			/*else if (i == THINK_POLYOBJ)
 			{
 				if (ISA(T_PolyObjRotate))
 				{
@@ -799,14 +800,13 @@ void R_SetThinkerNewStates(void)
 					if (pobj == NULL) continue;
 					SetPolyobjNewState(pobj);
 				}
-				// FIXME: waypoints are too buggy on DSZ2
-				/*else if (ISA(T_PolyObjWaypoint))
+				else if (ISA(T_PolyObjWaypoint))
 				{
 					CAST(p, polywaypoint_t);
 					polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 					if (pobj == NULL) continue;
 					SetPolyobjNewState(pobj);
-				}*/
+				}
 				else if (ISA(T_PolyDoorSlide))
 				{
 					CAST(p, polyslidedoor_t);
@@ -837,16 +837,16 @@ void R_SetThinkerNewStates(void)
 					pobj->firstlerp = p->firstlerp;
 					SetPolyobjNewState(pobj);
 				}
-				/*else if (ISA(T_PolyObjRotDisplace))
+				else if (ISA(T_PolyObjRotDisplace))
 				{
 					CAST(p, polyrotdisplace_t);
 					polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 					if (pobj == NULL) continue;
 					SetPolyobjNewState(pobj);
-				}*/
-			}
+				}
+			}*/
 			// Other thinkers
-			else
+			//else
 			{
 				if (ISA(T_MoveCeiling) || ISA(T_CrushCeiling))
 				{
@@ -1125,7 +1125,7 @@ void R_DoThinkerLerp(fixed_t frac)
 			}
 			if (cv_interpmovingplatforms.value)
 			{
-				if (i == THINK_POLYOBJ)
+				/*if (i == THINK_POLYOBJ)
 				{
 					if (ISA(T_PolyObjRotate))
 					{
@@ -1142,14 +1142,13 @@ void R_DoThinkerLerp(fixed_t frac)
 						if (pobj == NULL) continue;
 						LerpPolyobjState(pobj, frac);
 					}
-					// FIXME: waypoints are too buggy on DSZ2
-					/*else if (ISA(T_PolyObjWaypoint))
+					else if (ISA(T_PolyObjWaypoint))
 					{
 						CAST(p, polywaypoint_t);
 						polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 						if (pobj == NULL) continue;
 						LerpPolyobjState(pobj, frac);
-					}*/
+					}
 					else if (ISA(T_PolyDoorSlide))
 					{
 						CAST(p, polyslidedoor_t);
@@ -1174,16 +1173,16 @@ void R_DoThinkerLerp(fixed_t frac)
 						if (pobj == NULL) continue;
 						LerpPolyobjState(pobj, frac);
 					}
-					/*else if (ISA(T_PolyObjRotDisplace))
+					else if (ISA(T_PolyObjRotDisplace))
 					{
 						CAST(p, polyrotdisplace_t);
 						polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 						if (pobj == NULL) continue;
 						LerpPolyobjState(pobj, frac);
-					}*/
-				}
+					}
+				}*/
 				// Other thinkers
-				else
+				//else
 				{
 					if (ISA(T_MoveCeiling) || ISA(T_CrushCeiling))
 					{
@@ -1379,7 +1378,7 @@ void R_ResetThinkerLerp(void)
 					mo->z = mo->new_z;
 				}
 			}
-			else if (i == THINK_POLYOBJ)
+			/*else if (i == THINK_POLYOBJ)
 			{
 				if (ISA(T_PolyObjRotate))
 				{
@@ -1396,14 +1395,13 @@ void R_ResetThinkerLerp(void)
 					if (pobj == NULL) continue;
 					ResetPolyobjState(pobj);
 				}
-				// FIXME: waypoints are too buggy on DSZ2
-				/*else if (ISA(T_PolyObjWaypoint))
+				else if (ISA(T_PolyObjWaypoint))
 				{
 					CAST(p, polywaypoint_t);
 					polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 					if (pobj == NULL) continue;
 					ResetPolyobjState(pobj);
-				}*/
+				}
 				else if (ISA(T_PolyDoorSlide))
 				{
 					CAST(p, polyslidedoor_t);
@@ -1428,16 +1426,16 @@ void R_ResetThinkerLerp(void)
 					if (pobj == NULL) continue;
 					ResetPolyobjState(pobj);
 				}
-				/*else if (ISA(T_PolyObjRotDisplace))
+				else if (ISA(T_PolyObjRotDisplace))
 				{
 					CAST(p, polyrotdisplace_t);
 					polyobj_t *pobj = Polyobj_GetForNum(p->polyObjNum);
 					if (pobj == NULL) continue;
 					ResetPolyobjState(pobj);
-				}*/
-			}
+				}
+			}*/
 			// Other thinkers
-			else
+			//else
 			{
 				if (ISA(T_MoveCeiling) || ISA(T_CrushCeiling))
 				{
diff --git a/src/r_main.c b/src/r_main.c
index b058f623fb3145c47303977d94c13810203b22bd..659ff299feab8e7bbce96d49d6600bf1b24a145c 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -79,6 +79,7 @@ mobj_t *r_viewmobj;
 fixed_t rendertimefrac;
 fixed_t renderdeltatics;
 boolean tic_happened = false;
+UINT8 firsttics = 2;
 
 //
 // precalculated math tables
diff --git a/src/r_main.h b/src/r_main.h
index ccbc61d84d08befd908522102c7b83d72df85da9..9f1e6080796b13e195e60c3dc97763f4a0ae0f5e 100644
--- a/src/r_main.h
+++ b/src/r_main.h
@@ -39,6 +39,7 @@ extern fixed_t rendertimefrac;
 // Evaluated delta tics for this frame (how many tics since the last frame)
 extern fixed_t renderdeltatics;
 extern boolean tic_happened;
+extern UINT8 firsttics;
 
 //
 // Lighting LUT.