ref: 49a810aeb5cb996bf9a6d4e3c38fc4d17fb77610
dir: /d_sky.c/
#include "quakedef.h" #define SKY_SPAN_SHIFT 5 #define SKY_SPAN_MAX (1 << SKY_SPAN_SHIFT) skyvars_t skyvars; /* ================= D_Sky_uv_To_st ================= */ void D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t, float skydist) { double wu, wv; vec3_t end; 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]; end[2] *= 3; VectorNormalize(end); s[0] = (int)((skydist + 4*(skyvars.w-1)*end[0]) * 0x10000); t[0] = (int)((skydist + 4*(skyvars.h-1)*end[1]) * 0x10000); s[1] = (int)((skydist*2.0 + 4*(skyvars.w-1)*end[0]) * 0x10000); t[1] = (int)((skydist*2.0 + 4*(skyvars.h-1)*end[1]) * 0x10000); } /* ================= D_DrawSkyScans8 ================= */ void D_DrawSkyScans8 (espan_t *pspan) { int count, spancount, u, v, spancountminus1; pixel_t *pdest, pix; uzint *pz; fixed16_t s[2], t[2], snext[2], tnext[2], sstep[2], tstep[2]; float skydist; bool fog; int c0, c1, c2, inva; if(skyvars.source[0] == nil || skyvars.source[1] == nil) return; sstep[0] = sstep[1] = 0; // keep compiler happy tstep[0] = tstep[1] = 0; // ditto skydist = skyvars.time*skyvars.speed; // TODO: add D_SetupFrame & set this there if((fog = isskyfogged())){ c0 = fogvars.skyc0; c1 = fogvars.skyc1; c2 = fogvars.skyc1; inva = 255 - fogvars.sky; } do { pdest = dvars.viewbuffer + pspan->v*dvars.width + pspan->u; count = pspan->count; pz = dvars.zbuffer + pspan->v*dvars.width + pspan->u; memset(pz, 0xff, count*sizeof(*pz)); // calculate the initial s & t u = pspan->u; v = pspan->v; D_Sky_uv_To_st (u, v, s, t, skydist); do { spancount = min(count, SKY_SPAN_MAX); 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, skydist); 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{ // 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, skydist); 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{ pix = skyvars.source[1][((t[1] & skyvars.tmask) >> skyvars.tshift) + ((s[1] & skyvars.smask) >> 16)]; if(!opaque(pix)) pix = skyvars.source[0][((t[0] & skyvars.tmask) >> skyvars.tshift) + ((s[0] & skyvars.smask) >> 16)]; if(fog){ pix = ((c0 + inva*((pix>> 0)&0xff)) >> 8) << 0 | ((c1 + inva*((pix>> 8)&0xff)) >> 8) << 8 | ((c2 + inva*((pix>>16)&0xff)) >> 8) << 16; } *pdest++ = pix; s[0] += sstep[0]; t[0] += tstep[0]; s[1] += sstep[1]; t[1] += tstep[1]; } while (--spancount > 0); s[0] = snext[0]; t[0] = tnext[0]; s[1] = snext[1]; t[1] = tnext[1]; } while (count > 0); } while ((pspan = pspan->pnext) != nil); }