shithub: qk1

Download patch

ref: 53b4dd2f45fc0a8a10401984afe1a1c909eb86f8
parent: 116ac5a454742c6f0b1c1a16a987ffa2c1db012f
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sat Oct 14 20:09:42 EDT 2023

rewrite sky loading and rendering

--- a/d_edge.c
+++ b/d_edge.c
@@ -193,11 +193,6 @@
 
 			if (s->flags & SURF_DRAWSKY)
 			{
-				if (!r_skymade)
-				{
-					R_MakeSky ();
-				}
-
 				D_DrawSkyScans8 (s->spans);
 				D_DrawZSpans (s->spans);
 			}
--- a/d_iface.h
+++ b/d_iface.h
@@ -143,8 +143,7 @@
 void D_PolysetUpdateTables (void);
 
 // these are currently for internal use only, and should not be used by drivers
-extern int				r_skydirect;
-extern byte				*r_skysource;
+extern byte				*r_skysource[2];
 
 // transparency types for D_DrawRect ()
 #define DR_SOLID		0
@@ -185,10 +184,6 @@
 #define	CYCLE			128		// turbulent cycle size
 
 #define TILE_SIZE		128		// size of textures generated by R_GenTiledSurf
-
-#define SKYSHIFT		7
-#define	SKYSIZE			(1 << SKYSHIFT)
-#define SKYMASK			(SKYSIZE - 1)
 
 extern float	skyspeed, skyspeed2;
 extern float	skytime;
