From 9fb9f7ec19abcbd8caa7b2c61a0c990d03d674a3 Mon Sep 17 00:00:00 2001
From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Wed, 30 Jan 2008 07:18:56 +0000
Subject: [PATCH] fixed -tenebrae support, added glass and mirror rendering and
 caulk

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8052 d7cf8633-e32d-0410-b094-e92efae38249
---
 gl_rmain.c    | 28 +++++++++++++++++-----------
 image.c       |  4 ++++
 model_brush.c | 28 +++++++++++++++++++++++-----
 progdefs.h    |  1 +
 progsvm.h     |  1 +
 prvm_edict.c  |  4 ++--
 sv_main.c     |  1 +
 7 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/gl_rmain.c b/gl_rmain.c
index 87ceb656..1df9f491 100644
--- a/gl_rmain.c
+++ b/gl_rmain.c
@@ -2926,6 +2926,7 @@ static void R_Water_AddWaterPlane(msurface_t *surface)
 	vec3_t vert[3];
 	vec3_t normal;
 	vec3_t center;
+	mplane_t plane;
 	r_waterstate_waterplane_t *p;
 	// just use the first triangle with a valid normal for any decisions
 	VectorClear(normal);
@@ -2939,6 +2940,21 @@ static void R_Water_AddWaterPlane(msurface_t *surface)
 			break;
 	}
 
+	VectorCopy(normal, plane.normal);
+	VectorNormalize(plane.normal);
+	plane.dist = DotProduct(vert[0], plane.normal);
+	PlaneClassify(&plane);
+	if (PlaneDiff(r_refdef.view.origin, &plane) < 0)
+	{
+		// skip backfaces (except if nocullface is set)
+		if (!(surface->texture->currentframe->currentmaterialflags & MATERIALFLAG_NOCULLFACE))
+			return;
+		VectorNegate(plane.normal, plane.normal);
+		plane.dist *= -1;
+		PlaneClassify(&plane);
+	}
+
+
 	// find a matching plane if there is one
 	for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
 		if (fabs(PlaneDiff(vert[0], &p->plane)) < 1 && fabs(PlaneDiff(vert[1], &p->plane)) < 1 && fabs(PlaneDiff(vert[2], &p->plane)) < 1)
@@ -2951,17 +2967,7 @@ static void R_Water_AddWaterPlane(msurface_t *surface)
 	{
 		// store the new plane
 		r_waterstate.numwaterplanes++;
-		VectorCopy(normal, p->plane.normal);
-		VectorNormalize(p->plane.normal);
-		p->plane.dist = DotProduct(vert[0], p->plane.normal);
-		PlaneClassify(&p->plane);
-		// flip the plane if it does not face the viewer
-		if (PlaneDiff(r_refdef.view.origin, &p->plane) < 0)
-		{
-			VectorNegate(p->plane.normal, p->plane.normal);
-			p->plane.dist *= -1;
-			PlaneClassify(&p->plane);
-		}
+		p->plane = plane;
 		// clear materialflags and pvs
 		p->materialflags = 0;
 		p->pvsvalid = false;
diff --git a/image.c b/image.c
index 2146a647..5ff4076e 100644
--- a/image.c
+++ b/image.c
@@ -703,6 +703,10 @@ imageformat_t imageformats_tenebrae[] =
 	{"override/%s.png", PNG_LoadImage_BGRA},
 	{"override/%s.jpg", JPEG_LoadImage_BGRA},
 	{"override/%s.pcx", LoadPCX_BGRA},
+	{"%s.tga", LoadTGA_BGRA},
+	{"%s.png", PNG_LoadImage_BGRA},
+	{"%s.jpg", JPEG_LoadImage_BGRA},
+	{"%s.pcx", LoadPCX_BGRA},
 	{NULL, NULL}
 };
 
diff --git a/model_brush.c b/model_brush.c
index 3278bcd4..12ae4d6f 100644
--- a/model_brush.c
+++ b/model_brush.c
@@ -1317,6 +1317,9 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
 	unsigned char *data, *mtdata;
 	const char *s;
 	char mapname[MAX_QPATH], name[MAX_QPATH];
+	unsigned char zero[4];
+
+	memset(zero, 0, sizeof(zero));
 
 	loadmodel->data_textures = NULL;
 
