shithub: qk1

Download patch

ref: 6d97f6b4494d46084ca64c8bb79deb8d67ea4d6f
parent: bf02a0915ffa42a3b051ea6e41c9ed1528d04614
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Oct 16 13:58:20 EDT 2023

add initial water alpha support

--- a/d_edge.c
+++ b/d_edge.c
@@ -234,7 +234,7 @@
 				}
 
 				D_CalcGradients (pface);
-				Turbulent8 (s->spans);
+				Turbulent8 (s->spans, r_wateralpha.value);
 				D_DrawZSpans (s->spans);
 
 				if (s->insubmodel)
@@ -286,8 +286,10 @@
 
 				if(s->flags & SURF_FENCE)
 					D_DrawSpans16_Fence(s->spans);
+				else if(s->flags & SURF_TRANS)
+					(*d_drawspans) (s->spans, r_wateralpha.value);
 				else
-					(*d_drawspans) (s->spans);
+					(*d_drawspans) (s->spans, 1.0);
 
 				D_DrawZSpans (s->spans);
 
--- a/d_init.c
+++ b/d_init.c
@@ -19,7 +19,7 @@
 
 extern int			d_aflatcolor;
 
-void (*d_drawspans) (espan_t *pspan);
+void (*d_drawspans) (espan_t *pspan, float alpha);
 
 
 /*
--- a/d_local.h
+++ b/d_local.h
@@ -50,11 +50,10 @@
 fixed16_t	sadjust, tadjust;
 fixed16_t	bbextents, bbextentt;
 
-
 void D_DrawSpans8 (espan_t *pspans);
-void D_DrawSpans16 (espan_t *pspans);
+void D_DrawSpans16 (espan_t *pspans, float alpha);
 void D_DrawZSpans (espan_t *pspans);
-void Turbulent8 (espan_t *pspan);
+void Turbulent8 (espan_t *pspan, float alpha);
 void D_SpriteDrawSpans (sspan_t *pspan);
 void D_DrawSpans16_Fence (espan_t *pspan);
 
@@ -84,5 +83,5 @@
 extern int		d_minmip;
 extern float	d_scalemip[3];
 
-extern void (*d_drawspans) (espan_t *pspan);
+extern void (*d_drawspans) (espan_t *pspan, float alpha);
 
--- a/d_scan.c
+++ b/d_scan.c
@@ -8,10 +8,8 @@
 fixed16_t		r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
 int				*r_turb_turb;
 int				r_turb_spancount;
+static uzint	*r_turb_z;
 
-void D_DrawTurbulent8Span (void);
-
-
 /*
 =============
 D_WarpScreen
@@ -28,8 +26,8 @@
 	int		*turb;
 	int		*col;
 	byte	**row;
-	byte	*rowptr[MAXHEIGHT+(AMP2*2)];
-	int		column[MAXWIDTH+(AMP2*2)];
+	static byte	*rowptr[MAXHEIGHT+(AMP2*2)];
+	static int		column[MAXWIDTH+(AMP2*2)];
 	float	wratio, hratio;
 
 	w = r_refdef.vrect.width;
@@ -68,13 +66,54 @@
 	}
 }
 
+static byte *alphamap;
+static byte mapalpha;
 
+static void
+buildalpha(int alpha)
+{
+	extern s32int fbpal[256];
+	int a, b;
+	byte *ca, *cb, *p;
+	int r0, g0, b0;
+	int r1, g1, b1;
+	int rr, gg, bb;
+	int i, dst, x, best;
+
+	if(alphamap == nil)
+		alphamap = malloc(256*256);
+	for(a = 0; a < 256; a++){
+		ca = (byte*)&fbpal[a];
+		r0 = ca[0]; g0 = ca[1]; b0 = ca[2];
+		for(b = 0; b < 256; b++){
+				cb = (byte*)&fbpal[b];
+				r1 = cb[0]; g1 = cb[1]; b1 = cb[2];
+				rr = (alpha*r0 + (255 - alpha)*r1)/255;
+				gg = (alpha*g0 + (255 - alpha)*g1)/255;
+				bb = (alpha*b0 + (255 - alpha)*b1)/255;
+				dst = 9999999;
+				best = 255;
+				p = (byte*)fbpal;
+				for(i = 0; i < 768; i += 4){
+					if((x = (rr-p[i])*(rr-p[i])+(gg-p[i+1])*(gg-p[i+1])+(bb-p[i+2])*(bb-p[i+2])) < dst){
+					dst = x;
+					best = i;
+				}
+				alphamap[a<<8 | b] = best/4;
+			}
+		}
+	}
+}
+
+#define blendalpha(a, b, alpha) \
+	alphamap[(u16int)((a)<<8 | (b))]
+
 /*
 =============
 D_DrawTurbulent8Span
 =============
 */
-void D_DrawTurbulent8Span (void)
+void D_DrawTurbulent8Span (int izi, byte alpha)
 {
 	int		sturb, tturb;
 
@@ -82,9 +121,17 @@
 	{
 		sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
 		tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
-		*r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb);
+		if (*r_turb_z <= (izi >> 16)){
+			if(alpha == 255 || alpha == 0)
+				*r_turb_pdest = *(r_turb_pbase + (tturb<<6) + sturb);
+			else
+				*r_turb_pdest = blendalpha(*(r_turb_pbase + (tturb<<6) + sturb), *r_turb_pdest, alpha);
+			*r_turb_z = (izi >> 16);
+		}
 		r_turb_s += r_turb_sstep;
 		r_turb_t += r_turb_tstep;
+		r_turb_pdest++;
+		r_turb_z++;
 	} while (--r_turb_spancount > 0);
 }
 
