From 8232dbca10181c56a73247cac2464af4465c5481 Mon Sep 17 00:00:00 2001
From: MonsterIestyn <iestynjealous@ntlworld.com>
Date: Fri, 2 Jan 2015 15:14:22 +0000
Subject: [PATCH] *Fixed OpenGL's handling of cv_translucency effects (should
 not remove shadows if off, but perhaps make them use default alpha?), someone
 was a bit hasty! *De-stupified the MD2 status checks regarding drawing of
 sprites - if they're already checked before calling HWR_DrawSprite, there's
 no point doing them WITHIN the function as well *Split off sprite shadow code
 into HWR_DrawSpriteShadow for convenience

git-svn-id: https://code.orospakr.ca/svn/srb2/trunk@8983 6de4a73c-47e2-0310-b8c1-93d6ecd3f8cd
---
 src/hardware/hw_main.c | 377 +++++++++++++++++++++--------------------
 1 file changed, 191 insertions(+), 186 deletions(-)

diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index db812c0df8..bc86c12957 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -3527,6 +3527,186 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
 	return false;
 }
 
+static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale)
+{
+	UINT8 i;
+	float tr_x, tr_y;
+	FOutVector *wv;
+	FOutVector swallVerts[4];
+	FSurfaceInfo sSurf;
+	fixed_t floorheight, mobjfloor;
+
+	mobjfloor = HWR_OpaqueFloorAtPos(
+		spr->mobj->x, spr->mobj->y,
+		spr->mobj->z, spr->mobj->height);
+	if (cv_shadowoffs.value)
+	{
+		angle_t shadowdir;
+
+		// Set direction
+		if (splitscreen && stplyr != &players[displayplayer])
+			shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value);
+		else
+			shadowdir = localangle + FixedAngle(cv_cam_rotate.value);
+
+		// Find floorheight
+		floorheight = HWR_OpaqueFloorAtPos(
+			spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
+			spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
+			spr->mobj->z, spr->mobj->height);
+
+		// The shadow is falling ABOVE it's mobj?
+		// Don't draw it, then!
+		if (spr->mobj->z < floorheight)
+			return;
+		else
+		{
+			fixed_t floorz;
+			floorz = HWR_OpaqueFloorAtPos(
+				spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight),
+				spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight),
+				spr->mobj->z, spr->mobj->height);
+			// The shadow would be falling on a wall? Don't draw it, then.
+			// Would draw midair otherwise.
+			if (floorz < floorheight)
+				return;
+		}
+
+		floorheight = FixedInt(spr->mobj->z - floorheight);
+	}
+	else
+		floorheight = FixedInt(spr->mobj->z - mobjfloor);
+
+	// create the sprite billboard
+	//
+	//  3--2
+	//  | /|
+	//  |/ |
+	//  0--1
+
+	// x1/x2 were already scaled in HWR_ProjectSprite
+	swallVerts[0].x = swallVerts[3].x = spr->x1;
+	swallVerts[2].x = swallVerts[1].x = spr->x2;
+
+	if (spr->mobj && this_scale != 1.0f)
+	{
+		// Always a pixel above the floor, perfectly flat.
+		swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3);
+
+		swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset) * this_scale;
+		swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset * this_scale;
+	}
+	else
+	{
+		// Always a pixel above the floor, perfectly flat.
+		swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3);
+
+		// Spread out top away from the camera. (Fixme: Make it always move out in the same direction!... somehow.)
+		swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset);
+		swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset;
+	}
+
+	// transform
+	wv = swallVerts;
+
+	for (i = 0; i < 4; i++,wv++)
+	{
+		// Offset away from the camera based on height from floor.
+		if (cv_shadowoffs.value)
+			wv->z += floorheight;
+		wv->z += 3;
+
+		//look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+		tr_x = wv->z;
+		tr_y = wv->y;
+		wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin);
+		wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos);
+		// ---------------------- mega lame test ----------------------------------
+
+		//scale y before frustum so that frustum can be scaled to screen height
+		wv->y *= ORIGINAL_ASPECT * gr_fovlud;
+		wv->x *= gr_fovlud;
+	}
+
+	if (spr->flip)
+	{
+		swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s;
+		swallVerts[2].sow = swallVerts[1].sow = 0;
+	}
+	else
+	{
+		swallVerts[0].sow = swallVerts[3].sow = 0;
+		swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s;
+	}
+
+	// flip the texture coords (look familiar?)
+	if (spr->vflip)
+	{
+		swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t;
+		swallVerts[0].tow = swallVerts[1].tow = 0;
+	}
+	else
+	{
+		swallVerts[3].tow = swallVerts[2].tow = 0;
+		swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t;
+	}
+
+	sSurf.FlatColor.s.red = 0x00;
+	sSurf.FlatColor.s.blue = 0x00;
+	sSurf.FlatColor.s.green = 0x00;
+
+	/*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW)
+	{
+		sector_t *sector = spr->mobj->subsector->sector;
+		UINT8 lightlevel = sector->lightlevel;
+		extracolormap_t *colormap = sector->extra_colormap;
+
+		if (sector->numlights)
+		{
+			INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false);
+
+			if (!(spr->mobj->frame & FF_FULLBRIGHT))
+				lightlevel = *sector->lightlist[light].lightlevel;
+			else
+				lightlevel = 255;
+
+			if (sector->lightlist[light].extra_colormap)
+				colormap = sector->lightlist[light].extra_colormap;
+		}
+		else
+		{
+			lightlevel = sector->lightlevel;
+
+			if (sector->extra_colormap)
+				colormap = sector->extra_colormap;
+		}
+
+		if (colormap)
+			sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true);
+		else
+			sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true);
+	}*/
+
+	// shadow is always half as translucent as the sprite itself
+	if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency)
+		sSurf.FlatColor.s.alpha = 0x80; // default
+	else if (spr->mobj->flags2 & MF2_SHADOW)
+		sSurf.FlatColor.s.alpha = 0x20;
+	else if (spr->mobj->frame & FF_TRANSMASK)
+	{
+		HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf);
+		sSurf.FlatColor.s.alpha /= 2; //cut alpha in half!
+	}
+	else
+		sSurf.FlatColor.s.alpha = 0x80; // default
+
+	if (sSurf.FlatColor.s.alpha > floorheight/4)
+	{
+		sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4);
+		HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
+	}
+}
+
 // -----------------+
 // HWR_DrawSprite   : Draw flat sprites
 //                  : (monsters, bonuses, weapons, lights, ...)
