From c528aa06154e34f8cce26e335f556beaaf4324cb Mon Sep 17 00:00:00 2001
From: divverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Sat, 27 Aug 2011 18:52:13 +0000
Subject: [PATCH] fix cachepic handling with respect to r_restart and
 Draw_NewPic

Some forgotten memsets, and attempts to free the notexture, could wreak havoc

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11303 d7cf8633-e32d-0410-b094-e92efae38249
::stable-branch::merge=670bb7badcf717f7c3c50345d79754c77fa443bf
---
 draw.h    |  2 ++
 gl_draw.c | 33 ++++++++++++++++++++-------------
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/draw.h b/draw.h
index c7f1bc27..5cb62afa 100644
--- a/draw.h
+++ b/draw.h
@@ -45,6 +45,8 @@ typedef struct cachepic_s
 	qboolean hasalpha;
 	// name of pic
 	char name[MAX_QPATH];
+	// allow to override/free the texture
+	qboolean allow_free_tex;
 }
 cachepic_t;
 
diff --git a/gl_draw.c b/gl_draw.c
index aa6a0c38..86976c85 100644
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -361,23 +361,31 @@ cachepic_t *Draw_CachePic_Flags(const char *path, unsigned int cachepicflags)
 		return cachepics; // return the first one
 	}
 	pic = cachepics + (numcachepics++);
+	memset(pic, 0, sizeof(*pic));
 	strlcpy (pic->name, path, sizeof(pic->name));
 	// link into list
 	pic->chain = cachepichash[hashkey];
 	cachepichash[hashkey] = pic;
 
 reload:
+	// TODO why does this crash?
+	if(pic->allow_free_tex && pic->tex)
+		R_PurgeTexture(pic->tex);
+
 	// check whether it is an dynamic texture (if so, we can directly use its texture handler)
 	pic->flags = cachepicflags;
 	pic->tex = CL_GetDynTexture( path );
 	// if so, set the width/height, too
 	if( pic->tex ) {
+		pic->allow_free_tex = false;
 		pic->width = R_TextureWidth(pic->tex);
 		pic->height = R_TextureHeight(pic->tex);
 		// we're done now (early-out)
 		return pic;
 	}
 
+	pic->allow_free_tex = true;
+
 	pic->hasalpha = true; // assume alpha unless we know it has none
 	pic->texflags = texflags;
 	pic->autoload = (cachepicflags & CACHEPICFLAG_NOTPERSISTENT);
@@ -490,6 +498,7 @@ reload:
 		pic->tex = draw_generatepic(pic->name, (cachepicflags & CACHEPICFLAG_QUIET) != 0);
 		pic->width = R_TextureWidth(pic->tex);
 		pic->height = R_TextureHeight(pic->tex);
+		pic->allow_free_tex = (pic->tex != r_texture_notexture);
 	}
 
 	return pic;
@@ -573,26 +582,24 @@ cachepic_t *Draw_NewPic(const char *picname, int width, int height, int alpha, u
 	}
 	else
 	{
-		if (pic == NULL)
+		if (numcachepics == MAX_CACHED_PICS)
 		{
-			if (numcachepics == MAX_CACHED_PICS)
-			{
-				Con_Printf ("Draw_NewPic: numcachepics == MAX_CACHED_PICS\n");
-				// FIXME: support NULL in callers?
-				return cachepics; // return the first one
-			}
-			pic = cachepics + (numcachepics++);
-			strlcpy (pic->name, picname, sizeof(pic->name));
-			// link into list
-			pic->chain = cachepichash[hashkey];
-			cachepichash[hashkey] = pic;
+			Con_Printf ("Draw_NewPic: numcachepics == MAX_CACHED_PICS\n");
+			// FIXME: support NULL in callers?
+			return cachepics; // return the first one
 		}
+		pic = cachepics + (numcachepics++);
+		memset(pic, 0, sizeof(*pic));
+		strlcpy (pic->name, picname, sizeof(pic->name));
+		// link into list
+		pic->chain = cachepichash[hashkey];
+		cachepichash[hashkey] = pic;
 	}
 
 	pic->flags = CACHEPICFLAG_NEWPIC; // disable texflags checks in Draw_CachePic
 	pic->width = width;
 	pic->height = height;
-	if (pic->tex)
+	if (pic->allow_free_tex && pic->tex)
 		R_FreeTexture(pic->tex);
 	pic->tex = R_LoadTexture2D(drawtexturepool, picname, width, height, pixels_bgra, TEXTYPE_BGRA, (alpha ? TEXF_ALPHA : 0), -1, NULL);
 	return pic;
-- 
2.39.5