diff --git a/src/d_main.c b/src/d_main.c
index e3143d22ce0effe84393d5f1b1153c4f5aa953d3..3e97cb49ae4a5c3de31545ac0a6f496cdee55875 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -498,14 +498,14 @@ static void D_Display(void)
 					if (rendermode != render_none)
 					{
 						viewwindowy = vid.height / 2;
-						M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
+						ylookup = ylookup2;
 
 						topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
 
 						R_RenderPlayerView(&players[secondarydisplayplayer]);
 
 						viewwindowy = 0;
-						M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
+						ylookup = ylookup1;
 					}
 				}
 
diff --git a/src/doomdef.h b/src/doomdef.h
index 84404d6edb62d82633b3f2643b9133a14d6b7ed3..9f0de060656fd11a23d86a13f094c44e5053a1f6 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -677,13 +677,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
 /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
 //#define PAPER_COLLISIONCORRECTION
 
-/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
-/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
-/// on the bright side it fixes some weird issues with translucent walls
-/// \note	SRB2CB port.
-///      	SRB2CB itself ported this from PrBoom+
-#define NEWCLIP
-
 /// OpenGL shaders
 #define GL_SHADERS
 
diff --git a/src/doomstat.h b/src/doomstat.h
index a812cc304f6e0b19cab8f2fecf37868264ed9b16..3f40a49b7a363e3677d202c4ded09c0feadcfca5 100644
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -130,7 +130,7 @@ extern postimg_t postimgtype2;
 extern INT32 postimgparam2;
 
 extern INT32 viewwindowx, viewwindowy;
-extern INT32 viewwidth, scaledviewwidth;
+extern INT32 viewwidth;
 
 // Player taking events, and displaying.
 extern INT32 consoleplayer;
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 36ff86abd7d0770351234913b03d837e2086b62d..a118784feaa3fbe3196f84fb73c8cd4dd0b8fedd 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -41,11 +41,9 @@
 #include "../r_things.h" // R_GetShadowZ
 #include "../d_main.h"
 #include "../p_slopes.h"
-#include "hw_md2.h"
 
-#ifdef NEWCLIP
+#include "hw_md2.h"
 #include "hw_clip.h"
-#endif
 
 #define R_FAKEFLOORS
 #define HWPRECIP
@@ -81,19 +79,6 @@ boolean drawsky = true;
 #define FIELDOFVIEW ANGLE_90
 #define ABS(x) ((x) < 0 ? -(x) : (x))
 
-static angle_t gl_clipangle;
-
-// The viewangletox[viewangle + FINEANGLES/4] lookup
-// maps the visible view angles to screen X coordinates,
-// flattening the arc to a flat projection plane.
-// There will be many angles mapped to the same X.
-static INT32 gl_viewangletox[FINEANGLES/2];
-
-// The xtoviewangleangle[] table maps a screen pixel
-// to the lowest viewangle that maps back to x ranges
-// from clipangle to -clipangle.
-static angle_t gl_xtoviewangle[MAXVIDWIDTH+1];
-
 // ==========================================================================
 //                                                                    GLOBALS
 // ==========================================================================
@@ -786,41 +771,6 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL
 //                                                          BSP, CULL, ETC..
 // ==========================================================================
 
-// return the frac from the interception of the clipping line
-// (in fact a clipping plane that has a constant, so can clip with simple 2d)
-// with the wall segment
-//
-#ifndef NEWCLIP
-static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
-{
-	float num, den;
-	float v1x, v1y, v1dx, v1dy, v2dx, v2dy;
-	angle_t pclipangle = gl_xtoviewangle[x];
-
-	// a segment of a polygon
-	v1x  = v1->x;
-	v1y  = v1->y;
-	v1dx = (v2->x - v1->x);
-	v1dy = (v2->y - v1->y);
-
-	// the clipping line
-	pclipangle = pclipangle + dup_viewangle; //back to normal angle (non-relative)
-	v2dx = FIXED_TO_FLOAT(FINECOSINE(pclipangle>>ANGLETOFINESHIFT));
-	v2dy = FIXED_TO_FLOAT(FINESINE(pclipangle>>ANGLETOFINESHIFT));
-
-	den = v2dy*v1dx - v2dx*v1dy;
-	if (den == 0)
-		return -1; // parallel
-
-	// calc the frac along the polygon segment,
-	//num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
-	//num = -v1x * v2dy + v1y * v2dx;
-	num = (gl_viewx - v1x)*v2dy + (v1y - gl_viewy)*v2dx;
-
-	return num / den;
-}
-#endif
-
 // SoM: split up and light walls according to the lightlist.
 // This may also include leaving out parts of the wall that can't be seen
 static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags)
@@ -1846,7 +1796,6 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
 //
 // e6y: Check whether the player can look beyond this line
 //
-#ifdef NEWCLIP
 boolean checkforemptylines = true;
 // Don't modify anything here, just check
 // Kalaron: Modified for sloped linedefs
@@ -1929,295 +1878,6 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
 
 	return false;
 }