--- a/d_init.c
+++ b/d_init.c
@@ -30,8 +30,6 @@
 void D_Init (void)
 {
 
-	r_skydirect = 1;
-
 	Cvar_RegisterVariable (&d_subdiv16);
 	Cvar_RegisterVariable (&d_mipcap);
 	Cvar_RegisterVariable (&d_mipscale);
--- a/d_sky.c
+++ b/d_sky.c
@@ -7,6 +7,7 @@
 #define SKY_SPAN_SHIFT	5
 #define SKY_SPAN_MAX	(1 << SKY_SPAN_SHIFT)
 
+extern int skyw, skyh;
 
 /*
 =================
@@ -15,26 +16,28 @@
 */
 void D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
 {
-	float	wu, wv, temp;
+	double	wu, wv, temp;
 	vec3_t	end;
 
 	if (r_refdef.vrect.width >= r_refdef.vrect.height)
-		temp = (float)r_refdef.vrect.width;
+		temp = r_refdef.vrect.width;
 	else
-		temp = (float)r_refdef.vrect.height;
+		temp = r_refdef.vrect.height;
 
-	wu = 8192.0 * (float)(u-((int)vid.width>>1)) / temp;
-	wv = 8192.0 * (float)(((int)vid.height>>1)-v) / temp;
+	wu = 8192.0 * (double)(u-((int)vid.width>>1)) / temp;
+	wv = 8192.0 * (double)(((int)vid.height>>1)-v) / temp;
 
-	end[0] = 4096*vpn[0] + wu*vright[0] + wv*vup[0];
-	end[1] = 4096*vpn[1] + wu*vright[1] + wv*vup[1];
-	end[2] = 4096*vpn[2] + wu*vright[2] + wv*vup[2];
+	end[0] = 4096.0*vpn[0] + wu*vright[0] + wv*vup[0];
+	end[1] = 4096.0*vpn[1] + wu*vright[1] + wv*vup[1];
+	end[2] = 4096.0*vpn[2] + wu*vright[2] + wv*vup[2];
 	end[2] *= 3;
-	VectorNormalize (end);
+	VectorNormalize(end);
 
 	temp = skytime*skyspeed;	// TODO: add D_SetupFrame & set this there
-	*s = (int)((temp + 6*(SKYSIZE/2-1)*end[0]) * 0x10000);
-	*t = (int)((temp + 6*(SKYSIZE/2-1)*end[1]) * 0x10000);
+	s[0] = (int)((temp + 4*(skyw-1)*end[0]) * 0x10000);
+	t[0] = (int)((temp + 4*(skyh-1)*end[1]) * 0x10000);
+	s[1] = (int)((temp*2.0 + 4*(skyw-1)*end[0]) * 0x10000);
+	t[1] = (int)((temp*2.0 + 4*(skyh-1)*end[1]) * 0x10000);
 }
 
 
@@ -46,12 +49,12 @@
 void D_DrawSkyScans8 (espan_t *pspan)
 {
 	int				count, spancount, u, v;
-	unsigned char	*pdest;
-	fixed16_t		s, t, snext, tnext, sstep, tstep;
+	unsigned char	*pdest, m;
+	fixed16_t		s[2], t[2], snext[2], tnext[2], sstep[2], tstep[2];
 	int				spancountminus1;
 
-	sstep = 0;	// keep compiler happy
-	tstep = 0;	// ditto
+	sstep[0] = sstep[1] = 0;	// keep compiler happy
+	tstep[0] = tstep[1] = 0;	// ditto
 
 	do
 	{
@@ -63,7 +66,7 @@
 	// calculate the initial s & t
 		u = pspan->u;
 		v = pspan->v;
-		D_Sky_uv_To_st (u, v, &s, &t);
+		D_Sky_uv_To_st (u, v, s, t);
 
 		do
 		{
@@ -80,10 +83,12 @@
 
 			// calculate s and t at far end of span,
 			// calculate s and t steps across span by shifting
-				D_Sky_uv_To_st (u, v, &snext, &tnext);
+				D_Sky_uv_To_st (u, v, snext, tnext);
 
-				sstep = (snext - s) >> SKY_SPAN_SHIFT;
-				tstep = (tnext - t) >> SKY_SPAN_SHIFT;
+				sstep[0] = (snext[0] - s[0]) >> SKY_SPAN_SHIFT;
+				tstep[0] = (tnext[0] - t[0]) >> SKY_SPAN_SHIFT;
+				sstep[1] = (snext[1] - s[1]) >> SKY_SPAN_SHIFT;
+				tstep[1] = (tnext[1] - t[1]) >> SKY_SPAN_SHIFT;
 			}
 			else
 			{
@@ -94,24 +99,35 @@
 				if (spancountminus1 > 0)
 				{
 					u += spancountminus1;
-					D_Sky_uv_To_st (u, v, &snext, &tnext);
+					D_Sky_uv_To_st (u, v, snext, tnext);
 
-					sstep = (snext - s) / spancountminus1;
-					tstep = (tnext - t) / spancountminus1;
+					sstep[0] = (snext[0] - s[0]) / spancountminus1;
+					tstep[0] = (tnext[0] - t[0]) / spancountminus1;
+					sstep[1] = (snext[1] - s[1]) / spancountminus1;
+					tstep[1] = (tnext[1] - t[1]) / spancountminus1;
 				}
 			}
 
 			do
 			{
-				*pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) +
-						((s & R_SKY_SMASK) >> 16)];
-				s += sstep;
-				t += tstep;
+				m = r_skysource[1][((t[1] & R_SKY_TMASK) >> 9) +
+						((s[1] & R_SKY_SMASK) >> 16)];
+				if(m == 0)
+					*pdest = r_skysource[0][((t[0] & R_SKY_TMASK) >> 9) +
+							((s[0] & R_SKY_SMASK) >> 16)];
+				else
+					*pdest = m;
+				pdest++;
+				s[0] += sstep[0];
+				t[0] += tstep[0];
+				s[1] += sstep[1];
+				t[1] += tstep[1];
 			} while (--spancount > 0);
 
-			s = snext;
-			t = tnext;
-
+			s[0] = snext[0];
+			t[0] = tnext[0];
+			s[1] = snext[1];
+			t[1] = tnext[1];
 		} while (count > 0);
 
 	} while ((pspan = pspan->pnext) != nil);
