From bf88407d00858d2523e41dda5d24cc8485a659b8 Mon Sep 17 00:00:00 2001
From: Monster Iestyn <iestynjealous@ntlworld.com>
Date: Fri, 9 Feb 2018 17:23:35 +0000
Subject: [PATCH] Make sure both software and OpenGL ignore patches that are
 completely out of a multi-patch texture's bounds.

This fixes OpenGL in particular crashing because of such a weird situation.
---
 src/hardware/hw_cache.c | 16 ++++++++++++++--
 src/r_data.c            | 11 +++++++++++
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c
index 78fc31afcc..919bbb31cd 100644
--- a/src/hardware/hw_cache.c
+++ b/src/hardware/hw_cache.c
@@ -62,19 +62,31 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
 	UINT8 texel;
 	UINT16 texelu16;
 
+	if (!ptexturewidth)
+		return;
+
 	x1 = originx;
 	x2 = x1 + SHORT(realpatch->width);
 
+	if (x1 > ptexturewidth || x2 < 0)
+		return; // patch not located within texture's x bounds, ignore
+
+	if (originy > ptextureheight || (originy + SHORT(realpatch->height)) < 0)
+		return; // patch not located within texture's y bounds, ignore
+
+	// patch is actually inside the texture!
+	// now check if texture is partly off-screen and adjust accordingly
+
+	// left edge
 	if (x1 < 0)
 		x = 0;
 	else
 		x = x1;
 
+	// right edge
 	if (x2 > ptexturewidth)
 		x2 = ptexturewidth;
 
-	if (!ptexturewidth)
-		return;
 
 	col = x * pblockwidth / ptexturewidth;
 	ncols = ((x2 - x) * pblockwidth) / ptexturewidth;
diff --git a/src/r_data.c b/src/r_data.c
index c4209fad60..169b042015 100644
--- a/src/r_data.c
+++ b/src/r_data.c
@@ -439,11 +439,22 @@ static UINT8 *R_GenerateTexture(size_t texnum)
 		height = SHORT(realpatch->height);
 		x2 = x1 + width;
 
+		if (x1 > texture->width || x2 < 0)
+			continue; // patch not located within texture's x bounds, ignore
+
+		if (patch->originy > texture->height || (patch->originy + height) < 0)
+			continue; // patch not located within texture's y bounds, ignore
+
+		// patch is actually inside the texture!
+		// now check if texture is partly off-screen and adjust accordingly
+
+		// left edge
 		if (x1 < 0)
 			x = 0;
 		else
 			x = x1;
 
+		// right edge
 		if (x2 > texture->width)
 			x2 = texture->width;
 
-- 
GitLab