-#else
-//Hurdler: just like in r_bsp.c
-#if 1
-#define MAXSEGS         MAXVIDWIDTH/2+1
-#else
-//Alam_GBC: Or not (may cause overflow)
-#define MAXSEGS         128
-#endif
-
-// hw_newend is one past the last valid seg
-static cliprange_t *   hw_newend;
-static cliprange_t     gl_solidsegs[MAXSEGS];
-
-// needs fix: walls are incorrectly clipped one column less
-static consvar_t cv_glclipwalls = CVAR_INIT ("gr_clipwalls", "Off", 0, CV_OnOff, NULL);
-
-static void printsolidsegs(void)
-{
-	cliprange_t *       start;
-	if (!hw_newend)
-		return;
-	for (start = gl_solidsegs;start != hw_newend;start++)
-	{
-		CONS_Debug(DBG_RENDER, "%d-%d|",start->first,start->last);
-	}
-	CONS_Debug(DBG_RENDER, "\n\n");
-}
-
-//
-//
-//
-static void HWR_ClipSolidWallSegment(INT32 first, INT32 last)
-{
-	cliprange_t *next, *start;
-	float lowfrac, highfrac;
-	boolean poorhack = false;
-
-	// Find the first range that touches the range
-	//  (adjacent pixels are touching).
-	start = gl_solidsegs;
-	while (start->last < first-1)
-		start++;
-
-	if (first < start->first)
-	{
-		if (last < start->first-1)
-		{
-			// Post is entirely visible (above start),
-			//  so insert a new clippost.
-			HWR_StoreWallRange(first, last);
-
-			next = hw_newend;
-			hw_newend++;
-
-			while (next != start)
-			{
-				*next = *(next-1);
-				next--;
-			}
-
-			next->first = first;
-			next->last = last;
-			printsolidsegs();
-			return;
-		}
-
-		// There is a fragment above *start.
-		if (!cv_glclipwalls.value)
-		{
-			if (!poorhack) HWR_StoreWallRange(first, last);
-			poorhack = true;
-		}
-		else
-		{
-			highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
-			HWR_StoreWallRange(0, highfrac);
-		}
-		// Now adjust the clip size.
-		start->first = first;
-	}
-
-	// Bottom contained in start?
-	if (last <= start->last)
-	{
-		printsolidsegs();
-		return;
-	}
-	next = start;
-	while (last >= (next+1)->first-1)
-	{
-		// There is a fragment between two posts.
-		if (!cv_glclipwalls.value)
-		{
-			if (!poorhack) HWR_StoreWallRange(first,last);
-			poorhack = true;
-		}
-		else
-		{
-			lowfrac  = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
-			highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
-			HWR_StoreWallRange(lowfrac, highfrac);
-		}
-		next++;
-
-		if (last <= next->last)
-		{
-			// Bottom is contained in next.
-			// Adjust the clip size.
-			start->last = next->last;
-			goto crunch;
-		}
-	}
-
-	if (first == next->first+1) // 1 line texture
-	{
-		if (!cv_glclipwalls.value)
-		{
-			if (!poorhack) HWR_StoreWallRange(first,last);
-			poorhack = true;
-		}
-		else
-			HWR_StoreWallRange(0, 1);
-	}
-	else
-	{
-	// There is a fragment after *next.
-		if (!cv_glclipwalls.value)
-		{
-			if (!poorhack) HWR_StoreWallRange(first,last);
-			poorhack = true;
-		}
-		else
-		{
-			lowfrac  = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
-			HWR_StoreWallRange(lowfrac, 1);
-		}
-	}
-
-	// Adjust the clip size.
-	start->last = last;
-
-	// Remove start+1 to next from the clip list,
-	// because start now covers their area.
-crunch:
-	if (next == start)
-	{
-		printsolidsegs();
-		// Post just extended past the bottom of one post.
-		return;
-	}
-
-
-	while (next++ != hw_newend)
-	{
-		// Remove a post.
-		*++start = *next;
-	}
-
-	hw_newend = start;
-	printsolidsegs();
-}
-
-//
-//  handle LineDefs with upper and lower texture (windows)
-//
-static void HWR_ClipPassWallSegment(INT32 first, INT32 last)
-{
-	cliprange_t *start;
-	float lowfrac, highfrac;
-	//to allow noclipwalls but still solidseg reject of non-visible walls
-	boolean poorhack = false;
-
-	// Find the first range that touches the range
-	//  (adjacent pixels are touching).
-	start = gl_solidsegs;
-	while (start->last < first - 1)
-		start++;
-
-	if (first < start->first)
-	{
-		if (last < start->first-1)
-		{
-			// Post is entirely visible (above start).
-			HWR_StoreWallRange(0, 1);
-			return;
-		}
-
-		// There is a fragment above *start.
-		if (!cv_glclipwalls.value)
-		{	//20/08/99: Changed by Hurdler (taken from faB's code)
-			if (!poorhack) HWR_StoreWallRange(0, 1);
-			poorhack = true;
-		}
-		else
-		{
-			highfrac = HWR_ClipViewSegment(min(start->first + 1,
-				start->last), (polyvertex_t *)gl_curline->pv1,
-				(polyvertex_t *)gl_curline->pv2);
-			HWR_StoreWallRange(0, highfrac);
-		}
-	}
-
-	// Bottom contained in start?
-	if (last <= start->last)
-		return;
-
-	while (last >= (start+1)->first-1)
-	{
-		// There is a fragment between two posts.
-		if (!cv_glclipwalls.value)
-		{
-			if (!poorhack) HWR_StoreWallRange(0, 1);
-			poorhack = true;
-		}
-		else
-		{
-			lowfrac  = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
-			highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
-			HWR_StoreWallRange(lowfrac, highfrac);
-		}
-		start++;
-
-		if (last <= start->last)
-			return;
-	}
-
-	if (first == start->first+1) // 1 line texture
-	{
-		if (!cv_glclipwalls.value)
-		{
-			if (!poorhack) HWR_StoreWallRange(0, 1);
-			poorhack = true;
-		}
-		else
-			HWR_StoreWallRange(0, 1);
-	}
-	else
-	{
-		// There is a fragment after *next.
-		if (!cv_glclipwalls.value)
-		{
-			if (!poorhack) HWR_StoreWallRange(0,1);
-			poorhack = true;
-		}
-		else
-		{
-			lowfrac = HWR_ClipViewSegment(max(start->last - 1,
-				start->first), (polyvertex_t *)gl_curline->pv1,
-				(polyvertex_t *)gl_curline->pv2);
-			HWR_StoreWallRange(lowfrac, 1);
-		}
-	}
-}
-
-// --------------------------------------------------------------------------
-//  HWR_ClipToSolidSegs check if it is hide by wall (solidsegs)
-// --------------------------------------------------------------------------
-static boolean HWR_ClipToSolidSegs(INT32 first, INT32 last)
-{
-	cliprange_t * start;
-
-	// Find the first range that touches the range
-	//  (adjacent pixels are touching).
-	start = gl_solidsegs;
-	while (start->last < first-1)
-		start++;
-
-	if (first < start->first)
-		return true;
-
-	// Bottom contained in start?
-	if (last <= start->last)
-		return false;
-
-	return true;
-}
-
-//
-// HWR_ClearClipSegs
-//
-static void HWR_ClearClipSegs(void)
-{
-	gl_solidsegs[0].first = -0x7fffffff;
-	gl_solidsegs[0].last = -1;
-	gl_solidsegs[1].first = vid.width; //viewwidth;
-	gl_solidsegs[1].last = 0x7fffffff;
-	hw_newend = gl_solidsegs+2;
-}
-#endif // NEWCLIP
 
 // -----------------+
 // HWR_AddLine      : Clips the given segment and adds any visible pieces to the line list.
@@ -2227,11 +1887,6 @@ static void HWR_ClearClipSegs(void)
 static void HWR_AddLine(seg_t * line)
 {
 	angle_t angle1, angle2;
-#ifndef NEWCLIP
-	INT32 x1, x2;
-	angle_t span, tspan;
-	boolean bothceilingssky = false, bothfloorssky = false;
-#endif
 
 	// SoM: Backsector needs to be run through R_FakeFlat
 	static sector_t tempsec;
@@ -2251,7 +1906,6 @@ static void HWR_AddLine(seg_t * line)
 	angle1 = R_PointToAngle64(v1x, v1y);
 	angle2 = R_PointToAngle64(v2x, v2y);
 
-#ifdef NEWCLIP
 	 // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle!
 	if (angle2 - angle1 < ANGLE_180)
 		return;
@@ -2264,90 +1918,9 @@ static void HWR_AddLine(seg_t * line)
     }
 
 	checkforemptylines = true;
-#else
-	// Clip to view edges.
-	span = angle1 - angle2;
-
-	// backface culling : span is < ANGLE_180 if ang1 > ang2 : the seg is facing
-	if (span >= ANGLE_180)
-		return;
-
-	// Global angle needed by segcalc.
-	//rw_angle1 = angle1;
-	angle1 -= dup_viewangle;
-	angle2 -= dup_viewangle;
-
-	tspan = angle1 + gl_clipangle;
-	if (tspan > 2*gl_clipangle)
-	{
-		tspan -= 2*gl_clipangle;
-
-		// Totally off the left edge?
-		if (tspan >= span)
-			return;
-
-		angle1 = gl_clipangle;
-	}
-	tspan = gl_clipangle - angle2;
-	if (tspan > 2*gl_clipangle)
-	{
-		tspan -= 2*gl_clipangle;
-
-		// Totally off the left edge?
-		if (tspan >= span)
-			return;
-
-		angle2 = (angle_t)-(signed)gl_clipangle;
-	}
-
-#if 0
-	{
-		float fx1,fx2,fy1,fy2;
-		//BP: test with a better projection than viewangletox[R_PointToAngle(angle)]
-		// do not enable this at release 4 mul and 2 div
-		fx1 = ((polyvertex_t *)(line->pv1))->x-gl_viewx;
-		fy1 = ((polyvertex_t *)(line->pv1))->y-gl_viewy;
-		fy2 = (fx1 * gl_viewcos + fy1 * gl_viewsin);
-		if (fy2 < 0)
-			// the point is back
-			fx1 = 0;
-		else
-			fx1 = gl_windowcenterx + (fx1 * gl_viewsin - fy1 * gl_viewcos) * gl_centerx / fy2;
-
-		fx2 = ((polyvertex_t *)(line->pv2))->x-gl_viewx;
-		fy2 = ((polyvertex_t *)(line->pv2))->y-gl_viewy;
-		fy1 = (fx2 * gl_viewcos + fy2 * gl_viewsin);
-		if (fy1 < 0)
-			// the point is back
-			fx2 = vid.width;
-		else
-			fx2 = gl_windowcenterx + (fx2 * gl_viewsin - fy2 * gl_viewcos) * gl_centerx / fy1;
-
-		x1 = fx1+0.5f;
-		x2 = fx2+0.5f;
-	}
-#else
-	// The seg is in the view range,
-	// but not necessarily visible.
-	angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
-	angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT;
-
-	x1 = gl_viewangletox[angle1];
-	x2 = gl_viewangletox[angle2];
-#endif
-	// Does not cross a pixel?
-//	if (x1 == x2)
-/*	{
-		// BP: HERE IS THE MAIN PROBLEM !
-		//CONS_Debug(DBG_RENDER, "tineline\n");
-		return;
-	}
-*/
-#endif
 
 	gl_backsector = line->backsector;
 