@@ -3629,7 +3809,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
 
 	// Draw shadow BEFORE sprite
 	if (cv_shadow.value // Shadows enabled
-		&& !(spr->mobj->flags & MF_SCENERY && spr->mobj->flags & MF_SPAWNCEILING && spr->mobj->flags & MF_NOGRAVITY) // Ceiling scenery have no shadow.
+		&& (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
 		&& !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
 #ifdef ALAM_LIGHTING
 		&& !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow.
@@ -3640,187 +3820,9 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
 		////////////////////
 		// SHADOW SPRITE! //
 		////////////////////
-		FOutVector swallVerts[4];
-		FSurfaceInfo sSurf;
-		fixed_t floorheight, mobjfloor;
-
-		mobjfloor = HWR_OpaqueFloorAtPos(
-			spr->mobj->x, spr->mobj->y,
-			spr->mobj->z, spr->mobj->height);
-		if (cv_shadowoffs.value)
-		{
-			angle_t shadowdir;
-
-			// Set direction
-			if (splitscreen && stplyr != &players[displayplayer])
-				shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value);
-			else
-				shadowdir = localangle + FixedAngle(cv_cam_rotate.value);
-
-			// Find floorheight
-			floorheight = HWR_OpaqueFloorAtPos(
-				spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
-				spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
-				spr->mobj->z, spr->mobj->height);
-
-			// The shadow is falling ABOVE it's mobj?
-			// Don't draw it, then!
-			if (spr->mobj->z < floorheight)
-				goto noshadow;
-			else
-			{
-				fixed_t floorz;
-				floorz = HWR_OpaqueFloorAtPos(
-					spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight),
-					spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight),
-					spr->mobj->z, spr->mobj->height);
-				// The shadow would be falling on a wall? Don't draw it, then.
-				// Would draw midair otherwise.
-				if (floorz < floorheight)
-					goto noshadow;
-			}
-
-			floorheight = FixedInt(spr->mobj->z - floorheight);
-		}
-		else
-			floorheight = FixedInt(spr->mobj->z - mobjfloor);
-
-		// create the sprite billboard
-		//
-		//  3--2
-		//  | /|
-		//  |/ |
-		//  0--1
-
-		// x1/x2 were already scaled in HWR_ProjectSprite
-		swallVerts[0].x = swallVerts[3].x = spr->x1;
-		swallVerts[2].x = swallVerts[1].x = spr->x2;
-
-		if (spr->mobj && this_scale != 1.0f)
-		{
-			// Always a pixel above the floor, perfectly flat.
-			swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3);
-
-			swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset) * this_scale;
-			swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset * this_scale;
-		}
-		else
-		{
-			// Always a pixel above the floor, perfectly flat.
-			swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3);
-
-			// Spread out top away from the camera. (Fixme: Make it always move out in the same direction!... somehow.)
-			swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset);
-			swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset;
-		}
-
-		// transform
-		wv = swallVerts;
-
-		for (i = 0; i < 4; i++,wv++)
-		{
-			// Offset away from the camera based on height from floor.
-			if (cv_shadowoffs.value)
-				wv->z += floorheight;
-			wv->z += 3;
-
-			//look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-			tr_x = wv->z;
-			tr_y = wv->y;
-			wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin);
-			wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos);
-			// ---------------------- mega lame test ----------------------------------
-
-			//scale y before frustum so that frustum can be scaled to screen height
-			wv->y *= ORIGINAL_ASPECT * gr_fovlud;
-			wv->x *= gr_fovlud;
-		}
-
-		if (spr->flip)
-		{
-			swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s;
-			swallVerts[2].sow = swallVerts[1].sow = 0;
-		}
-		else
-		{
-			swallVerts[0].sow = swallVerts[3].sow = 0;
-			swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s;
-		}
-
-		// flip the texture coords (look familiar?)
-		if (spr->vflip)
-		{
-			swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t;
-			swallVerts[0].tow = swallVerts[1].tow = 0;
-		}
-		else
-		{
-			swallVerts[3].tow = swallVerts[2].tow = 0;
-			swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t;
-		}
-
-		sSurf.FlatColor.s.red = 0x00;
-		sSurf.FlatColor.s.blue = 0x00;
-		sSurf.FlatColor.s.green = 0x00;
-
-		/*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW)
-		{
-			sector_t *sector = spr->mobj->subsector->sector;
-			UINT8 lightlevel = sector->lightlevel;
-			extracolormap_t *colormap = sector->extra_colormap;
-
-			if (sector->numlights)
-			{
-				INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false);
-
-				if (!(spr->mobj->frame & FF_FULLBRIGHT))
-					lightlevel = *sector->lightlist[light].lightlevel;
-				else
-					lightlevel = 255;
-
-				if (sector->lightlist[light].extra_colormap)
-					colormap = sector->lightlist[light].extra_colormap;
-			}
-			else
-			{
-				lightlevel = sector->lightlevel;
-
-				if (sector->extra_colormap)
-					colormap = sector->extra_colormap;
-			}
-
-			if (colormap)
-				sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true);
-			else
-				sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true);
-		}*/
-
-		// shadow is always half as translucent as the sprite itself
-		if (!cv_translucency.value)
-			; // translucency disabled
-		else if (spr->mobj->flags2 & MF2_SHADOW)
-			sSurf.FlatColor.s.alpha = 0x20;
-		else if (spr->mobj->frame & FF_TRANSMASK)
-		{
-			HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf);
-			sSurf.FlatColor.s.alpha /= 2; //cut alpha in half!
-		}
-		else
-			sSurf.FlatColor.s.alpha = 0x80; // default
-
-		/// \todo do the test earlier
-		if (!cv_grmd2.value || (md2_models[spr->mobj->sprite].scale < 0.0f) || (md2_models[spr->mobj->sprite].notfound = true) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) || (md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound = true))
-		{
-			if (sSurf.FlatColor.s.alpha > floorheight/4)
-			{
-				sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4);
-				HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
-			}
-		}
+		HWR_DrawSpriteShadow(spr, gpatch, this_scale);
 	}
 
