diff --git a/src/v_video.c b/src/v_video.c
index 1fb10fb5d8db8eec1d5c00a542306fc9751ac847..64bb3214e0de5aa06fce57c08b4385e2dc2ca6c0 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -758,79 +758,80 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
 {
 	UINT8 *dest;
 	const UINT8 *deststop;
-	INT32 u, v, dupx, dupy;
+
+	if (rendermode == render_none)
+		return;
 
 #ifdef HWRENDER
-	if (rendermode != render_soft && rendermode != render_none)
+	if (rendermode != render_soft && !con_startup)
 	{
 		HWR_DrawFill(x, y, w, h, c);
 		return;
 	}
 #endif
 
-	dupx = vid.dupx;
-	dupy = vid.dupy;
-
-	if (!screens[0])
-		return;
-
-	if (c & V_NOSCALESTART)
-	{
-		dest = screens[0] + y*vid.width + x;
-		deststop = screens[0] + vid.rowbytes * vid.height;
-	}
-	else
+	if (!(c & V_NOSCALESTART))
 	{
+		INT32 dupx = vid.dupx, dupy = vid.dupy;
+
 		if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
 		{ // Clear the entire screen, from dest to deststop. Yes, this really works.
 			memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp);
 			return;
 		}
 
-		dest = screens[0] + y*dupy*vid.width + x*dupx;
-		deststop = screens[0] + vid.rowbytes * vid.height;
+		x *= dupx;
+		y *= dupy;
+		w *= dupx;
+		h *= dupy;
 
-		if (w == BASEVIDWIDTH)
-			w = vid.width;
-		else
-			w *= dupx;
-		if (h == BASEVIDHEIGHT)
-			h = vid.height;
-		else
-			h *= dupy;
-
-		if (x && y && x + w < vid.width && y + h < vid.height)
+		// Center it if necessary
+		if (vid.width != BASEVIDWIDTH * dupx)
 		{
-			// Center it if necessary
-			if (vid.width != BASEVIDWIDTH * dupx)
-			{
-				// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
-				// so center this imaginary screen
-				if (c & V_SNAPTORIGHT)
-					dest += (vid.width - (BASEVIDWIDTH * dupx));
-				else if (!(c & V_SNAPTOLEFT))
-					dest += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
-			}
-			if (vid.height != BASEVIDHEIGHT * dupy)
-			{
-				// same thing here
-				if (c & V_SNAPTOBOTTOM)
-					dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width;
-				else if (!(c & V_SNAPTOTOP))
-					dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2;
-			}
+			// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
+			// so center this imaginary screen
+			if (c & V_SNAPTORIGHT)
+				x += (vid.width - (BASEVIDWIDTH * dupx));
+			else if (!(c & V_SNAPTOLEFT))
+				x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
 		}
+		if (vid.height != BASEVIDHEIGHT * dupy)
+		{
+			// same thing here
+			if (c & V_SNAPTOBOTTOM)
+				y += (vid.height - (BASEVIDHEIGHT * dupy));
+			else if (!(c & V_SNAPTOTOP))
+				y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
+		}
+	}
+
+	if (x >= vid.width || y >= vid.height)
+		return; // off the screen
+	if (x < 0)
+	{
+		w += x;
+		x = 0;
 	}
+	if (y < 0)
+	{
+		h += y;
+		y = 0;
+	}
+
+	if (w <= 0 || h <= 0)
+		return; // zero width/height wouldn't draw anything
+	if (x + w > vid.width)
+		w = vid.width - x;
+	if (y + h > vid.height)
+		h = vid.height - y;
+
+	dest = screens[0] + y*vid.width + x;
+	deststop = screens[0] + vid.rowbytes * vid.height;
 
 	c &= 255;
 
-	for (v = 0; v < h; v++, dest += vid.width)
-		for (u = 0; u < w; u++)
-		{
-			if (dest > deststop)
-				return;
-			dest[u] = (UINT8)c;
-		}
+	for (;(--h >= 0) && dest < deststop; dest += vid.width)
+		memset(dest, (UINT8)(c&255), w * vid.bpp);
 }
 
 //