-#ifdef NEWCLIP
 	if (!line->backsector)
     {
 		gld_clipper_SafeAddClipRange(angle2, angle1);
@@ -2389,115 +1962,6 @@ static void HWR_AddLine(seg_t * line)
     }
 
 	HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D
-	return;
-#else
-	// Single sided line?
-	if (!gl_backsector)
-		goto clipsolid;
-
-	gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true);
-
-	if (gl_backsector->ceilingpic == skyflatnum && gl_frontsector->ceilingpic == skyflatnum)
-		bothceilingssky = true;
-	if (gl_backsector->floorpic == skyflatnum && gl_frontsector->floorpic == skyflatnum)
-		bothfloorssky = true;
-
-	if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
-	{
-		if (!line->polyseg &&
-			!line->sidedef->midtexture
-			&& ((!gl_frontsector->ffloors && !gl_backsector->ffloors)
-				|| Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags)))
-			return; // line is empty, don't even bother
-
-		goto clippass; // treat like wide open window instead
-	}
-
-	if (gl_frontsector->f_slope || gl_frontsector->c_slope || gl_backsector->f_slope || gl_backsector->c_slope)
-	{
-		fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
-		fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
-
-#define SLOPEPARAMS(slope, end1, end2, normalheight) \
-		end1 = P_GetZAt(slope, v1x, v1y, normalheight); \
-		end2 = P_GetZAt(slope, v2x, v2y, normalheight);
-
-		SLOPEPARAMS(gl_frontsector->f_slope, frontf1, frontf2, gl_frontsector->  floorheight)
-		SLOPEPARAMS(gl_frontsector->c_slope, frontc1, frontc2, gl_frontsector->ceilingheight)
-		SLOPEPARAMS( gl_backsector->f_slope,  backf1,  backf2,  gl_backsector->  floorheight)
-		SLOPEPARAMS( gl_backsector->c_slope,  backc1,  backc2,  gl_backsector->ceilingheight)
-#undef SLOPEPARAMS
-		// if both ceilings are skies, consider it always "open"
-		// same for floors
-		if (!bothceilingssky && !bothfloorssky)
-		{
-			// Closed door.
-			if ((backc1 <= frontf1 && backc2 <= frontf2)
-				|| (backf1 >= frontc1 && backf2 >= frontc2))
-			{
-				goto clipsolid;
-			}
-
-			// Check for automap fix.
-			if (backc1 <= backf1 && backc2 <= backf2
-			&& ((backc1 >= frontc1 && backc2 >= frontc2) || gl_curline->sidedef->toptexture)
-			&& ((backf1 <= frontf1 && backf2 >= frontf2) || gl_curline->sidedef->bottomtexture))
-				goto clipsolid;
-		}
-
-		// Window.
-		if (!bothceilingssky) // ceilings are always the "same" when sky
-			if (backc1 != frontc1 || backc2 != frontc2)
-				goto clippass;
-		if (!bothfloorssky)	// floors are always the "same" when sky
-			if (backf1 != frontf1 || backf2 != frontf2)
-				goto clippass;
-	}
-	else
-	{
-		// if both ceilings are skies, consider it always "open"
-		// same for floors
-		if (!bothceilingssky && !bothfloorssky)
-		{
-			// Closed door.
-			if (gl_backsector->ceilingheight <= gl_frontsector->floorheight ||
-				gl_backsector->floorheight >= gl_frontsector->ceilingheight)
-				goto clipsolid;
-
-			// Check for automap fix.
-			if (gl_backsector->ceilingheight <= gl_backsector->floorheight
-			&& ((gl_backsector->ceilingheight >= gl_frontsector->ceilingheight) || gl_curline->sidedef->toptexture)
-			&& ((gl_backsector->floorheight <= gl_backsector->floorheight) || gl_curline->sidedef->bottomtexture))
-				goto clipsolid;
-		}
-
-		// Window.
-		if (!bothceilingssky) // ceilings are always the "same" when sky
-			if (gl_backsector->ceilingheight != gl_frontsector->ceilingheight)
-				goto clippass;
-		if (!bothfloorssky)	// floors are always the "same" when sky
-			if (gl_backsector->floorheight != gl_frontsector->floorheight)
-				goto clippass;
-	}
-
-	// Reject empty lines used for triggers and special events.
-	// Identical floor and ceiling on both sides,
-	//  identical light levels on both sides,
-	//  and no middle texture.
-	if (R_IsEmptyLine(gl_curline, gl_frontsector, gl_backsector))
-		return;
-
-clippass:
-	if (x1 == x2)
-		{  x2++;x1 -= 2; }
-	HWR_ClipPassWallSegment(x1, x2-1);
-	return;
-
-clipsolid:
-	if (x1 == x2)
-		goto clippass;
-	HWR_ClipSolidWallSegment(x1, x2-1);
-#endif
 }
 
 // HWR_CheckBBox
@@ -2512,10 +1976,6 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
 	INT32 boxpos;
 	fixed_t px1, py1, px2, py2;
 	angle_t angle1, angle2;
-#ifndef NEWCLIP
-	INT32 sx1, sx2;
-	angle_t span, tspan;
-#endif
 
 	// Find the corners of the box
 	// that define the edges from current viewpoint.
@@ -2541,59 +2001,9 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
 	px2 = bspcoord[checkcoord[boxpos][2]];
 	py2 = bspcoord[checkcoord[boxpos][3]];
 
-#ifdef NEWCLIP
 	angle1 = R_PointToAngle64(px1, py1);
 	angle2 = R_PointToAngle64(px2, py2);
 	return gld_clipper_SafeCheckRange(angle2, angle1);
-#else
-	// check clip list for an open space
-	angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle;
-	angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle;
-
-	span = angle1 - angle2;
-
-	// Sitting on a line?
-	if (span >= ANGLE_180)
-		return true;
-
-	tspan = angle1 + gl_clipangle;
-
-	if (tspan > 2*gl_clipangle)
-	{
-		tspan -= 2*gl_clipangle;
-
-		// Totally off the left edge?
-		if (tspan >= span)
-			return false;
-
-		angle1 = gl_clipangle;
-	}
-	tspan = gl_clipangle - angle2;
-	if (tspan > 2*gl_clipangle)
-	{
-		tspan -= 2*gl_clipangle;
-
-		// Totally off the left edge?
-		if (tspan >= span)
-			return false;
-
-		angle2 = (angle_t)-(signed)gl_clipangle;
-	}
-
-	// Find the first clippost
-	//  that touches the source post
-	//  (adjacent pixels are touching).
-	angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
-	angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT;
-	sx1 = gl_viewangletox[angle1];
-	sx2 = gl_viewangletox[angle2];
-
-	// Does not cross a pixel.
-	if (sx1 == sx2)
-		return false;
-
-	return HWR_ClipToSolidSegs(sx1, sx2 - 1);
-#endif
 }
 
 //
@@ -3317,100 +2727,6 @@ static void HWR_RenderBSPNode(INT32 bspnum)
 	}
 }
 
