Adding Smooth Sky Scroll To WinQuake
Moderator: InsideQC Admins
3 posts
• Page 1 of 1
Adding Smooth Sky Scroll To WinQuake
This adds MK's smooth sky scroll from Makaqu to WinQuake. It is a minimal implementation: 6 changed files: d_sky.c, r_sky.c, d_iface.h, d_edge.c, r_shared.h, r_surf.c
But only 2 files are changed much: d_sky.c, r_sky.c
1. r_surf.c - find R_GenTile function. And remove it.
2. r_shared.h - find this and remove
3. d_edge.c - find this and remove
4. d_iface.h --- find these and remove
5. r_sky.c - find these and remove
In r_setskyframe remove ...
6. r_sky.c - find this ....
And replace with ...
7A. d_sky.c - replace this ...
With this ....
7B. d_sky.c --- final step ...
Find:
And replace with ...
But only 2 files are changed much: d_sky.c, r_sky.c
1. r_surf.c - find R_GenTile function. And remove it.
2. r_shared.h - find this and remove
- Code: Select all
extern int r_skymade;
extern void R_MakeSky (void);
3. d_edge.c - find this and remove
- Code: Select all
if (!r_skymade)
{
R_MakeSky ();
}
4. d_iface.h --- find these and remove
- Code: Select all
// these are currently for internal use only, and should not be used by drivers
extern byte *r_skysource;
- Code: Select all
void R_GenTile (msurface_t *psurf, void *pdest);
5. r_sky.c - find these and remove
- Code: Select all
int r_skymade;
// 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
- Code: Select all
/*
=================
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))
return;
xlast = xshift;
ylast = yshift;
pnewsky = (unsigned *)&newsky[0];
for (y=0 ; y<SKYSIZE ; y++)
{
baseofs = ((y+yshift) & SKYMASK) * 131;
// FIXME: clean this up
#if 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++;
}
#else
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
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
#if 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++;
}
#else
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
pnewsky += 128 / sizeof (unsigned);
}
}
In r_setskyframe remove ...
- Code: Select all
r_skymade = 0;
6. r_sky.c - find this ....
- Code: Select all
void R_InitSky (texture_t *mt)
{
int i, j;
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;
}
And replace with ...
- Code: Select all
void R_InitSky (texture_t *mt)
{
skyoverlay = (byte *)mt + mt->offsets[0]; // Manoel Kasimier - smooth sky
skyunderlay = skyoverlay+128; // Manoel Kasimier - smooth sky
}
7A. d_sky.c - replace this ...
- Code: Select all
/*
=================
D_Sky_uv_To_st
=================
*/
void D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
{
float wu, wv, temp;
vec3_t end;
if (r_refdef.vrect.width >= r_refdef.vrect.height)
temp = (float)r_refdef.vrect.width;
else
temp = (float)r_refdef.vrect.height;
wu = 8192.0 * (float)(u-((int)R_CANVAS_width>>1)) / temp;
wv = 8192.0 * (float)(((int)R_CANVAS_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[2] *= 3;
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);
}
With this ....
- Code: Select all
static float timespeed1, timespeed2; // Manoel Kasimier - smooth sky
extern byte *skyunderlay, *skyoverlay; // Manoel Kasimier - smooth sky
/*
=================
D_Sky_uv_To_st
=================
*/
void D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t
, fixed16_t *s2, fixed16_t *t2) // Manoel Kasimier - smooth sky
{
float wu, wv;//, temp; // Manoel Kasimier - edited
vec3_t end;
// ToChriS - begin
wu = (u - xcenter) / xscale;
wv = (ycenter - v) / yscale;
end[0] = vpn[0] + wu*vright[0] + wv*vup[0];
end[1] = vpn[1] + wu*vright[1] + wv*vup[1];
end[2] = vpn[2] + wu*vright[2] + wv*vup[2];
// ToChriS - end
end[2] *= 3;
VectorNormalize (end);
*s = (int)((timespeed1 + 6*(SKYSIZE/2-1)*end[0]) * 0x10000); // Manoel Kasimier - smooth sky - edited
*t = (int)((timespeed1 + 6*(SKYSIZE/2-1)*end[1]) * 0x10000); // Manoel Kasimier - smooth sky - edited
*s2 = (int)((timespeed2 + 6*(SKYSIZE/2-1)*end[0]) * 0x10000); // Manoel Kasimier - smooth sky
*t2 = (int)((timespeed2 + 6*(SKYSIZE/2-1)*end[1]) * 0x10000); // Manoel Kasimier - smooth sky
}
unsigned char D_DrawSkyPixelOpaque (unsigned char pixel1, unsigned char pixel2)
{
return pixel2 ? pixel2 : pixel1;
}
7B. d_sky.c --- final step ...
Find:
- Code: Select all
void D_DrawSkyScans8 (espan_t *pspan)
{
int count, spancount, u, v;
unsigned char *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
int spancountminus1;
sstep = 0; // keep compiler happy
tstep = 0; // ditto
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s & t
u = pspan->u;
v = pspan->v;
D_Sky_uv_To_st (u, v, &s, &t);
do
{
if (count >= SKY_SPAN_MAX)
spancount = SKY_SPAN_MAX;
else
spancount = count;
count -= spancount;
if (count)
{
u += spancount;
// 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);
sstep = (snext - s) >> SKY_SPAN_SHIFT;
tstep = (tnext - t) >> SKY_SPAN_SHIFT;
}
else
{
// calculate s and t at last pixel in span,
// calculate s and t steps across span by division
spancountminus1 = (float)(spancount - 1);
if (spancountminus1 > 0)
{
u += spancountminus1;
D_Sky_uv_To_st (u, v, &snext, &tnext);
sstep = (snext - s) / spancountminus1;
tstep = (tnext - t) / spancountminus1;
}
}
do
{
*pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) +
((s & R_SKY_SMASK) >> 16)];
s += sstep;
t += tstep;
} while (--spancount > 0);
s = snext;
t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
And replace with ...
- Code: Select all
/*
=================
D_DrawSkyScans8
=================
*/
void D_DrawSkyScans8 (espan_t *pspan)
{
int count, spancount, u, v;
unsigned char *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
int spancountminus1;
fixed16_t s2, t2, snext2, tnext2, sstep2, tstep2; // Manoel Kasimier - smooth sky
timespeed1=skytime*skyspeed;//*4; // Fightoon modification
timespeed2=timespeed1*2.0;//*-1; // Fightoon modification
sstep2 = 0;
tstep2 = 0;
// Manoel Kasimier - smooth sky - end
sstep = 0; // keep compiler happy
tstep = 0; // ditto
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s & t
u = pspan->u;
v = pspan->v;
D_Sky_uv_To_st (u, v, &s, &t, &s2, &t2); // Manoel Kasimier - smooth sky - edited
do
{
if (count >= SKY_SPAN_MAX)
spancount = SKY_SPAN_MAX;
else
spancount = count;
count -= spancount;
if (count)
{
u += spancount;
// 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, &snext2, &tnext2); // Manoel Kasimier - smooth sky - edited
sstep = (snext - s) >> SKY_SPAN_SHIFT;
tstep = (tnext - t) >> SKY_SPAN_SHIFT;
sstep2 = (snext2 - s2) >> SKY_SPAN_SHIFT; // Manoel Kasimier - smooth sky
tstep2 = (tnext2 - t2) >> SKY_SPAN_SHIFT; // Manoel Kasimier - smooth sky
}
else
{
// calculate s and t at last pixel in span,
// calculate s and t steps across span by division
spancountminus1 = (float)(spancount - 1);
if (spancountminus1 > 0)
{
u += spancountminus1;
D_Sky_uv_To_st (u, v, &snext, &tnext, &snext2, &tnext2); // Manoel Kasimier - smooth sky - edited
sstep = (snext - s) / spancountminus1;
tstep = (tnext - t) / spancountminus1;
sstep2 = (snext2 - s2) / spancountminus1; // Manoel Kasimier - smooth sky
tstep2 = (tnext2 - t2) / spancountminus1; // Manoel Kasimier - smooth sky
}
}
do
{
// Manoel Kasimier - smooth sky - begin
*pdest++ = D_DrawSkyPixelOpaque(skyunderlay[((t & R_SKY_TMASK) >> 8) + ((s & R_SKY_SMASK) >> 16)],
skyoverlay [((t2 & R_SKY_TMASK) >> 8) + ((s2 & R_SKY_SMASK) >> 16)]);
// Manoel Kasimier - smooth sky - end
s += sstep;
t += tstep;
s2 += sstep2; // Manoel Kasimier - smooth sky
t2 += tstep2; // Manoel Kasimier - smooth sky
} while (--spancount > 0);
s = snext;
t = tnext;
s2 = snext2; // Manoel Kasimier - smooth sky
t2 = tnext2; // Manoel Kasimier - smooth sky
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-

Baker - Posts: 3666
- Joined: Tue Mar 14, 2006 5:15 am
Re: Adding Smooth Sky Scroll To WinQuake
These changes also fixes the sky scaling on zoom, and allows the usage of multiple sky textures on the same scene.
For example, you can have a daytime sky in a window, and a nighttime sky in another. Or a regular sky in the lower floors of a skyscraper, and a starry sky in its rooftop.
For example, you can have a daytime sky in a window, and a nighttime sky in another. Or a regular sky in the lower floors of a skyscraper, and a starry sky in its rooftop.
-

mankrip - Posts: 915
- Joined: Fri Jul 04, 2008 3:02 am
Re: Adding Smooth Sky Scroll To WinQuake
I thought this was a great of enough fix but seems to come with extra bonus fix. 
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
-

Baker - Posts: 3666
- Joined: Tue Mar 14, 2006 5:15 am
3 posts
• Page 1 of 1
Return to Programming Tutorials
Who is online
Users browsing this forum: No registered users and 1 guest