@@ -1533,14 +1536,29 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
 			if (tx->name[0] == '*')
 			{
 				// LordHavoc: some turbulent textures should not be affected by wateralpha
-				if (strncmp(tx->name,"*lava",5)
-				 && strncmp(tx->name,"*teleport",9)
-				 && strncmp(tx->name,"*rift",5)) // Scourge of Armagon texture
-					tx->basematerialflags |= MATERIALFLAG_WATERALPHA | MATERIALFLAG_NOSHADOW | MATERIALFLAG_WATERSHADER;
-				tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW;
+				if (!strncmp(tx->name, "*glassmirror", 12)) // Tenebrae
+				{
+					// replace the texture with transparent black
+					tx->skinframes[0] = R_SkinFrame_LoadInternalBGRA(tx->name, TEXF_MIPMAP | TEXF_PRECACHE, zero, 1, 1);
+					tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_NOSHADOW | MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_REFLECTION;
+				}
+				else if (!strncmp(tx->name,"*lava",5)
+				 || !strncmp(tx->name,"*teleport",9)
+				 || !strncmp(tx->name,"*rift",5)) // Scourge of Armagon texture
+					tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW;
+				else
+					tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW | MATERIALFLAG_WATERALPHA | MATERIALFLAG_WATERSHADER;
+			}
+			else if (!strncmp(tx->name, "mirror", 6)) // Tenebrae
+			{
+				// replace the texture with transparent black
+				tx->skinframes[0] = R_SkinFrame_LoadInternalBGRA(tx->name, TEXF_PRECACHE, zero, 1, 1);
+				tx->basematerialflags |= MATERIALFLAG_WALL | MATERIALFLAG_REFLECTION;
 			}
 			else if (!strncmp(tx->name, "sky", 3))
 				tx->basematerialflags |= MATERIALFLAG_SKY | MATERIALFLAG_NOSHADOW;
+			else if (!strcmp(tx->name, "caulk"))
+				tx->basematerialflags = MATERIALFLAG_NODRAW;
 			else
 				tx->basematerialflags |= MATERIALFLAG_WALL;
 			if (tx->skinframes[0] && tx->skinframes[0]->fog)
diff --git a/progdefs.h b/progdefs.h
index 15db5488..7086dbdc 100644
--- a/progdefs.h
+++ b/progdefs.h
@@ -164,6 +164,7 @@ typedef struct entvars_s
 } entvars_t;
 
 #define PROGHEADER_CRC 5927
+#define PROGHEADER_CRC_TENEBRAE 32401
 
 #endif
 
diff --git a/progsvm.h b/progsvm.h
index 2033411b..3a6028b1 100644
--- a/progsvm.h
+++ b/progsvm.h
@@ -354,6 +354,7 @@ typedef struct prvm_prog_s
 	int					localstack_used;
 
 	unsigned short		headercrc; // [INIT]
+	unsigned short		headercrc2; // [INIT] alternate CRC for tenebrae progs.dat
 
 	unsigned short		filecrc;
 
diff --git a/prvm_edict.c b/prvm_edict.c
index 092f560f..9e85cfc7 100644
--- a/prvm_edict.c
+++ b/prvm_edict.c
@@ -1590,8 +1590,8 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
 
 	if (prog->progs->version != PROG_VERSION)
 		PRVM_ERROR ("%s: %s has wrong version number (%i should be %i)", PRVM_NAME, filename, prog->progs->version, PROG_VERSION);
-	if (prog->progs->crc != prog->headercrc)
-		PRVM_ERROR ("%s: %s system vars have been modified, progdefs.h is out of date", PRVM_NAME, filename);
+	if (prog->progs->crc != prog->headercrc && prog->progs->crc != prog->headercrc2)
+		PRVM_ERROR ("%s: %s system vars have been modified (CRC of progs.dat systemvars %i != engine %i), progdefs.h is out of date", PRVM_NAME, filename, prog->progs->crc, prog->headercrc);
 
 	//prog->functions = (dfunction_t *)((unsigned char *)progs + progs->ofs_functions);
 	dfunctions = (dfunction_t *)((unsigned char *)prog->progs + prog->progs->ofs_functions);
diff --git a/sv_main.c b/sv_main.c
index a15f914c..72a9d326 100644
--- a/sv_main.c
+++ b/sv_main.c
@@ -2867,6 +2867,7 @@ static void SV_VM_Setup(void)
 	prog->builtins = vm_sv_builtins;
 	prog->numbuiltins = vm_sv_numbuiltins;
 	prog->headercrc = PROGHEADER_CRC;
+	prog->headercrc2 = PROGHEADER_CRC_TENEBRAE;
 	prog->max_edicts = 512;
 	if (sv.protocol == PROTOCOL_QUAKE)
 		prog->limit_edicts = 640; // before quake mission pack 1 this was 512
-- 
2.39.5