-/*
-//
-// Clear 'stack' of subsectors to draw
-//
-static void HWR_ClearDrawSubsectors(void)
-{
-	gl_drawsubsector_p = gl_drawsubsectors;
-}
-
-//
-// Draw subsectors pushed on the drawsubsectors 'stack', back to front
-//
-static void HWR_RenderSubsectors(void)
-{
-	while (gl_drawsubsector_p > gl_drawsubsectors)
-	{
-		HWR_RenderBSPNode(
-		lastsubsec->nextsubsec = bspnum & (~NF_SUBSECTOR);
-	}
-}
-*/
-
-// ==========================================================================
-//                                                              FROM R_MAIN.C
-// ==========================================================================
-
-//BP : exactely the same as R_InitTextureMapping
-void HWR_InitTextureMapping(void)
-{
-	angle_t i;
-	INT32 x;
-	INT32 t;
-	fixed_t focallength;
-	fixed_t grcenterx;
-	fixed_t grcenterxfrac;
-	INT32 grviewwidth;
-
-#define clipanglefov (FIELDOFVIEW>>ANGLETOFINESHIFT)
-
-	grviewwidth = vid.width;
-	grcenterx = grviewwidth/2;
-	grcenterxfrac = grcenterx<<FRACBITS;
-
-	// Use tangent table to generate viewangletox:
-	//  viewangletox will give the next greatest x
-	//  after the view angle.
-	//
-	// Calc focallength
-	//  so FIELDOFVIEW angles covers SCREENWIDTH.
-	focallength = FixedDiv(grcenterxfrac,
-		FINETANGENT(FINEANGLES/4+clipanglefov/2));
-
-	for (i = 0; i < FINEANGLES/2; i++)
-	{
-		if (FINETANGENT(i) > FRACUNIT*2)
-			t = -1;
-		else if (FINETANGENT(i) < -FRACUNIT*2)
-			t = grviewwidth+1;
-		else
-		{
-			t = FixedMul(FINETANGENT(i), focallength);
-			t = (grcenterxfrac - t+FRACUNIT-1)>>FRACBITS;
-
-			if (t < -1)
-				t = -1;
-			else if (t > grviewwidth+1)
-				t = grviewwidth+1;
-		}
-		gl_viewangletox[i] = t;
-	}
-
-	// Scan viewangletox[] to generate xtoviewangle[]:
-	//  xtoviewangle will give the smallest view angle
-	//  that maps to x.
-	for (x = 0; x <= grviewwidth; x++)
-	{
-		i = 0;
-		while (gl_viewangletox[i]>x)
-			i++;
-		gl_xtoviewangle[x] = (i<<ANGLETOFINESHIFT) - ANGLE_90;
-	}
-
-	// Take out the fencepost cases from viewangletox.
-	for (i = 0; i < FINEANGLES/2; i++)
-	{
-		if (gl_viewangletox[i] == -1)
-			gl_viewangletox[i] = 0;
-		else if (gl_viewangletox[i] == grviewwidth+1)
-			gl_viewangletox[i]  = grviewwidth;
-	}
-
-	gl_clipangle = gl_xtoviewangle[0];
-}
-
 // ==========================================================================
 // gl_things.c
 // ==========================================================================
@@ -5967,7 +5283,7 @@ static void HWR_DrawSkyBackground(player_t *player)
 		// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
 		// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
 
-		angle = (dup_viewangle + gl_xtoviewangle[0]);
+		angle = (dup_viewangle + xtoviewangle[0]);
 
 		dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
 
@@ -6217,18 +5533,11 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
 
 	drawcount = 0;
 
-#ifdef NEWCLIP
-	if (rendermode == render_opengl)
-	{
-		angle_t a1 = gld_FrustumAngle(gl_aimingangle);
-		gld_clipper_Clear();
-		gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
+	angle_t a1 = gld_FrustumAngle(gl_aimingangle);
+	gld_clipper_Clear();
+	gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
 #ifdef HAVE_SPHEREFRUSTRUM
-		gld_FrustrumSetup();
-#endif
-	}
-#else
-	HWR_ClearClipSegs();
+	gld_FrustrumSetup();
 #endif
 
 	//04/01/2000: Hurdler: added for T&L
@@ -6245,35 +5554,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
 
 	HWR_RenderBSPNode((INT32)numnodes-1);
 
-#ifndef NEWCLIP
-	// Make a viewangle int so we can render things based on mouselook
-	if (player == &players[consoleplayer])
-		viewangle = localaiming;
-	else if (splitscreen && player == &players[secondarydisplayplayer])
-		viewangle = localaiming2;
-
-	// Handle stuff when you are looking farther up or down.
-	if ((gl_aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
-	{
-		dup_viewangle += ANGLE_90;
-		HWR_ClearClipSegs();
-		HWR_RenderBSPNode((INT32)numnodes-1); //left
-
-		dup_viewangle += ANGLE_90;
-		if (((INT32)gl_aimingangle > ANGLE_45 || (INT32)gl_aimingangle<-ANGLE_45))
-		{
-			HWR_ClearClipSegs();
-			HWR_RenderBSPNode((INT32)numnodes-1); //back
-		}
-
-		dup_viewangle += ANGLE_90;
-		HWR_ClearClipSegs();
-		HWR_RenderBSPNode((INT32)numnodes-1); //right
-
-		dup_viewangle += ANGLE_90;
-	}
-#endif
-
 	if (cv_glbatching.value)
 		HWR_RenderBatches();
 
@@ -6433,18 +5713,11 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
 
 	drawcount = 0;
 
-#ifdef NEWCLIP
-	if (rendermode == render_opengl)
-	{
-		angle_t a1 = gld_FrustumAngle(gl_aimingangle);
-		gld_clipper_Clear();
-		gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
+	angle_t a1 = gld_FrustumAngle(gl_aimingangle);
+	gld_clipper_Clear();
+	gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
 #ifdef HAVE_SPHEREFRUSTRUM
-		gld_FrustrumSetup();
-#endif
-	}
-#else
-	HWR_ClearClipSegs();
+	gld_FrustrumSetup();
 #endif
 
 	//04/01/2000: Hurdler: added for T&L
@@ -6465,35 +5738,6 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
 
 	HWR_RenderBSPNode((INT32)numnodes-1);
 
-#ifndef NEWCLIP
-	// Make a viewangle int so we can render things based on mouselook
-	if (player == &players[consoleplayer])
-		viewangle = localaiming;
-	else if (splitscreen && player == &players[secondarydisplayplayer])
-		viewangle = localaiming2;
-
-	// Handle stuff when you are looking farther up or down.
-	if ((gl_aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
-	{
-		dup_viewangle += ANGLE_90;
-		HWR_ClearClipSegs();
-		HWR_RenderBSPNode((INT32)numnodes-1); //left
-
-		dup_viewangle += ANGLE_90;
-		if (((INT32)gl_aimingangle > ANGLE_45 || (INT32)gl_aimingangle<-ANGLE_45))
-		{
-			HWR_ClearClipSegs();
-			HWR_RenderBSPNode((INT32)numnodes-1); //back
-		}
-
-		dup_viewangle += ANGLE_90;
-		HWR_ClearClipSegs();
-		HWR_RenderBSPNode((INT32)numnodes-1); //right
-
-		dup_viewangle += ANGLE_90;
-	}
-#endif
-
 	PS_STOP_TIMING(ps_bsptime);
 
 	if (cv_glbatching.value)
@@ -6646,10 +5890,6 @@ void HWR_AddCommands(void)
 	CV_RegisterVar(&cv_glsolvetjoin);
 
 	CV_RegisterVar(&cv_glbatching);
-
-#ifndef NEWCLIP
-	CV_RegisterVar(&cv_glclipwalls);
-#endif
 }
 
 void HWR_AddSessionCommands(void)
diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h
index 9450ca2c56ed56d52916f587136e2e9352f3f4b4..fbc365c11370e717733e84bf15806f6020e7191a 100644
--- a/src/hardware/hw_main.h
+++ b/src/hardware/hw_main.h
@@ -37,7 +37,6 @@ void HWR_ClearSkyDome(void);
 void HWR_BuildSkyDome(void);
 void HWR_DrawViewBorder(INT32 clearlines);
 void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum);
-void HWR_InitTextureMapping(void);
 void HWR_SetViewSize(void);
 void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option);
 void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);
diff --git a/src/r_defs.h b/src/r_defs.h
index a9b9a4a0835a5969b93e4def8a2f231b5d565991..bef0d9ba2a05e49f6f9c937d1f8897ecfe41657c 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -764,11 +764,11 @@ typedef struct drawseg_s
 	struct ffloor_s *thicksides[MAXFFLOORS];
 	INT16 *thicksidecol;
 	INT32 numthicksides;
-	fixed_t frontscale[MAXVIDWIDTH];
+	fixed_t *frontscale;
 
 	UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping
 
-	fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures
+	fixed_t *maskedtextureheight; // For handling sloped midtextures
 
 	vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
 } drawseg_t;
