diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 70e283bba8428ce42fd0938943a0d6d4fa824443..ac8bba608288063b7b34dff533f9d2ef0e9c84e2 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -5270,7 +5270,6 @@ void TryRunTics(tic_t realtics)
 				boolean update_stats = !(paused || P_AutoPause());
 
 				DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic));
-				prev_tics = I_GetTime();
 
 				if (update_stats)
 					PS_START_TIMING(ps_tictime);
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index d9c32d46b3c6cf31f751115a9b062856788c1eed..5402b4a8dab00485c99ab152f53286e85561f07a 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -3644,6 +3644,19 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
 	fixed_t slopez;
 	pslope_t *groundslope;
 
+	// uncapped/interpolation
+	fixed_t interpx;
+	fixed_t interpy;
+
+	interpx = thing->x;
+	interpy = thing->y;
+
+	if (cv_frameinterpolation.value == 1 && !paused)
+	{
+		interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
+		interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
+	}
+
 	groundz = R_GetShadowZ(thing, &groundslope);
 
 	heightsec = thing->subsector->sector->heightsec;
@@ -3678,8 +3691,8 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
 	scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height);
 
 	fscale = FIXED_TO_FLOAT(scalemul);
-	fx = FIXED_TO_FLOAT(thing->x);
-	fy = FIXED_TO_FLOAT(thing->y);
+	fx = FIXED_TO_FLOAT(interpx);
+	fy = FIXED_TO_FLOAT(interpy);
 
 	//  3--2
 	//  | /|
diff --git a/src/r_main.c b/src/r_main.c
index 2496074807611d48187977bf9a6a17df3f32f71c..e7f567b583f596245387e5a6d463be51776290db 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -100,9 +100,6 @@ lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
 lighttable_t *scalelightfixed[MAXLIGHTSCALE];
 lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
 
-// Frame interpolation/uncapped
-tic_t prev_tics;
-
 // Hack to support extra boom colormaps.
 extracolormap_t *extra_colormaps = NULL;
 
diff --git a/src/r_main.h b/src/r_main.h
index 45254f6c431775e03f4f49f1e463d44d0bd16072..08654a6949624e5e1ff1aca47a6b6fd382a20aa8 100644
--- a/src/r_main.h
+++ b/src/r_main.h
@@ -120,7 +120,6 @@ extern consvar_t cv_skybox;
 extern consvar_t cv_tailspickup;
 
 // Frame interpolation (uncapped framerate)
-extern tic_t prev_tics;
 extern consvar_t cv_frameinterpolation;
 
 // Called by startup code.
diff --git a/src/r_things.c b/src/r_things.c
index 55e84d6b79868eb2ec61831877b3bad25ddd8678..553e1607fa2db8530c16fd2647b9e14a3499d273 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1140,7 +1140,24 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
 	msecnode_t *node;
 	sector_t *sector;
 	ffloor_t *rover;
-#define CHECKZ (isflipped ? z > thing->z+thing->height/2 && z < groundz : z < thing->z+thing->height/2 && z > groundz)
+
+	// for frame interpolation
+	fixed_t interpx;
+	fixed_t interpy;
+	fixed_t interpz;
+	
+	interpx = thing->x;
+	interpy = thing->y;
+	interpz = thing->z;
+
+	if (cv_frameinterpolation.value == 1 && !paused)
+	{
+		interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
+		interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
+		interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z);
+	}
+
+#define CHECKZ (isflipped ? z > interpz+thing->height/2 && z < groundz : z < interpz+thing->height/2 && z > groundz)
 
 	for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next)
 	{
@@ -1151,7 +1168,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
 		if (sector->heightsec != -1)
 			z = isflipped ? sectors[sector->heightsec].ceilingheight : sectors[sector->heightsec].floorheight;
 		else
-			z = isflipped ? P_GetSectorCeilingZAt(sector, thing->x, thing->y) : P_GetSectorFloorZAt(sector, thing->x, thing->y);
+			z = isflipped ? P_GetSectorCeilingZAt(sector, interpx, interpy) : P_GetSectorFloorZAt(sector, interpx, interpy);
 
 		if CHECKZ
 		{
@@ -1165,7 +1182,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
 				if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE)))
 					continue;
 
-				z = isflipped ? P_GetFFloorBottomZAt(rover, thing->x, thing->y) : P_GetFFloorTopZAt(rover, thing->x, thing->y);
+				z = isflipped ? P_GetFFloorBottomZAt(rover, interpx, interpy) : P_GetFFloorTopZAt(rover, interpx, interpy);
 				if CHECKZ
 				{
 					groundz = z;
@@ -1252,9 +1269,24 @@ static void R_SkewShadowSprite(
 			fixed_t groundz, INT32 spriteheight, fixed_t scalemul,
 			fixed_t *shadowyscale, fixed_t *shadowskew)
 {
+
 	// haha let's try some dumb stuff
 	fixed_t xslope, zslope;
-	angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - groundslope->xydirection) >> ANGLETOFINESHIFT;
+	angle_t sloperelang;
+
+	// for frame interpolation
+	fixed_t interpx;
+	fixed_t interpy;
+
+	interpx = thing->x;
+	interpy = thing->y;
+
+	if (cv_frameinterpolation.value == 1 && !paused)
+	{
+		interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x);
+		interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y);
+	}
+	sloperelang = (R_PointToAngle(interpx, interpy) - groundslope->xydirection) >> ANGLETOFINESHIFT;
 
 	xslope = FixedMul(FINESINE(sloperelang), groundslope->zdelta);
 	zslope = FixedMul(FINECOSINE(sloperelang), groundslope->zdelta);