--- a/r_local.h
+++ b/r_local.h
@@ -119,7 +119,6 @@
 void R_DrawSurfaceBlock8 (void);
 texture_t *R_TextureAnimation (texture_t *base);
 
-void R_GenSkyTile (void *pdest);
 void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags);
 void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel);
 
--- a/r_shared.h
+++ b/r_shared.h
@@ -99,9 +99,6 @@
 extern void SetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
 	fixed8_t endvertu, fixed8_t endvertv);
 
-extern int	r_skymade;
-extern void R_MakeSky (void);
-
 extern int	ubasestep, errorterm, erroradjustup, erroradjustdown;
 
 // flags in finalvert_t.flags
--- a/r_sky.c
+++ b/r_sky.c
@@ -10,186 +10,40 @@
 
 float		skytime;
 
-byte		*r_skysource;
+byte		*r_skysource[2];
 
-int r_skymade;
-int r_skydirect;		// not used?
+int r_skymade, skyw, skyh;
 
-
-// TODO: clean up these routines
-
-byte	bottomsky[128*131];
-byte	bottommask[128*131];
-byte	newsky[128*256];	// newsky and topsky both pack in here, 128 bytes
-							//  of newsky on the left of each scan, 128 bytes
-							//  of topsky on the right, because the low-level
-							//  drawers need 256-byte scan widths
-
-
 /*
 =============
 R_InitSky
-
-A sky texture is 256*128, with the right side being a masked overlay
 ==============
 */
 void R_InitSky (texture_t *mt)
 {
-	int			i, j;
-	byte		*src;
+	int x, y, w, n;
+	byte *src;
 
 	src = (byte *)mt + mt->offsets[0];
-
-	for (i=0 ; i<128 ; i++)
-	{
-		for (j=0 ; j<128 ; j++)
-		{
-			newsky[(i*256) + j + 128] = src[i*256 + j + 128];
-		}
-	}
-
-	for (i=0 ; i<128 ; i++)
-	{
-		for (j=0 ; j<131 ; j++)
-		{
-			if (src[i*256 + (j & 0x7F)])
-			{
-				bottomsky[(i*131) + j] = src[i*256 + (j & 0x7F)];
-				bottommask[(i*131) + j] = 0;
-			}
-			else
-			{
-				bottomsky[(i*131) + j] = 0;
-				bottommask[(i*131) + j] = 0xff;
-			}
-		}
-	}
-	
-	r_skysource = newsky;
-}
-
-
-/*
-=================
-R_MakeSky
-=================
-*/
-void R_MakeSky (void)
-{
-	int			x, y;
-	int			ofs, baseofs;
-	int			xshift, yshift;
-	unsigned	*pnewsky;
-	static int	xlast = -1, ylast = -1;
-
-	xshift = skytime*skyspeed;
-	yshift = skytime*skyspeed;
-
-	if ((xshift == xlast) && (yshift == ylast))
+	w = mt->width;
+	skyh = mt->height;
+	if(w == skyh){ // probably without a mask?
+		skyw = w;
+		n = skyw*skyh;
+		r_skysource[0] = Hunk_Alloc(n);
+		r_skysource[1] = r_skysource[0];
+		memmove(r_skysource[0], src+n, n);
 		return;
-
-	xlast = xshift;
-	ylast = yshift;
-	
-	pnewsky = (unsigned *)&newsky[0];
-
-	for (y=0 ; y<SKYSIZE ; y++)
-	{
-		baseofs = ((y+yshift) & SKYMASK) * 131;
-
-// FIXME: clean this up
-#ifdef UNALIGNED_OK
-
-		for (x=0 ; x<SKYSIZE ; x += 4)
-		{
-			ofs = baseofs + ((x+xshift) & SKYMASK);
-
-		// PORT: unaligned dword access to bottommask and bottomsky
-
-			*pnewsky = (*(pnewsky + (128 / sizeof (unsigned))) &
-						*(unsigned *)&bottommask[ofs]) |
-						*(unsigned *)&bottomsky[ofs];
-			pnewsky++;
-		}
-
-#endif /* UNALIGNED_OK */
-#ifndef UNALIGNED_OK
-
-		for (x=0 ; x<SKYSIZE ; x++)
-		{
-			ofs = baseofs + ((x+xshift) & SKYMASK);
-
-			*(byte *)pnewsky = (*((byte *)pnewsky + 128) &
-						*(byte *)&bottommask[ofs]) |
-						*(byte *)&bottomsky[ofs];
-			pnewsky = (unsigned *)((byte *)pnewsky + 1);
-		}
-
-#endif /* ! UNALIGNED_OK */
-
-		pnewsky += 128 / sizeof (unsigned);
 	}
-
-	r_skymade = 1;
-}
-
-
-/*
-=================
-R_GenSkyTile
-=================
-*/
-void R_GenSkyTile (void *pdest)
-{
-	int			x, y;
-	int			ofs, baseofs;
-	int			xshift, yshift;
-	unsigned	*pnewsky;
-	unsigned	*pd;
-
-	xshift = skytime*skyspeed;
-	yshift = skytime*skyspeed;
-
-	pnewsky = (unsigned *)&newsky[0];
-	pd = (unsigned *)pdest;
-
-	for (y=0 ; y<SKYSIZE ; y++)
-	{
-		baseofs = ((y+yshift) & SKYMASK) * 131;
-
-// FIXME: clean this up
-#ifdef UNALIGNED_OK
-
-		for (x=0 ; x<SKYSIZE ; x += 4)
-		{
-			ofs = baseofs + ((x+xshift) & SKYMASK);
-
-		// PORT: unaligned dword access to bottommask and bottomsky
-
-			*pd = (*(pnewsky + (128 / sizeof (unsigned))) &
-				   *(unsigned *)&bottommask[ofs]) |
-				   *(unsigned *)&bottomsky[ofs];
-			pnewsky++;
-			pd++;
+	skyw = w/2;
+	n = skyw*skyh;
+	r_skysource[0] = Hunk_Alloc(n*2);
+	r_skysource[1] = r_skysource[0] + n;
+	for(y=0 ; y<skyh; y++){
+		for(x=0 ; x<skyw; x++){
+			r_skysource[0][y*skyw + x] = src[y*w + skyw + x];
+			r_skysource[1][y*skyw + x] = src[y*w + x];
 		}
-
-#endif /* UNALIGNED_OK */
-#ifndef UNALIGNED_OK
-
-		for (x=0 ; x<SKYSIZE ; x++)
-		{
-			ofs = baseofs + ((x+xshift) & SKYMASK);
-
-			*(byte *)pd = (*((byte *)pnewsky + 128) &
-						*(byte *)&bottommask[ofs]) |
-						*(byte *)&bottomsky[ofs];
-			pnewsky = (unsigned *)((byte *)pnewsky + 1);
-			pd = (unsigned *)((byte *)pd + 1);
-		}
-
-#endif /* ! UNALIGNED_OK */
-
-		pnewsky += 128 / sizeof (unsigned);
 	}
 }
 
@@ -209,10 +63,9 @@
 	g = GreatestCommonDivisor (iskyspeed, iskyspeed2);
 	s1 = iskyspeed / g;
 	s2 = iskyspeed2 / g;
-	temp = SKYSIZE * s1 * s2;
+	temp = skyh * s1 * s2;
 
 	skytime = cl.time - ((int)(cl.time / temp) * temp);
-	
 
 	r_skymade = 0;
 }
--- a/r_surf.c
+++ b/r_surf.c
@@ -522,8 +522,6 @@
 		R_GenTurbTile((pixel_t *)
 			((byte *)psurf->texinfo->texture
 			+ psurf->texinfo->texture->offsets[0]), pdest);
-	}else if(psurf->flags & SURF_DRAWSKY)
-		R_GenSkyTile(pdest);
-	else
+	}else if((psurf->flags & SURF_DRAWSKY) == 0)
 		fatal("Unknown tile type");
 }