diff --git a/src/r_draw.c b/src/r_draw.c
index 79ad9adde954f741054d81f182937ffb89da6ffd..4dd204606732504af20a3277a7b708465dfa0307 100644
--- a/src/r_draw.c
+++ b/src/r_draw.c
@@ -18,6 +18,7 @@
 #include "doomdef.h"
 #include "doomstat.h"
 #include "r_local.h"
+#include "r_splats.h"
 #include "st_stuff.h" // need ST_HEIGHT
 #include "i_video.h"
 #include "v_video.h"
@@ -37,24 +38,24 @@
 
 /**	\brief view info
 */
-INT32 viewwidth, scaledviewwidth, viewheight, viewwindowx, viewwindowy;
+INT32 viewwidth, viewheight, viewwindowx, viewwindowy;
 
 /**	\brief pointer to the start of each line of the screen,
 */
-UINT8 *ylookup[MAXVIDHEIGHT*4];
+UINT8 **ylookup;
 
 /**	\brief pointer to the start of each line of the screen, for view1 (splitscreen)
 */
-UINT8 *ylookup1[MAXVIDHEIGHT*4];
+UINT8 **ylookup1;
 
 /**	\brief pointer to the start of each line of the screen, for view2 (splitscreen)
 */
-UINT8 *ylookup2[MAXVIDHEIGHT*4];
+UINT8 **ylookup2;
 
 /**	\brief  x byte offset for columns inside the viewwindow,
 	so the first column starts at (SCRWIDTH - VIEWWIDTH)/2
 */
-INT32 columnofs[MAXVIDWIDTH*4];
+INT32 *columnofs;
 
 UINT8 *topleft;
 
@@ -121,6 +122,9 @@ float focallengthf, zeroheight;
 
 UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
 
+// For, uh, tilted lighting, duh.
+static INT32 *tiltlighting;
+
 // =========================================================================
 //                   TRANSLATION COLORMAP CODE
 // =========================================================================
@@ -701,6 +705,29 @@ void R_InitViewBuffer(INT32 width, INT32 height)
 	if (bytesperpixel < 1 || bytesperpixel > 4)
 		I_Error("R_InitViewBuffer: wrong bytesperpixel value %d\n", bytesperpixel);
 
+	negonearray = Z_Realloc(negonearray, sizeof(*negonearray) * viewwidth, PU_STATIC, NULL);
+	screenheightarray = Z_Realloc(screenheightarray, sizeof(*screenheightarray) * viewwidth, PU_STATIC, NULL);
+
+	floorclip = Z_Realloc(floorclip, sizeof(*floorclip) * viewwidth, PU_STATIC, NULL);
+	ceilingclip = Z_Realloc(ceilingclip, sizeof(*ceilingclip) * viewwidth, PU_STATIC, NULL);
+
+	frontscale = Z_Realloc(frontscale, sizeof(*frontscale) * viewwidth, PU_STATIC, NULL);
+
+	ylookup1 = Z_Realloc(ylookup1, sizeof(*ylookup1) * (viewheight * 4), PU_STATIC, NULL);
+	ylookup2 = Z_Realloc(ylookup2, sizeof(*ylookup2) * (viewheight * 4), PU_STATIC, NULL);
+	ylookup = ylookup1;
+
+	columnofs = Z_Realloc(columnofs, sizeof(*columnofs) * (viewwidth * 4), PU_STATIC, NULL);
+
+	xtoviewangle = Z_Realloc(xtoviewangle, sizeof(*xtoviewangle) * (viewwidth + 1), PU_STATIC, NULL);
+
+	tiltlighting = Z_Realloc(tiltlighting, sizeof(*tiltlighting) * viewwidth, PU_STATIC, NULL);
+
+	R_AllocSegMemory();
+	R_AllocPlaneMemory();
+	R_AllocFloorSpriteTables();
+	R_AllocVisSpriteMemory();
+
 	// Handle resize, e.g. smaller view windows with border and/or status bar.
 	viewwindowx = (vid.width - width) >> 1;
 
@@ -717,7 +744,7 @@ void R_InitViewBuffer(INT32 width, INT32 height)
 	// Precalculate all row offsets.
 	for (i = 0; i < height; i++)
 	{
-		ylookup[i] = ylookup1[i] = screens[0] + (i+viewwindowy)*vid.width*bytesperpixel;
+		ylookup1[i] = screens[0] + (i+viewwindowy)*vid.width*bytesperpixel;
 		ylookup2[i] = screens[0] + (i+(vid.height>>1))*vid.width*bytesperpixel; // for splitscreen
 	}
 }
@@ -745,8 +772,6 @@ void R_VideoErase(size_t ofs, INT32 count)
 
 // R_CalcTiltedLighting
 // Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