@@ -94,12 +141,13 @@
 Turbulent8
 =============
 */
-void Turbulent8 (espan_t *pspan)
+void Turbulent8 (espan_t *pspan, float alpha)
 {
 	int				count;
 	fixed16_t		snext, tnext;
 	float			sdivz, tdivz, zi, z, du, dv, spancountminus1;
 	float			sdivz16stepu, tdivz16stepu, zi16stepu;
+	byte			balpha;
 	
 	r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
 
@@ -111,11 +159,19 @@
 	sdivz16stepu = d_sdivzstepu * 16;
 	tdivz16stepu = d_tdivzstepu * 16;
 	zi16stepu = d_zistepu * 16;
+	alpha = clamp(alpha, 0.0, 1.0);
+	balpha = alpha * 255;
 
+	if(balpha != 255 && (alphamap == nil || balpha != mapalpha)){
+		mapalpha = balpha;
+		buildalpha(balpha);
+	}
+
 	do
 	{
 		r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
 				(screenwidth * pspan->v) + pspan->u);
+		r_turb_z = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
 
 		count = pspan->count;
 
@@ -211,7 +267,7 @@
 			r_turb_s = r_turb_s & ((CYCLE<<16)-1);
 			r_turb_t = r_turb_t & ((CYCLE<<16)-1);
 
-			D_DrawTurbulent8Span ();
+			D_DrawTurbulent8Span ((int)(zi * 0x8000 * 0x10000), balpha);
 
 			r_turb_s = snext;
 			r_turb_t = tnext;
@@ -382,7 +438,7 @@
 D_DrawSpans16
 =============
 */
-void D_DrawSpans16 (espan_t *pspan) //qbism- up it from 8 to 16
+void D_DrawSpans16 (espan_t *pspan, float alpha) //qbism- up it from 8 to 16
 {
 	int				count, spancount;
 	unsigned char	*pbase, *pdest;
@@ -495,9 +551,10 @@
 				}
 			}
 
-			void dospan(uchar *, uchar *, int, int, int, int, int, int);
-			if(spancount > 0)
+			if(spancount > 0){
+				void dospan(uchar *, uchar *, int, int, int, int, int, int);
 				dospan(pdest, pbase, s, t, sstep, tstep, spancount, cachewidth);
+			}
 			pdest += spancount;
 			s = snext;
 			t = tnext;
--- a/model.c
+++ b/model.c
@@ -780,7 +780,7 @@
 		if(strncmp(out->texinfo->texture->name, "sky", 3) == 0)
 			out->flags |= SURF_DRAWSKY | SURF_DRAWTILED;
 		else if(out->texinfo->texture->name[0] == '*'){	// turbulent
-			out->flags |= SURF_DRAWTURB | SURF_DRAWTILED;
+			out->flags |= SURF_DRAWTURB | SURF_DRAWTILED | SURF_TRANS;
 			for (i=0 ; i<2 ; i++){
 				out->extents[i] = 16384;
 				out->texturemins[i] = -8192;
--- a/qk1.c
+++ b/qk1.c
@@ -5,7 +5,7 @@
 #include "quakedef.h"
 #include "fns.h"
 
-int mainstacksize = 1*1024*1024;
+int mainstacksize = 4*1024*1024;
 char *netmtpt = "/net";
 char *game;
 int debug;
--- a/r_local.h
+++ b/r_local.h
@@ -50,6 +50,7 @@
 extern cvar_t	r_reportedgeout;
 extern cvar_t	r_numedges;
 extern cvar_t	r_part_scale;
+extern cvar_t	r_wateralpha;
 
 #define XCENTERING	(1.0 / 2.0)
 #define YCENTERING	(1.0 / 2.0)
--- a/r_main.c
+++ b/r_main.c
@@ -117,6 +117,7 @@
 cvar_t	r_aliastransbase = {"r_aliastransbase", "200"};
 cvar_t	r_aliastransadj = {"r_aliastransadj", "100"};
 cvar_t	r_part_scale = {"r_part_scale", "0.75", true};
+cvar_t	r_wateralpha = {"r_wateralpha", "1", true};
 
 extern cvar_t	scr_fov;
 
@@ -199,6 +200,7 @@
 	Cvar_RegisterVariable (&r_aliastransbase);
 	Cvar_RegisterVariable (&r_aliastransadj);
 	Cvar_RegisterVariable (&r_part_scale);
+	Cvar_RegisterVariable (&r_wateralpha);
 
 	view_clipplanes[0].leftedge = true;
 	view_clipplanes[1].rightedge = true;
--- a/vid.c
+++ b/vid.c
@@ -11,7 +11,7 @@
 Point center;		/* of window */
 Rectangle grabr;
 
-static s32int fbpal[256];
+s32int fbpal[256];
 static uchar *fbs;
 static Image *fbi;
 static Rectangle fbr;