diff --git a/src/r_plane.c b/src/r_plane.c
index 818770906..d844048ae 100644
--- a/src/r_plane.c
+++ b/src/r_plane.c
@@ -89,8 +89,6 @@ static fixed_t planeheight;
 fixed_t yslopetab[MAXVIDHEIGHT*16];
 fixed_t *yslope;
 
-fixed_t basexscale, baseyscale;
-
 fixed_t cachedheight[MAXVIDHEIGHT];
 fixed_t cacheddistance[MAXVIDHEIGHT];
 fixed_t cachedxstep[MAXVIDHEIGHT];
@@ -114,7 +112,7 @@ void R_InitPlanes(void)
 // Sets planeripple.xfrac and planeripple.yfrac, added to ds_xfrac and ds_yfrac, if the span is not tilted.
 //
 
-struct
+static struct
 {
 	INT32 offset;
 	fixed_t xfrac, yfrac;
@@ -143,15 +141,6 @@ static void R_UpdatePlaneRipple(void)
 	planeripple.offset = (leveltime * 140);
 }
 
-//
-// R_MapPlane
-//
-// Uses global vars:
-//  planeheight
-//  basexscale
-//  baseyscale
-//  centerx
-
 static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
 {
 	angle_t angle, planecos, planesin;
@@ -176,16 +165,13 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
 		cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]);
 		span = abs(centery - y);
 
-		if (span) // don't divide by zero
+		if (span) // Don't divide by zero
 		{
 			ds_xstep = FixedMul(planesin, planeheight) / span;
 			ds_ystep = FixedMul(planecos, planeheight) / span;
 		}
 		else
-		{
-			ds_xstep = FixedMul(distance, basexscale);
-			ds_ystep = FixedMul(distance, baseyscale);
-		}
+			ds_xstep = ds_ystep = FRACUNIT;
 
 		cachedxstep[y] = ds_xstep;
 		cachedystep[y] = ds_ystep;
@@ -197,6 +183,11 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
 		ds_ystep = cachedystep[y];
 	}
 
+	// [RH] Instead of using the xtoviewangle array, I calculated the fractional values
+	// at the middle of the screen, then used the calculated ds_xstep and ds_ystep
+	// to step from those to the proper texture coordinate to start drawing at.
+	// That way, the texture coordinate is always calculated by its position
+	// on the screen and not by its position relative to the edge of the visplane.
 	ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep;
 	ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep;
 
@@ -295,7 +286,6 @@ void R_ClearFFloorClips (void)
 void R_ClearPlanes(void)
 {
 	INT32 i, p;
-	angle_t angle;
 
 	// opening / clipping determination
 	for (i = 0; i < viewwidth; i++)
@@ -321,13 +311,6 @@ void R_ClearPlanes(void)
 
 	// texture calculation
 	memset(cachedheight, 0, sizeof (cachedheight));
-
-	// left to right mapping
-	angle = (viewangle-ANGLE_90)>>ANGLETOFINESHIFT;
-
-	// scale will be unit scale at SCREENWIDTH/2 distance
-	basexscale = FixedDiv (FINECOSINE(angle),centerxfrac);
-	baseyscale = -FixedDiv (FINESINE(angle),centerxfrac);
 }
 
 static visplane_t *new_visplane(unsigned hash)
@@ -532,53 +515,22 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
 //
 // R_ExpandPlane
 //
-// This function basically expands the visplane or I_Errors.
+// This function basically expands the visplane.
 // The reason for this is that when creating 3D floor planes, there is no
 // need to create new ones with R_CheckPlane, because 3D floor planes
 // are created by subsector and there is no way a subsector can graphically
 // overlap.
 void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop)
 {
-//	INT32 unionl, unionh;
-//	INT32 x;
-
 	// Don't expand polyobject planes here - we do that on our own.
 	if (pl->polyobj)
 		return;
 
 	if (pl->minx > start) pl->minx = start;
 	if (pl->maxx < stop)  pl->maxx = stop;
-/*
-	if (start < pl->minx)
-	{
-		unionl = start;
-	}
-	else
-	{
-		unionl = pl->minx;
-	}
-
-	if (stop > pl->maxx)
-	{
-		unionh = stop;
-	}
-	else
-	{
-		unionh = pl->maxx;
-	}
-	for (x = start; x <= stop; x++)
-		if (pl->top[x] != 0xffff || pl->bottom[x] != 0x0000)
-			break;
-
-	if (x <= stop)
-		I_Error("R_ExpandPlane: planes in same subsector overlap?!\nminx: %d, maxx: %d, start: %d, stop: %d\n", pl->minx, pl->maxx, start, stop);
-
-	pl->minx = unionl, pl->maxx = unionh;
-*/
-
 }
 