-static INT32 tiltlighting[MAXVIDWIDTH];
-
 static void R_CalcTiltedLighting(fixed_t start, fixed_t end)
 {
 	// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
diff --git a/src/r_draw.h b/src/r_draw.h
index 09fd2fff2e52f60935fd86294318fffbc69c892d..a58a8a6580c71ba861498c0d7e2f070ab95f5702 100644
--- a/src/r_draw.h
+++ b/src/r_draw.h
@@ -19,10 +19,10 @@
 // -------------------------------
 // COMMON STUFF FOR 8bpp AND 16bpp
 // -------------------------------
-extern UINT8 *ylookup[MAXVIDHEIGHT*4];
-extern UINT8 *ylookup1[MAXVIDHEIGHT*4];
-extern UINT8 *ylookup2[MAXVIDHEIGHT*4];
-extern INT32 columnofs[MAXVIDWIDTH*4];
+extern UINT8 **ylookup;
+extern UINT8 **ylookup1;
+extern UINT8 **ylookup2;
+extern INT32 *columnofs;
 extern UINT8 *topleft;
 
 // -------------------------
diff --git a/src/r_fps.c b/src/r_fps.c
index c6eb5948212972d87d1e0079c668483fb927de94..7aec22d262f29184f98ce75a6ec7e1b9f5fd465a 100644
--- a/src/r_fps.c
+++ b/src/r_fps.c
@@ -122,7 +122,7 @@ static vector3_t *R_LerpVector3(const vector3_t *from, const vector3_t *to, fixe
 
 // recalc necessary stuff for mouseaiming
 // slopes are already calculated for the full possible view (which is 4*viewheight).
-// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
+// 18/08/18: (No it's actually 16*viewheight, thanks Lactozilla for finding this out)
 static void R_SetupFreelook(player_t *player, boolean skybox)
 {
 #ifndef HWRENDER
diff --git a/src/r_main.c b/src/r_main.c
index dea402eec87b2bef5282c93624b80e0e68474188..df4f676d5770a57951a4c6e7b8411017b77c7d26 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -95,7 +95,7 @@ INT32 viewangletox[FINEANGLES/2];
 // The xtoviewangleangle[] table maps a screen pixel
 // to the lowest viewangle that maps back to x ranges
 // from clipangle to -clipangle.
-angle_t xtoviewangle[MAXVIDWIDTH+1];
+angle_t *xtoviewangle;
 
 lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
 lighttable_t *scalelightfixed[MAXLIGHTSCALE];
@@ -606,7 +606,10 @@ static struct {
 	INT32 scrmapsize;
 
 	INT32 x1; // clip rendering horizontally for efficiency
-	INT16 ceilingclip[MAXVIDWIDTH], floorclip[MAXVIDWIDTH];
+	INT16 *ceilingclip, *floorclip;
+#ifdef WOUGHMP_WOUGHMP
+	float *fisheyemap;
+#endif
 
 	boolean use;
 } viewmorph = {
@@ -620,7 +623,10 @@ static struct {
 	0,
 
 	0,
-	{0}, {0},
+	NULL, NULL,
+#ifdef WOUGHMP_WOUGHMP
+	NULL,
+#endif
 
 	false
 };
@@ -632,9 +638,6 @@ void R_CheckViewMorph(void)
 	fixed_t temp;
 	INT32 end, vx, vy, pos, usedpos;
 	INT32 usedx, usedy, halfwidth = vid.width/2, halfheight = vid.height/2;
-#ifdef WOUGHMP_WOUGHMP
-	float fisheyemap[MAXVIDWIDTH/2 + 1];
-#endif
 
 	angle_t rollangle = players[displayplayer].viewrollangle;
 #ifdef WOUGHMP_WOUGHMP
@@ -677,10 +680,13 @@ void R_CheckViewMorph(void)
 
 	if (viewmorph.scrmapsize != vid.width*vid.height)
 	{
-		if (viewmorph.scrmap)
-			free(viewmorph.scrmap);
-		viewmorph.scrmap = malloc(vid.width*vid.height * sizeof(INT32));
 		viewmorph.scrmapsize = vid.width*vid.height;
+		viewmorph.scrmap = realloc(viewmorph.scrmap, vid.width*vid.height * sizeof(INT32));
+		viewmorph.ceilingclip = realloc(viewmorph.ceilingclip, vid.width * sizeof(INT16));
+		viewmorph.floorclip = realloc(viewmorph.floorclip, vid.width * sizeof(INT16));
+#ifdef WOUGHMP_WOUGHMP
+		viewmorph.fisheyemap = realloc(viewmorph.fisheyemap, (vid.width/2 + 1) * sizeof(float));
+#endif
 	}
 
 	temp = FINECOSINE(rollangle);
@@ -923,14 +929,12 @@ void R_ExecuteSetViewSize(void)
 	// status bar overlay
 	st_overlay = cv_showhud.value;
 
-	scaledviewwidth = vid.width;
+	viewwidth = vid.width;
 	viewheight = vid.height;
 
 	if (splitscreen)
 		viewheight >>= 1;
 
-	viewwidth = scaledviewwidth;
-
 	centerx = viewwidth/2;
 	centery = viewheight/2;
 	centerxfrac = centerx<<FRACBITS;
@@ -948,13 +952,16 @@ void R_ExecuteSetViewSize(void)
 
 	projection = projectiony = FixedDiv(centerxfrac, fovtan);
 
-	R_InitViewBuffer(scaledviewwidth, viewheight);
+	R_InitViewBuffer(viewwidth, viewheight);
 
 	R_InitTextureMapping();
 
 	// thing clipping
 	for (i = 0; i < viewwidth; i++)
+	{
+		negonearray[i] = -1;
 		screenheightarray[i] = (INT16)viewheight;
+	}
 
 	// setup sky scaling
 	R_SetSkyScale();
@@ -1023,9 +1030,6 @@ void R_Init(void)
 
 	R_SetViewSize(); // setsizeneeded is set true
 
-	//I_OutputMsg("\nR_InitPlanes");
-	R_InitPlanes();
-
 	// this is now done by SCR_Recalc() at the first mode set
 	//I_OutputMsg("\nR_InitLightTables");
 	R_InitLightTables();
diff --git a/src/r_plane.c b/src/r_plane.c
index c568484b6ed7e71335a665a40710753d2608133f..5a9218f69d5ac511dd950ae7d63a63e89b2e0abd 100644
--- a/src/r_plane.c
+++ b/src/r_plane.c
@@ -39,6 +39,7 @@
 //SoM: 3/23/2000: Use Boom visplane hashing.
 
 visplane_t *visplanes[MAXVISPLANES];
+static UINT16 numvisplanes;
 static visplane_t *freetail;
 static visplane_t **freehead = &freetail;
 
@@ -62,14 +63,14 @@ INT16 *openings, *lastopening; /// \todo free leak
 //  floorclip starts out SCREENHEIGHT
 //  ceilingclip starts out -1
 //
-INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH];
-fixed_t frontscale[MAXVIDWIDTH];
+INT16 *floorclip, *ceilingclip;
+fixed_t *frontscale;
 
 //
 // spanstart holds the start of a plane span
 // initialized to 0 at start
 //
-static INT32 spanstart[MAXVIDHEIGHT];
+static INT32 *spanstart;
 
 //
 // texture mapping
@@ -84,24 +85,75 @@ static fixed_t planeheight;
 //                (this is to calculate yslopes only when really needed)
 //                (when mouselookin', yslope is moving into yslopetab)
 //                Check R_SetupFrame, R_SetViewSize for more...
-fixed_t yslopetab[MAXVIDHEIGHT*16];
+fixed_t *yslopetab;
 fixed_t *yslope;
 
-fixed_t cachedheight[MAXVIDHEIGHT];
-fixed_t cacheddistance[MAXVIDHEIGHT];
-fixed_t cachedxstep[MAXVIDHEIGHT];
-fixed_t cachedystep[MAXVIDHEIGHT];
+fixed_t *cachedheight;
+fixed_t *cacheddistance;
+fixed_t *cachedxstep;
+fixed_t *cachedystep;
 
 static fixed_t xoffs, yoffs;
 static floatv3_t ds_slope_origin, ds_slope_u, ds_slope_v;
 
-//
-// R_InitPlanes
-// Only at game startup.
-//
-void R_InitPlanes(void)
+static INT16 *ffloor_f_clip;
+static INT16 *ffloor_c_clip;
+
+UINT16 *visplanes_top[MAXVISPLANES];
+UINT16 *visplanes_bottom[MAXVISPLANES];
+
+static void R_AllocVisplaneTables(unsigned i)
+{
+	// leave pads for [minx-1]/[maxx+1]
+	visplanes_top[i] = Z_Realloc(visplanes_top[i], sizeof(UINT16) * (viewwidth + 2), PU_STATIC, NULL);
+	visplanes_bottom[i] = Z_Realloc(visplanes_bottom[i], sizeof(UINT16) * (viewwidth + 2), PU_STATIC, NULL);
+}
+
+void R_AllocPlaneMemory(void)
 {
-	// FIXME: unused
+	// Alloc visplane top/bottom bounds
+	visplane_t *check;
+
+	for (unsigned i = 0; i < MAXVISPLANES; i++)
+	{
+		if (visplanes_top[i] || visplanes_bottom[i])
+			R_AllocVisplaneTables(i);
+
+		if ((check = visplanes[i]))
+		{
+			check->top = visplanes_top[check->id] + 1;
+			check->bottom = visplanes_bottom[check->id] + 1;
+		}
+	}
+
+	// Need to do it for "freed" visplanes too
+	check = freetail;
+
+	while (check)
+	{
+		check->top = visplanes_top[check->id] + 1;
+		check->bottom = visplanes_bottom[check->id] + 1;
+		check = check->next;
+	}
+
+	// Alloc ffloor clip tables
+	ffloor_f_clip = Z_Realloc(ffloor_f_clip, sizeof(*ffloor_f_clip) * (viewwidth * MAXFFLOORS), PU_STATIC, NULL);
+	ffloor_c_clip = Z_Realloc(ffloor_c_clip, sizeof(*ffloor_c_clip) * (viewwidth * MAXFFLOORS), PU_STATIC, NULL);
+
+	for (unsigned i = 0; i < MAXFFLOORS; i++)
+	{
+		ffloor[i].f_clip = ffloor_f_clip + (i * viewwidth);
+		ffloor[i].c_clip = ffloor_c_clip + (i * viewwidth);
+	}
+
+	yslopetab = Z_Realloc(yslopetab, sizeof(*yslopetab) * (viewheight * 16), PU_STATIC, NULL);
+
+	cachedheight = Z_Realloc(cachedheight, sizeof(*cachedheight) * viewheight, PU_STATIC, NULL);
+	cacheddistance = Z_Realloc(cacheddistance, sizeof(*cacheddistance) * viewheight, PU_STATIC, NULL);
+	cachedxstep = Z_Realloc(cachedxstep, sizeof(*cachedxstep) * viewheight, PU_STATIC, NULL);
+	cachedystep = Z_Realloc(cachedystep, sizeof(*cachedystep) * viewheight, PU_STATIC, NULL);
+
+	spanstart = Z_Realloc(spanstart, sizeof(*spanstart) * viewheight, PU_STATIC, NULL);
 }
 
 //
@@ -369,7 +421,7 @@ void R_ClearPlanes(void)
 	lastopening = openings;
 
 	// texture calculation
-	memset(cachedheight, 0, sizeof (cachedheight));
+	memset(cachedheight, 0, sizeof(*cachedheight) * viewheight);
 }
 
 static visplane_t *new_visplane(unsigned hash)
@@ -377,8 +429,10 @@ static visplane_t *new_visplane(unsigned hash)
 	visplane_t *check = freetail;
 	if (!check)
 	{
-		check = malloc(sizeof (*check));
+		check = calloc(1, sizeof (*check));
 		if (check == NULL) I_Error("%s: Out of memory", "new_visplane"); // FIXME: ugly
+		check->id = numvisplanes++;
+		R_AllocVisplaneTables(check->id);
 	}
 	else
 	{
@@ -486,8 +540,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
 	check->polyobj = polyobj;
 	check->slope = slope;
 
-	memset(check->top, 0xff, sizeof (check->top));
-	memset(check->bottom, 0x00, sizeof (check->bottom));
+	check->top = visplanes_top[check->id] + 1;
+	check->bottom = visplanes_bottom[check->id] + 1;
+
+	memset(check->top, 0xff, sizeof(*check->top) * viewwidth);
+	memset(check->bottom, 0x00, sizeof(*check->bottom) * viewwidth);
 
 	return check;
 }
@@ -542,8 +599,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
 		}
 		else
 		{
-			unsigned hash =
-				visplane_hash(pl->picnum, pl->lightlevel, pl->height);
+			unsigned hash = visplane_hash(pl->picnum, pl->lightlevel, pl->height);
 			new_pl = new_visplane(hash);
 		}
 
@@ -564,8 +620,10 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
 		pl = new_pl;
 		pl->minx = start;
 		pl->maxx = stop;
-		memset(pl->top, 0xff, sizeof pl->top);
-		memset(pl->bottom, 0x00, sizeof pl->bottom);
+		pl->top = visplanes_top[pl->id] + 1;
+		pl->bottom = visplanes_bottom[pl->id] + 1;
+		memset(pl->top, 0xff, sizeof(*pl->top) * viewwidth);
+		memset(pl->bottom, 0x00, sizeof(*pl->bottom) * viewwidth);
 	}
 	return pl;
 }