-noshadow:
-
 	// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
 	// sprite lighting by modulating the RGB components
 	/// \todo coloured
@@ -3865,11 +3867,14 @@ noshadow:
 			Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
 	}
 
-	/// \todo do the test earlier
-	if (!cv_grmd2.value || (md2_models[spr->mobj->sprite].scale < 0.0f))
 	{
 		FBITFIELD blend = 0;
-		if (spr->mobj->flags2 & MF2_SHADOW)
+		if (!cv_translucency.value) // translucency disabled
+		{
+			Surf.FlatColor.s.alpha = 0xFF;
+			blend = PF_Translucent|PF_Occlude;
+		}
+		else if (spr->mobj->flags2 & MF2_SHADOW)
 		{
 			Surf.FlatColor.s.alpha = 0x40;
 			blend = PF_Translucent;
@@ -4390,10 +4395,10 @@ static void HWR_DrawSprites(void)
 #endif
 				if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
 				{
-					if (!cv_grmd2.value || (cv_grmd2.value && md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == true))
+					if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
 						HWR_DrawSprite(spr);
 				}
-				else if (!cv_grmd2.value || (cv_grmd2.value && md2_models[spr->mobj->sprite].notfound == true))
+				else if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f)
 					HWR_DrawSprite(spr);
 		}
 	}
@@ -4419,7 +4424,7 @@ static void HWR_DrawMD2S(void)
 #endif
 				if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
 				{
-					if ((md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == false) && (md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f))
+					if (md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == false && md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f)
 						HWR_DrawMD2(spr);
 				}
 				else if (md2_models[spr->mobj->sprite].notfound == false && md2_models[spr->mobj->sprite].scale > 0.0f)
-- 
GitLab