shithub: qk1

Download patch

ref: a5b441d0296071fa3b3eb6a3e7501e781da9cb4d
parent: 67e63b7e1b4b799192b3e9c8a9702e54c83b67d1
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Dec 17 19:06:37 EST 2023

fog: R_BlendFog for external callers

--- a/d_local.h
+++ b/d_local.h
@@ -33,8 +33,6 @@
 	int				u, v, count;
 } sspan_t;
 
-typedef s32int uzint;
-
 extern cvar_t	d_subdiv16;
 
 extern float	scale_for_mip;
--- a/r_fog.c
+++ b/r_fog.c
@@ -6,6 +6,7 @@
 static struct {
 	float density;
 	pixel_t color;
+	byte c0, c1, c2;
 }r_fog_data;
 
 static void
@@ -20,7 +21,7 @@
 	case 5:
 	case 2:
 		x = atof(Cmd_Argv(i++));
-		r_fog_data.density = max(0.0, x) * 0.016;
+		r_fog_data.density = clamp(x, 0.0, 1.0) * 0.016;
 		r_fog_data.density *= r_fog_data.density;
 		if(n == 2)
 			break;
@@ -30,6 +31,9 @@
 			x = atof(Cmd_Argv(i));
 			r_fog_data.color = r_fog_data.color << 8 | (int)(0xff * clamp(x, 0.0, 1.0));
 		}
+		r_fog_data.c0 = r_fog_data.color>> 0;
+		r_fog_data.c1 = r_fog_data.color>> 8;
+		r_fog_data.c2 = r_fog_data.color>>16;
 		break;
 	}
 }
@@ -42,45 +46,52 @@
 	setcvar("r_skyfog", "0");
 }
 
+pixel_t
+R_BlendFog(pixel_t pix, uzint z)
+{
+	byte a;
+	float d;
+
+	if(r_fog.value <= 0 || r_fog_data.density <= 0.0)
+		return pix;
+
+	if(z > 65536){
+		d = 65536ULL*65536ULL / (u64int)z;
+		if((pix & ~0xffffff) == 0)
+			d /= 1.5;
+		d = 1.0 - exp2(-r_fog_data.density * d*d);
+		a = 255*d;
+	}else if(z < 0){
+		a = 255 * clamp(r_skyfog.value, 0, 1.0);
+	}else
+		a = 0;
+
+	if(a == 0)
+		return pix;
+
+	return
+		((a*r_fog_data.c0 + (255-a)*((pix>> 0)&0xff)) >> 8) << 0 |
+		((a*r_fog_data.c1 + (255-a)*((pix>> 8)&0xff)) >> 8) << 8 |
+		((a*r_fog_data.c2 + (255-a)*((pix>>16)&0xff)) >> 8) << 16;
+}
+
 void
 R_DrawFog(void)
 {
-	byte ca0, ca1, ca2, skyfogalpha, a;
 	pixel_t *pix;
 	int i, x, y;
 	uzint *z;
-	float d;
 
 	if(r_fog.value <= 0 || r_fog_data.density <= 0.0)
 		return;
 
-	ca0 = r_fog_data.color>> 0;
-	ca1 = r_fog_data.color>> 8;
-	ca2 = r_fog_data.color>>16;
-
-	skyfogalpha = 255 * clamp(r_skyfog.value, 0, 1.0);
 	/* FIXME(sigrid): this is super slow */
 	for(y = r_refdef.vrect.y; y < r_refdef.vrectbottom; y++){
 		i = y * vid.width + r_refdef.vrect.x;
 		pix = vid.buffer + i;
 		z = d_pzbuffer + i;
-		for(x = r_refdef.vrect.x; x < r_refdef.vrectright; x++, i++, pix++, z++){
-			if(*z > 65536){
-				d = 65536.0 / (float)(*z >> 16);
-				d = 1.0 - exp2(-r_fog_data.density * d*d);
-				a = 255*clamp(d, 0.0, 1.0);
-			}else if(*z < 0){
-				a = skyfogalpha;
-			}else
-				continue;
-
-			if(a > 0){
-				*pix =
-					((a*ca0 + (255-a)*((*pix>> 0)&0xff)) >> 8) << 0 |
-					((a*ca1 + (255-a)*((*pix>> 8)&0xff)) >> 8) << 8 |
-					((a*ca2 + (255-a)*((*pix>>16)&0xff)) >> 8) << 16;
-			}
-		}
+		for(x = r_refdef.vrect.x; x < r_refdef.vrectright; x++, i++, pix++, z++)
+			*pix = R_BlendFog(*pix, *z);
 	}
 }
 
--- a/r_local.h
+++ b/r_local.h
@@ -102,6 +102,7 @@
 extern int r_drawflags;
 
 void R_ResetFog(void);
+pixel_t R_BlendFog(pixel_t pix, uzint z);
 void R_DrawFog(void);
 void R_InitFog(void);
 
--- a/r_shared.h
+++ b/r_shared.h
@@ -13,6 +13,8 @@
 
 #define SIN_BUFFER_SIZE	(MAXDIMENSION+CYCLE)
 
+typedef s32int uzint;
+
 //===================================================================
 
 extern int		cachewidth;