@@ -1009,7 +1067,7 @@ void R_DrawSinglePlane(visplane_t *pl)
 		// Don't mess with angle on slopes! We'll handle this ourselves later
 		if (!pl->slope && viewangle != pl->viewangle+pl->plangle)
 		{
-			memset(cachedheight, 0, sizeof (cachedheight));
+			memset(cachedheight, 0, sizeof(*cachedheight) * viewheight);
 			viewangle = pl->viewangle+pl->plangle;
 		}
 
diff --git a/src/r_plane.h b/src/r_plane.h
index 9870a43e26286e5e888a13f20fa72ecf8b38be08..0d441b3ab3adf4d298be8d0a3cdf52aeda03646e 100644
--- a/src/r_plane.h
+++ b/src/r_plane.h
@@ -31,6 +31,7 @@
 typedef struct visplane_s
 {
 	struct visplane_s *next;
+	UINT16 id;
 
 	fixed_t height;
 	fixed_t viewx, viewy, viewz;
@@ -43,9 +44,8 @@ typedef struct visplane_s
 	// colormaps per sector
 	extracolormap_t *extra_colormap;
 
-	// leave pads for [minx-1]/[maxx+1]
-	UINT16 padtopstart, top[MAXVIDWIDTH], padtopend;
-	UINT16 padbottomstart, bottom[MAXVIDWIDTH], padbottomend;
+	UINT16 *top;
+	UINT16 *bottom;
 	INT32 high, low; // R_PlaneBounds should set these.
 
 	fixed_t xoffs, yoffs; // Scrolling flats.
@@ -63,17 +63,17 @@ extern visplane_t *ceilingplane;
 extern INT16 *lastopening, *openings;
 extern size_t maxopenings;
 
-extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH];
-extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16];
-extern fixed_t cachedheight[MAXVIDHEIGHT];
-extern fixed_t cacheddistance[MAXVIDHEIGHT];
-extern fixed_t cachedxstep[MAXVIDHEIGHT];
-extern fixed_t cachedystep[MAXVIDHEIGHT];
+extern INT16 *floorclip, *ceilingclip;
+extern fixed_t *frontscale, *yslopetab;
+extern fixed_t *cachedheight;
+extern fixed_t *cacheddistance;
+extern fixed_t *cachedxstep;
+extern fixed_t *cachedystep;
 
 extern fixed_t *yslope;
 extern lighttable_t **planezlight;
 
-void R_InitPlanes(void);
+void R_AllocPlaneMemory(void);
 void R_ClearPlanes(void);
 void R_ClearFFloorClips (void);
 
@@ -103,8 +103,8 @@ typedef struct planemgr_s
 	fixed_t b_pos; // B for Back sector
 	fixed_t f_frac, f_step;
 	fixed_t b_frac, b_step;
-	INT16 f_clip[MAXVIDWIDTH];
-	INT16 c_clip[MAXVIDWIDTH];
+	INT16 *f_clip;
+	INT16 *c_clip;
 
 	// For slope rendering; the height at the other end
 	fixed_t f_pos_slope;
diff --git a/src/r_segs.c b/src/r_segs.c
index facab62ab76479faeaabccc5a4f14a64446db40b..a11ee83e35ed2d6d18f3250a6ef480e51a0e3f81 100644
--- a/src/r_segs.c
+++ b/src/r_segs.c
@@ -1512,6 +1512,33 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2)
 	}
 }
 
+static size_t maxdrawsegs = 0;
+
+static fixed_t *frontscaletable = NULL;
+static fixed_t *maskedheighttable = NULL;
+
+void R_AllocSegMemory(void)
+{
+	if (!maxdrawsegs)
+		return;
+
+	frontscaletable = Z_Realloc(frontscaletable, sizeof(*frontscaletable) * (maxdrawsegs * viewwidth), PU_STATIC, NULL);
+	maskedheighttable = Z_Realloc(maskedheighttable, sizeof(*maskedheighttable) * (maxdrawsegs * viewwidth), PU_STATIC, NULL);
+
+	drawseg_t *lastseg = drawsegs + maxdrawsegs;
+
+	fixed_t *frontscale_p = frontscaletable;
+	fixed_t *maskedheight_p = maskedheighttable;
+
+	for (drawseg_t *ds = drawsegs; ds < lastseg; ds++)
+	{
+		ds->frontscale = frontscale_p;
+		ds->maskedtextureheight = maskedheight_p;
+		frontscale_p += viewwidth;
+		maskedheight_p += viewwidth;
+	}
+}
+
 //
 // R_StoreWallRange
 // A wall segment will be drawn
@@ -1530,7 +1557,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 	INT32 range;
 	vertex_t segleft, segright;
 	fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide;
-	static size_t maxdrawsegs = 0;
 
 	maskedtextureheight = NULL;
 	//initialize segleft and segright
@@ -1552,6 +1578,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 		curdrawsegs = drawsegs + curpos;
 		if (firstseg)
 			firstseg = drawsegs + (size_t)firstseg;
+		R_AllocSegMemory();
 	}
 
 	sidedef = curline->sidedef;
diff --git a/src/r_segs.h b/src/r_segs.h
index 09c68b27e95eb34deb1302762d9d8a50e72e44dc..5c1fbed8b069e19e907013da197a3bdbdee61dd6 100644
--- a/src/r_segs.h
+++ b/src/r_segs.h
@@ -18,9 +18,12 @@
 #pragma interface
 #endif
 
-transnum_t R_GetLinedefTransTable(fixed_t alpha);
 void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
 void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
 void R_StoreWallRange(INT32 start, INT32 stop);
 
+void R_AllocSegMemory(void);
+
+transnum_t R_GetLinedefTransTable(fixed_t alpha);
+
 #endif
diff --git a/src/r_splats.c b/src/r_splats.c
index d182d628ba8fc09ab3d8e898a339f29b3b2d92cb..aa5917e0f0d20cc6ef8965feec11c649b11b0d1e 100644
--- a/src/r_splats.c
+++ b/src/r_splats.c
@@ -22,9 +22,17 @@
 
 struct rastery_s *prastertab; // for ASM code
 
