diff --git a/src/r_segs.c b/src/r_segs.c
index 11b4c8aefd7b031755478bfd99bc661b0b35de0b..931b79a66ef8fb869c2c81dfa18e7f5e0c1e59b8 100644
--- a/src/r_segs.c
+++ b/src/r_segs.c
@@ -1453,34 +1453,45 @@ static void R_RenderSegLoop (void)
 		frontscale[rw_x] = rw_scale;
 
 		// draw the wall tiers
-		if (midtexture && yl <= yh && yh < vid.height && yh > 0)
+		if (midtexture)
 		{
 			// single sided line
-			dc_yl = yl;
-			dc_yh = yh;
-			dc_texturemid = rw_midtexturemid;
-			dc_source = R_GetColumn(midtexture,texturecolumn);
-			dc_texheight = textureheight[midtexture]>>FRACBITS;
+			if (yl <= yh && yh >= 0 && yl < viewheight)
+			{
+				dc_yl = yl;
+				dc_yh = yh;
+				dc_texturemid = rw_midtexturemid;
+				dc_source = R_GetColumn(midtexture,texturecolumn);
+				dc_texheight = textureheight[midtexture]>>FRACBITS;
 
-			//profile stuff ---------------------------------------------------------
+				//profile stuff ---------------------------------------------------------
 #ifdef TIMING
-			ProfZeroTimer();
+				ProfZeroTimer();
 #endif
-			colfunc();
+				colfunc();
 #ifdef TIMING
-			RDMSR(0x10,&mycount);
-			mytotal += mycount;      //64bit add
+				RDMSR(0x10,&mycount);
+				mytotal += mycount;      //64bit add
 
-			if (nombre--==0)
-				I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1),
-					(INT32)mytotal);
+				if (nombre--==0)
+					I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1),
+						(INT32)mytotal);
 #endif
-			//profile stuff ---------------------------------------------------------
+				//profile stuff ---------------------------------------------------------
 
-			// dont draw anything more for this column, since
-			// a midtexture blocks the view
-			ceilingclip[rw_x] = (INT16)viewheight;
-			floorclip[rw_x] = -1;
+				// dont draw anything more for this column, since
+				// a midtexture blocks the view
+				ceilingclip[rw_x] = (INT16)viewheight;
+				floorclip[rw_x] = -1;
+			}
+			else
+			{
+				// note: don't use min/max macros here
+				if (markceiling && yl >= 0)
+					ceilingclip[rw_x] = (yl-1 > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1);
+				if (markfloor && yh < viewheight)
+					floorclip[rw_x] = (yh < -1) ? -1 : (INT16)((INT16)yh + 1);
+			}
 		}
 		else
 		{
@@ -1494,21 +1505,27 @@ static void R_RenderSegLoop (void)
 				if (mid >= floorclip[rw_x])
 					mid = floorclip[rw_x]-1;
 
-				if (mid >= yl && yh < vid.height && yh > 0)
+				if (yl < 0)
+					; // do nothing, off-screen
+				else if (mid >= yl && yl < viewheight)
 				{
-					dc_yl = yl;
-					dc_yh = mid;
-					dc_texturemid = rw_toptexturemid;
-					dc_source = R_GetColumn(toptexture,texturecolumn);
-					dc_texheight = textureheight[toptexture]>>FRACBITS;
-					colfunc();
-					ceilingclip[rw_x] = (INT16)mid;
+					if (mid >= 0)
+					{
+						dc_yl = yl;
+						dc_yh = mid;
+						dc_texturemid = rw_toptexturemid;
+						dc_source = R_GetColumn(toptexture,texturecolumn);
+						dc_texheight = textureheight[toptexture]>>FRACBITS;
+						colfunc();
+						ceilingclip[rw_x] = (INT16)mid;
+					}
+					// else do nothing, off-screen
 				}
 				else
-					ceilingclip[rw_x] = (INT16)((INT16)yl - 1);
+					ceilingclip[rw_x] = (yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1);
 			}
-			else if (markceiling) // no top wall
-				ceilingclip[rw_x] = (INT16)((INT16)yl - 1);
+			else if (markceiling && yl >= 0) // no top wall
+				ceilingclip[rw_x] = (yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1);
 
 			if (bottomtexture)
 			{
@@ -1520,24 +1537,33 @@ static void R_RenderSegLoop (void)
 				if (mid <= ceilingclip[rw_x])
 					mid = ceilingclip[rw_x]+1;
 
-				if (mid <= yh && yh < vid.height && yh > 0)
+				if (yh >= viewheight)
+					; // do nothing, off-screen
+				else if (mid <= yh && yh >= 0)
 				{
-					dc_yl = mid;
-					dc_yh = yh;
-					dc_texturemid = rw_bottomtexturemid;
-					dc_source = R_GetColumn(bottomtexture,
-						texturecolumn);
-					dc_texheight = textureheight[bottomtexture]>>FRACBITS;
-					colfunc();
-					floorclip[rw_x] = (INT16)mid;
+					if (mid < viewheight)
+					{
+						dc_yl = mid;
+						dc_yh = yh;
+						dc_texturemid = rw_bottomtexturemid;
+						dc_source = R_GetColumn(bottomtexture,
+							texturecolumn);
+						dc_texheight = textureheight[bottomtexture]>>FRACBITS;
+						colfunc();
+						floorclip[rw_x] = (INT16)mid;
+					}
+					// else do nothing, off-screen
 				}
 				else
-					floorclip[rw_x] = (INT16)((INT16)yh + 1);
+					floorclip[rw_x] = (yh < -1) ? -1 : (INT16)((INT16)yh + 1);
 			}
-			else if (markfloor) // no bottom wall
-				floorclip[rw_x] = (INT16)((INT16)yh + 1);
+			else if (markfloor && yh < viewheight) // no bottom wall
+				floorclip[rw_x] = (yh < -1) ? -1 : (INT16)((INT16)yh + 1), -1;
 		}
 
+		if (floorclip[rw_x] > viewheight)
+			I_Error("floorclip[%d] > viewheight (value is %d)", rw_x, floorclip[rw_x]);
+
 		if (maskedtexture || numthicksides)
 		{
 			// save texturecol