-static void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
+static void R_MakeSpans(void (*mapfunc)(INT32, INT32, INT32), INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
 {
 	//    Alam: from r_splats's R_RasterizeFloorSplat
 	if (t1 >= vid.height) t1 = vid.height-1;
@@ -589,38 +541,12 @@ static void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
 
 	while (t1 < t2 && t1 <= b1)
 	{
-		R_MapPlane(t1, spanstart[t1], x - 1);
+		mapfunc(t1, spanstart[t1], x - 1);
 		t1++;
 	}
 	while (b1 > b2 && b1 >= t1)
 	{
-		R_MapPlane(b1, spanstart[b1], x - 1);
-		b1--;
-	}
-
-	while (t2 < t1 && t2 <= b2)
-		spanstart[t2++] = x;
-	while (b2 > b1 && b2 >= t2)
-		spanstart[b2--] = x;
-}
-
-static void R_MakeTiltedSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
-{
-	//    Alam: from r_splats's R_RasterizeFloorSplat
-	if (t1 >= vid.height) t1 = vid.height-1;
-	if (b1 >= vid.height) b1 = vid.height-1;
-	if (t2 >= vid.height) t2 = vid.height-1;
-	if (b2 >= vid.height) b2 = vid.height-1;
-	if (x-1 >= vid.width) x = vid.width;
-
-	while (t1 < t2 && t1 <= b1)
-	{
-		R_MapTiltedPlane(t1, spanstart[t1], x - 1);
-		t1++;
-	}
-	while (b1 > b2 && b1 >= t1)
-	{
-		R_MapTiltedPlane(b1, spanstart[b1], x - 1);
+		mapfunc(b1, spanstart[b1], x - 1);
 		b1--;
 	}
 
@@ -867,11 +793,10 @@ void R_DrawSinglePlane(visplane_t *pl)
 {
 	levelflat_t *levelflat;
 	INT32 light = 0;
-	INT32 x;
-	INT32 stop, angle;
+	INT32 x, stop;
 	ffloor_t *rover;
-	INT32 type;
-	INT32 spanfunctype = BASEDRAWFUNC;
+	INT32 type, spanfunctype = BASEDRAWFUNC;
+	void (*mapfunc)(INT32, INT32, INT32) = R_MapPlane;
 
 	if (!(pl->minx <= pl->maxx))
 		return;
@@ -1023,9 +948,6 @@ void R_DrawSinglePlane(visplane_t *pl)
 		&& viewangle != pl->viewangle+pl->plangle)
 	{
 		memset(cachedheight, 0, sizeof (cachedheight));
-		angle = (pl->viewangle+pl->plangle-ANGLE_90)>>ANGLETOFINESHIFT;
-		basexscale = FixedDiv(FINECOSINE(angle),centerxfrac);
-		baseyscale = -FixedDiv(FINESINE(angle),centerxfrac);
 		viewangle = pl->viewangle+pl->plangle;
 	}
 
@@ -1040,6 +962,8 @@ void R_DrawSinglePlane(visplane_t *pl)
 
 	if (pl->slope)
 	{
+		mapfunc = R_MapTiltedPlane;
+
 		if (!pl->plangle)
 		{
 			if (ds_powersoftwo)
@@ -1107,16 +1031,8 @@ void R_DrawSinglePlane(visplane_t *pl)
 
 	stop = pl->maxx + 1;
 
-	if (pl->slope)
-	{
-		for (x = pl->minx; x <= stop; x++)
-			R_MakeTiltedSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
-	}
-	else
-	{
-		for (x = pl->minx; x <= stop; x++)
-			R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
-	}
+	for (x = pl->minx; x <= stop; x++)
+		R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
 
 /*
 QUINCUNX anti-aliasing technique (sort of)
@@ -1183,7 +1099,7 @@ using the palette colors.
 			stop = pl->maxx + 1;
 
 			for (x = pl->minx; x <= stop; x++)
-				R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1],
+				R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1],
 					pl->top[x], pl->bottom[x]);
 		}
 	}
diff --git a/src/r_plane.h b/src/r_plane.h
index bdad77930..862b95069 100644
--- a/src/r_plane.h
+++ b/src/r_plane.h
@@ -69,7 +69,6 @@ extern fixed_t cachedheight[MAXVIDHEIGHT];
 extern fixed_t cacheddistance[MAXVIDHEIGHT];
 extern fixed_t cachedxstep[MAXVIDHEIGHT];
 extern fixed_t cachedystep[MAXVIDHEIGHT];
-extern fixed_t basexscale, baseyscale;
 
 extern fixed_t *yslope;
 extern lighttable_t **planezlight;
diff --git a/src/r_splats.c b/src/r_splats.c
index 4783fb640..c554e9b1f 100644
--- a/src/r_splats.c
+++ b/src/r_splats.c
@@ -155,7 +155,6 @@ void R_DrawFloorSplat(vissprite_t *spr)
 	fixed_t xscale, yscale;
 	fixed_t xoffset, yoffset;
 	fixed_t leftoffset, topoffset;
-	pslope_t *slope = NULL;
 	INT32 i;
 
 	boolean hflip = (spr->xiscale < 0);
@@ -188,7 +187,7 @@ void R_DrawFloorSplat(vissprite_t *spr)
 	if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD)
 		splatangle = mobj->angle;
 	else
-		splatangle = spr->viewangle;
+		splatangle = spr->viewpoint.angle;
 
 	if (!(spr->cut & SC_ISROTATED))
 		splatangle += mobj->rollangle;
@@ -218,7 +217,7 @@ void R_DrawFloorSplat(vissprite_t *spr)
 	splat.x = x;
 	splat.y = y;
 	splat.z = mobj->z;
-	splat.tilted = false;
+	splat.slope = NULL;
 
 	// Set positions
 
@@ -238,9 +237,9 @@ void R_DrawFloorSplat(vissprite_t *spr)
 	splat.verts[3].x = w - xoffset;
 	splat.verts[3].y = -h + yoffset;
 
-	angle = -splat.angle;
-	ca = FINECOSINE(angle>>ANGLETOFINESHIFT);
-	sa = FINESINE(angle>>ANGLETOFINESHIFT);
+	angle = -splat.angle>>ANGLETOFINESHIFT;
+	ca = FINECOSINE(angle);
+	sa = FINESINE(angle);
 
 	// Rotate
 	for (i = 0; i < 4; i++)
@@ -255,36 +254,10 @@ void R_DrawFloorSplat(vissprite_t *spr)
 
 		// The slope that was defined for the sprite.
 		if (renderflags & RF_SLOPESPLAT)
-			slope = mobj->floorspriteslope;
+			splat.slope = mobj->floorspriteslope;
 
 		if (standingslope && (renderflags & RF_OBJECTSLOPESPLAT))
-			slope = standingslope;
-
-		// Set splat as tilted
-		splat.tilted = (slope != NULL);
-	}
-
-	if (splat.tilted)
-	{
-		pslope_t *s = &splat.slope;
-
-		s->o.x = slope->o.x;
-		s->o.y = slope->o.y;
-		s->o.z = slope->o.z;
-
-		s->d.x = slope->d.x;
-		s->d.y = slope->d.y;
-
-		s->normal.x = slope->normal.x;
-		s->normal.y = slope->normal.y;
-		s->normal.z = slope->normal.z;
-
-		s->zdelta = slope->zdelta;
-		s->zangle = slope->zangle;
-		s->xydirection = slope->xydirection;
-
-		s->next = NULL;
-		s->flags = 0;
+			splat.slope = standingslope;
 	}
 
 	// Translate
@@ -293,9 +266,9 @@ void R_DrawFloorSplat(vissprite_t *spr)
 		tr_x = rotated[i].x + x;
 		tr_y = rotated[i].y + y;
 
-		if (slope)
+		if (splat.slope)
 		{
-			rot_z = P_GetSlopeZAt(slope, tr_x, tr_y);
+			rot_z = P_GetSlopeZAt(splat.slope, tr_x, tr_y);
 			splat.verts[i].z = rot_z;
 		}
 		else
@@ -305,18 +278,23 @@ void R_DrawFloorSplat(vissprite_t *spr)
 		splat.verts[i].y = tr_y;
 	}
 
+	angle = spr->viewpoint.angle >> ANGLETOFINESHIFT;
+	ca = FINECOSINE(angle);
+	sa = FINESINE(angle);
+
+	// Project
 	for (i = 0; i < 4; i++)
 	{
 		v3d = &splat.verts[i];
 
 		// transform the origin point
-		tr_x = v3d->x - viewx;
-		tr_y = v3d->y - viewy;
+		tr_x = v3d->x - spr->viewpoint.x;
+		tr_y = v3d->y - spr->viewpoint.y;
 
 		// rotation around vertical y axis
-		rot_x = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos);
-		rot_y = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
-		rot_z = v3d->z - viewz;
+		rot_x = FixedMul(tr_x, sa) - FixedMul(tr_y, ca);
+		rot_y = FixedMul(tr_x, ca) + FixedMul(tr_y, sa);
+		rot_z = v3d->z - spr->viewpoint.z;
 
 		if (rot_y < FRACUNIT)
 			return;
@@ -416,31 +394,32 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
 	if (R_CheckPowersOfTwo())
 		R_CheckFlatLength(ds_flatwidth * ds_flatheight);
 
-	if (pSplat->tilted)
+	if (pSplat->slope)
 	{
 		R_SetTiltedSpan(0);
-		R_SetScaledSlopePlane(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewangle, pSplat->angle);
+		R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
 		R_CalculateSlopeVectors();
 		spanfunctype = SPANDRAWFUNC_TILTEDSPRITE;
 	}
 	else
 	{
-		planeheight = abs(pSplat->z - viewz);
+		planeheight = abs(pSplat->z - vis->viewpoint.z);
 
 		if (pSplat->angle)
 		{
-			// Add the view offset, rotated by the plane angle.
-			fixed_t a = -pSplat->verts[0].x + viewx;
-			fixed_t b = -pSplat->verts[0].y + viewy;
-			angle_t angle = (pSplat->angle >> ANGLETOFINESHIFT);
-			offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b,FINESINE(angle));
-			offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b,FINECOSINE(angle));
 			memset(cachedheight, 0, sizeof(cachedheight));
+
+			// Add the view offset, rotated by the plane angle.
+			fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x;
+			fixed_t b = -pSplat->verts[0].y + vis->viewpoint.y;
+			angle_t angle = (pSplat->angle >> ANGLETOFINESHIFT);
+			offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b, FINESINE(angle));
+			offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b, FINECOSINE(angle));
 		}
 		else
 		{
-			offsetx = viewx - pSplat->verts[0].x;
-			offsety = pSplat->verts[0].y - viewy;
+			offsetx = vis->viewpoint.x - pSplat->verts[0].x;
+			offsety = pSplat->verts[0].y - vis->viewpoint.y;
 		}
 	}
 
@@ -461,7 +440,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
 	{
 		ds_transmap = vis->transmap;
 
-		if (pSplat->tilted)
+		if (pSplat->slope)
 			spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE;
 		else
 			spanfunctype = SPANDRAWFUNC_TRANSSPRITE;
@@ -528,12 +507,12 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
 		if (x2 < x1)
 			continue;
 
-		if (!pSplat->tilted)
+		if (!pSplat->slope)
 		{
 			fixed_t xstep, ystep;
 			fixed_t distance, span;
 
-			angle_t angle = (vis->viewangle + pSplat->angle)>>ANGLETOFINESHIFT;
+			angle_t angle = (vis->viewpoint.angle + pSplat->angle)>>ANGLETOFINESHIFT;
 			angle_t planecos = FINECOSINE(angle);
 			angle_t planesin = FINESINE(angle);
 
@@ -577,7 +556,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
 		rastertab[y].maxx = INT32_MIN;
 	}
 
-	if (pSplat->angle && !pSplat->tilted)
+	if (pSplat->angle && !pSplat->slope)
 		memset(cachedheight, 0, sizeof(cachedheight));
 }
 
diff --git a/src/r_splats.h b/src/r_splats.h
index cab3d63b6..7e31406d1 100644
--- a/src/r_splats.h
+++ b/src/r_splats.h
@@ -34,8 +34,7 @@ typedef struct floorsplat_s
 	INT32 width, height;
 	fixed_t scale, xscale, yscale;
 	angle_t angle;
-	boolean tilted; // Uses the tilted drawer
-	pslope_t slope;
+	pslope_t *slope;
 
 	vector3_t verts[4]; // (x,y,z) as viewed from above on map
 	fixed_t x, y, z; // position
diff --git a/src/r_things.c b/src/r_things.c
index b636a9701..ea57e4086 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1957,9 +1957,12 @@ static void R_ProjectSprite(mobj_t *thing)
 	vis->paperoffset = paperoffset;
 	vis->paperdistance = paperdistance;
 	vis->centerangle = centerangle;
-	vis->viewangle = viewangle;
 	vis->shear.tan = sheartan;
 	vis->shear.offset = 0;
+	vis->viewpoint.x = viewx;
+	vis->viewpoint.y = viewy;
+	vis->viewpoint.z = viewz;
+	vis->viewpoint.angle = viewangle;
 
 	vis->mobj = thing; // Easy access! Tails 06-07-2002
 
diff --git a/src/r_things.h b/src/r_things.h
index 9315b36e9..79dc80d94 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -164,7 +164,12 @@ typedef struct vissprite_s
 	fixed_t xiscale; // negative if flipped
 
 	angle_t centerangle; // for paper sprites
-	angle_t viewangle; // for floor sprites, the viewpoint's current angle
+
+	// for floor sprites
+	struct {
+		fixed_t x, y, z; // the viewpoint's current position
+		angle_t angle; // the viewpoint's current angle
+	} viewpoint;
 
 	struct {
 		fixed_t tan; // The amount to shear the sprite vertically per row
@@ -185,9 +190,10 @@ typedef struct vissprite_s
 
 	extracolormap_t *extra_colormap; // global colormaps
 
-	// Precalculated top and bottom screen coords for the sprite.
 	fixed_t thingheight; // The actual height of the thing (for 3D floors)
 	sector_t *sector; // The sector containing the thing.
+
+	// Precalculated top and bottom screen coords for the sprite.
 	INT16 sz, szt;
 
 	spritecut_e cut;