-static struct rastery_s rastertab[MAXVIDHEIGHT];
+static struct rastery_s *rastertab;
 static void prepare_rastertab(void);
 
+static boolean *cliptable;
+
+void R_AllocFloorSpriteTables(void)
+{
+	cliptable = Z_Realloc(cliptable, sizeof(*cliptable) * (viewwidth + 1), PU_STATIC, NULL);
+	rastertab = Z_Realloc(rastertab, sizeof(*rastertab) * viewheight, PU_STATIC, NULL);
+}
+
 // ==========================================================================
 //                                                               FLOOR SPLATS
 // ==========================================================================
@@ -412,7 +420,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
 
 		if (pSplat->angle)
 		{
-			memset(cachedheight, 0, sizeof(cachedheight));
+			memset(cachedheight, 0, sizeof(*cachedheight) * viewheight);
 
 			// Add the view offset, rotated by the plane angle.
 			fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x;
@@ -463,8 +471,6 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
 
 	for (y = miny; y <= maxy; y++)
 	{
-		boolean cliptab[MAXVIDWIDTH+1];
-
 		x1 = rastertab[y].minx>>FRACBITS;
 		x2 = rastertab[y].maxx>>FRACBITS;
 
@@ -487,10 +493,10 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
 			continue;
 
 		for (i = x1; i <= x2; i++)
-			cliptab[i] = (y >= mfloorclip[i] || y <= mceilingclip[i]);
+			cliptable[i] = (y >= mfloorclip[i] || y <= mceilingclip[i]);
 
 		// clip left
-		while (cliptab[x1])
+		while (cliptable[x1])
 		{
 			x1++;
 			if (x1 >= viewwidth)
@@ -502,7 +508,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
 
 		while (i > x1)
 		{
-			if (cliptab[i])
+			if (cliptable[i])
 				x2 = i-1;
 			i--;
 			if (i < 0)
@@ -562,7 +568,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
 	}
 
 	if (pSplat->angle && !pSplat->slope)
-		memset(cachedheight, 0, sizeof(cachedheight));
+		memset(cachedheight, 0, sizeof(*cachedheight) * viewheight);
 }
 
 static void prepare_rastertab(void)
diff --git a/src/r_splats.h b/src/r_splats.h
index dcae2789c9ec463ad2990dea3e3a8a4926ac529e..344380cd43cded8411abc9506d070304b67fd2e8 100644
--- a/src/r_splats.h
+++ b/src/r_splats.h
@@ -43,4 +43,6 @@ typedef struct floorsplat_s
 
 void R_DrawFloorSplat(vissprite_t *spr);
 
+void R_AllocFloorSpriteTables(void);
+
 #endif /*__R_SPLATS_H__*/
diff --git a/src/r_state.h b/src/r_state.h
index b36697f73cfa6cb0967c97d081c6020651589b7f..1868fde79234eda82c42970001f031e3fdaa3435 100644
--- a/src/r_state.h
+++ b/src/r_state.h
@@ -97,7 +97,7 @@ extern angle_t clipangle;
 extern angle_t doubleclipangle;
 
 extern INT32 viewangletox[FINEANGLES/2];
-extern angle_t xtoviewangle[MAXVIDWIDTH+1];
+extern angle_t *xtoviewangle;
 
 extern fixed_t rw_distance;
 extern angle_t rw_normalangle;
diff --git a/src/r_things.c b/src/r_things.c
index 248357e11fb0dc54f7c727cc75d01616dfb42d63..3423396c3731d7ed92548a04bae22f43ac65793c 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -63,8 +63,8 @@ typedef struct
 static lighttable_t **spritelights;
 
 // constant arrays used for psprite clipping and initializing clipping
-INT16 negonearray[MAXVIDWIDTH];
-INT16 screenheightarray[MAXVIDWIDTH];
+INT16 *negonearray;
+INT16 *screenheightarray;
 
 spriteinfo_t spriteinfo[NUMSPRITES];
 
@@ -513,9 +513,6 @@ void R_InitSprites(void)
 	float fa;
 #endif
 
-	for (i = 0; i < MAXVIDWIDTH; i++)
-		negonearray[i] = -1;
-
 #ifdef ROTSPRITE
 	for (angle = 1; angle < ROTANGLES; angle++)
 	{
@@ -574,6 +571,34 @@ void R_ClearSprites(void)
 	visspritecount = clippedvissprites = 0;
 }
 
+static INT16 *vissprite_clipbot[MAXVISSPRITES >> VISSPRITECHUNKBITS];
+static INT16 *vissprite_cliptop[MAXVISSPRITES >> VISSPRITECHUNKBITS];
+
+static void R_AllocVisSpriteChunkMemory(UINT32 chunk)
+{
+	vissprite_clipbot[chunk] = Z_Realloc(vissprite_clipbot[chunk], sizeof(INT16) * (VISSPRITESPERCHUNK * viewwidth), PU_STATIC, NULL);
+	vissprite_cliptop[chunk] = Z_Realloc(vissprite_cliptop[chunk], sizeof(INT16) * (VISSPRITESPERCHUNK * viewwidth), PU_STATIC, NULL);
+
+	for (unsigned i = 0; i < VISSPRITESPERCHUNK; i++)
+	{
+		vissprite_t *sprite = visspritechunks[chunk] + i;
+
+		sprite->clipbot = vissprite_clipbot[chunk] + (viewwidth * i);
+		sprite->cliptop = vissprite_cliptop[chunk] + (viewwidth * i);
+	}
+}
+
+void R_AllocVisSpriteMemory(void)
+{
+	unsigned numchunks = MAXVISSPRITES >> VISSPRITECHUNKBITS;
+
+	for (unsigned i = 0; i < numchunks; i++)
+	{
+		if (visspritechunks[i])
+			R_AllocVisSpriteChunkMemory(i);
+	}
+}
+
 //
 // R_NewVisSprite
 //
@@ -581,13 +606,16 @@ static vissprite_t overflowsprite;
 
 static vissprite_t *R_GetVisSprite(UINT32 num)
 {
-		UINT32 chunk = num >> VISSPRITECHUNKBITS;
+	UINT32 chunk = num >> VISSPRITECHUNKBITS;
 
-		// Allocate chunk if necessary
-		if (!visspritechunks[chunk])
-			Z_Malloc(sizeof(vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &visspritechunks[chunk]);
+	// Allocate chunk if necessary
+	if (!visspritechunks[chunk])
+	{
+		Z_Malloc(sizeof(vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &visspritechunks[chunk]);
+		R_AllocVisSpriteChunkMemory(chunk);
+	}
 
-		return visspritechunks[chunk] + (num & VISSPRITEINDEXMASK);
+	return visspritechunks[chunk] + (num & VISSPRITEINDEXMASK);
 }
 
 static vissprite_t *R_NewVisSprite(void)
diff --git a/src/r_things.h b/src/r_things.h
index bb8a1e97b024e5b2cb749d71b46ef2eff785460b..18e0113ef413f62b286e96c6346744ff9721f196 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -56,8 +56,8 @@ void R_DrawFlippedMaskedColumn(column_t *column);
 
 // Constant arrays used for psprite clipping
 //  and initializing clipping.
-extern INT16 negonearray[MAXVIDWIDTH];
-extern INT16 screenheightarray[MAXVIDWIDTH];
+extern INT16 *negonearray;
+extern INT16 *screenheightarray;
 
 fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
 
@@ -214,7 +214,7 @@ typedef struct vissprite_s
 
 	skincolornum_t color;
 
-	INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH];
+	INT16 *clipbot, *cliptop;
 
 	INT32 dispoffset; // copy of mobj->dispoffset, affects ordering but not drawing
 } vissprite_t;
@@ -224,6 +224,8 @@ extern UINT32 visspritecount;
 void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
 void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal);
 
+void R_AllocVisSpriteMemory(void);
+
 boolean R_SpriteIsFlashing(vissprite_t *vis);
 
 void R_DrawThingBoundingBox(vissprite_t *spr);