ngunix/renderer/d_scan.c

2643 lines
90 KiB
C

/*
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// d_scan.c
//
// Portable C scan-level rasterization code, all pixel depths.
//
// TODO: Fix this mess up, some of the codes formatting is utterly broken on most editors
#include "globaldef.h"
#include "r_local.h"
#include "d_local.h"
unsigned char *r_turb_pbase, *r_turb_pdest, *r_turb_prefst;;
fixed16_t r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
int *r_turb_turb;
int r_turb_spancount;
void D_DrawTurbulent8Span (void);
void D_DrawTurbulent8SpanT (void);
extern int fogcolr, fogcolg, fogcolb, fogthick, fogrange; // leilei - fog
extern byte bumpmap[256];
extern pixel_t transTable[256][256]; // for shrooms effect
pixel_t waterTable[256][256];
extern float oldwateralpha;
byte menumap[256][16]; // haha hack
extern pixel_t addTable[256][256]; // Additive blending effect
extern pixel_t mulTable[256][256]; // Multiply blending effect (for colormod)
extern pixel_t ditherTable[262144][4];
static byte *foggmap;
extern int wootel[32][32][32];
extern cvar_t *r_tranquality;
extern cvar_t *r_wateralpha;
extern float fademap[256]; // Used in generation of certain alpha tables
extern int oldwaterblend;
void SetFogMap (void)
{
foggmap = (byte *)host_fogmap;
}
void WaterTablgeGet (void)
{
float ay, ae;
int i, j, l, c, o;
float red, green, blue;
int ooh;
ooh = (int)r_tranquality->value;
ay = r_wateralpha->value; // water surface
ae = 1 - ay; // base pixels
for (l=0;l<255;l++)
{
for (c=0 ; c<255 ; c++)
{
if (oldwaterblend == 1){ // additive
red = host_basepal[c*3] + (host_basepal[l*3] *ay);
green = host_basepal[c*3+1] + (host_basepal[l*3+1] *ay);
blue = host_basepal[c*3+2] + (host_basepal[l*3+2] *ay);
}
else if (oldwaterblend == 2){ // multiplicative
red = host_basepal[c*3] *ae + ((host_basepal[c*3] * (host_basepal[l*3] * 0.05)) * ay);
green = host_basepal[c*3+1] *ae + ((host_basepal[c*3+1]* (host_basepal[l*3+1] * 0.05)) * ay);
blue = host_basepal[c*3+2] *ae + ((host_basepal[c*3+2] * (host_basepal[l*3+2] * 0.05)) * ay);
}
else if (oldwaterblend == 4){ // multiplicative
red = host_basepal[c*3] *ae + ((host_basepal[l*3] * 0.1 * (host_basepal[c*3] * 0.5)) * ay);
green = host_basepal[c*3+1] *ae + ((host_basepal[l*3+1] * 0.1 * (host_basepal[c*3+1] * 0.5)) * ay);
blue = host_basepal[c*3+2] *ae + ((host_basepal[l*3+2] * 0.1 * (host_basepal[c*3+2] * 0.5)) * ay);
}
else if (oldwaterblend == 5){ // weird alpha thing
/* how it works - goes through each color row from transparent(0) to opaque (16)
this would also be used for the future (can you say decals?) */
red = host_basepal[c*3] *(fademap[l] * ae) + (host_basepal[l*3] * (fademap[l]+0.3 * ay));
green = host_basepal[c*3+1] *(fademap[l] * ae) + (host_basepal[l*3+1] * (fademap[l]+0.3 * ay));
blue = host_basepal[c*3+2] * (fademap[l] * ae) + (host_basepal[l*3+2] * (fademap[l]+0.3 * ay));
}
else
{
red = host_basepal[c*3] *ae + (host_basepal[l*3] * ay);
green = host_basepal[c*3+1] *ae + (host_basepal[l*3+1] * ay);
blue = host_basepal[c*3+2] *ae + (host_basepal[l*3+2] * ay);
}
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
if (red < 0) red = 0;
if (green < 0) green = 0;
if (blue < 0) blue = 0;
if (ooh)
waterTable[l][c] = BestColor(red,green,blue, 0, 255); // High quality color tables get best color
else if (palmap2)
waterTable[l][c] = FindColor18(red,green,blue);
else
waterTable[l][c] = FindColor(red,green,blue); // Since we do this live we must do thisfast! or i'll cry.
}
}
}
/*
=============
D_AlphaShift
This way is for like uh mods that use vid_cshift
in ways intended for GLQuake use (i.e. contrasting a
centerprint visually)
it's a hacky workaround to play prydon gate
=============
*/
extern int shiftshif;
extern int shiftalpha;
void D_AlphaShift (void)
{
int x,y;
byte *pbuf;
VID_UnlockBuffer ();
S_ExtraUpdate ();
VID_LockBuffer ();
if (shiftalpha < 20)
return;
for (y=0 ; y<vid.height ; y++)
{
int t;
pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
t = (y & 1) << 1;
for (x=0 ; x<vid.width ; x++)
{
if (shiftalpha < 120)
pbuf[x] = transTable[shiftshif][pbuf[x]];
else if (shiftalpha < 220)
pbuf[x] = transTable[pbuf[x]][shiftshif];
else if (shiftalpha > 220)
pbuf[x] = (int)shiftshif;
}
}
VID_UnlockBuffer ();
S_ExtraUpdate ();
VID_LockBuffer ();
}
extern void *acolormap; // FIXME: should go away
/*
=============
D_WarpScreen
// this performs a slight compression of the screen at the same time as
// the sine warp, to keep the edges from wrapping
=============
*/
void D_WarpScreen (void)
{
int w, h;
int u,v;
byte *dest;
int *turb;
int *col;
byte **row;
byte *rowptr[MAXHEIGHT+(AMP2*2)];
int column[MAXWIDTH+(AMP2*2)];
float wratio, hratio;
w = r_refdef.vrect.width;
h = r_refdef.vrect.height;
wratio = w / (float)scr_vrect.width;
hratio = h / (float)scr_vrect.height;
for (v=0 ; v<scr_vrect.height+AMP2*2 ; v++)
rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) + (screenwidth * (int)((float)v * hratio * h / (h + AMP2 * 2)));
for (u=0 ; u<scr_vrect.width+AMP2*2 ; u++)
column[u] = r_refdef.vrect.x + (int)((float)u * wratio * w / (w + AMP2 * 2));
dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x;
turb = intsintable + ((int)(cl.time*SPEED)&(CYCLE-1));
for (v=0 ; v<scr_vrect.height ; v++, dest += vid.rowbytes)
{
col = &column[turb[v]];
row = &rowptr[v];
for (u=0 ; u<scr_vrect.width ; u+=4)
{
dest[u+0] = row[turb[u+0]][col[u+0]];
dest[u+1] = row[turb[u+1]][col[u+1]];
dest[u+2] = row[turb[u+2]][col[u+2]];
dest[u+3] = row[turb[u+3]][col[u+3]];
}
}
}
/*
=============
D_CrapScreen
=============
*/
void D_CrapScreen (void)
{
int w, h;
int u,v;
byte *dest;
int *turb;
int *col;
byte **row;
byte *rowptr[MAXHEIGHT+(AMP2*2)];
int column[MAXWIDTH+(AMP2*2)];
float wratio, hratio;
w = r_refdef.vrect.width;
h = r_refdef.vrect.height;
wratio = w / (float)scr_vrect.width;
hratio = h / (float)scr_vrect.height;
for (v=0 ; v<scr_vrect.height+AMP2*2 ; v++)
{
rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) +
(screenwidth * (int)((float)v * hratio * h / (h + AMP2 * 2)));
}
for (u=0 ; u<scr_vrect.width+AMP2*2 ; u++)
{
column[u] = r_refdef.vrect.x +
(int)((float)u * wratio * w / (w + AMP2 * 2));
}
turb = atableofnothingtable;
dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x;
for (v=0 ; v<scr_vrect.height ; v++, dest += vid.rowbytes)
{
col = &column[turb[v]];
row = &rowptr[v];
for (u=0 ; u<scr_vrect.width ; u+=4)
{
dest[u+0] = row[turb[u+0]][col[u+0]];
dest[u+1] = row[turb[u+1]][col[u+1]];
dest[u+2] = row[turb[u+2]][col[u+2]];
dest[u+3] = row[turb[u+3]][col[u+3]];
}
}
}
extern cvar_t *temp2;
// This is the MH version THANKS MH!!!
void D_CrapScreenMH (void)
{
int w, h;
int u,v;
byte *dest;
int *turb;
byte *rowptr[MAXHEIGHT+(AMP2*2)];
int column[MAXWIDTH+(AMP2*2)];
float wratio, hratio;
w = r_refdef.vrect.width;
h = r_refdef.vrect.height;
wratio = w / (float)scr_vrect.width;
hratio = h / (float)scr_vrect.height;
for (v=0 ; v<scr_vrect.height+AMP2*2 ; v++)
{
rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) +
(screenwidth * (int)((float)v * hratio * h / (h + AMP2 * 2)));
}
for (u=0 ; u<scr_vrect.width+AMP2*2 ; u++)
{
column[u] = r_refdef.vrect.x +
(int)((float)u * wratio * w / (w + AMP2 * 2));
}
turb = atableofnothingtable;
dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x;
for (v = 0; v < scr_vrect.height; v++, dest += vid.rowbytes)
{
byte *myrow = rowptr[v];
int *mycol = column;
int *mycolf = column;
byte *mydest = dest;
for (u = 0; u < scr_vrect.width; u += 4, mycol += 4, mydest += 4)
{
mydest[0] = myrow[mycol[0]];
mydest[1] = myrow[mycol[1]];
mydest[2] = myrow[mycol[2]];
mydest[3] = myrow[mycol[3]];
}
}
}
#if !id386
/*
=============
D_DrawTurbulent8Span
=============
*/
void D_DrawTurbulent8Span (void)
{
int sturb, tturb;
do
{
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);
r_turb_s += r_turb_sstep;
r_turb_t += r_turb_tstep;
} while (--r_turb_spancount > 0);
}
//
// if (foguse) // leilei - fogged case
// *pdest++ = (byte*)foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)];
// else
// *pdest++ = pbase[(s >> 16) + (t >> 16) * cachewidth];
//
#endif // !id386
int ferg;
void D_DrawTurbulent8Span_Fog (void)
{
int sturb, tturb;
do
{
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++ = foggmap[(*(r_turb_pbase + (tturb<<6) + sturb)) + (ferg >> 2 & 0xFF00)];
r_turb_s += r_turb_sstep;
r_turb_t += r_turb_tstep;
} while (--r_turb_spancount > 0);
}
int gmcol;
int izi, izistep, izistep2, sturb, tturb, teste; // mk transwater
short *pz; // mk transwater
extern cvar_t *temp1;
extern cvar_t *r_waterquality;
extern cvar_t *r_wateralpha;
int depthen;
void D_DrawTurbulent8SpanAlphaRefractions (void)
{
int sturb, tturb;
int refsturb, reftturb;
int refractsturb, refracttturb;
unsigned char temp, tempd2, tempd3, temp3, temp4;
int bleeh, bleeh2;
float wa;
//int pixsize = 2 * ( scr_vrect.width/ 640);
int pixsize = 2;
//wa = r_wateralpha->value;
// wa = depthen / 8192;
depthen = (depthen) >> 2;
do
{
if (*pz <= (izi >> 16))
{
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;
refractsturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)] * 4)>>16)&16;
refracttturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)] * 4)>>16)&16;
temp = *(r_turb_pbase + (tturb<<6) + sturb);
tempd3 = *(r_turb_pdest + ((refracttturb) + refractsturb >> pixsize));
// if ((*r_turb_pdest) < screenwidth)
//screenwidth * pspan->v
// tempd3 = *(r_turb_pdest + (int)((bumpmap[temp] - bumpmap[temp] /2)* (float)temp2->value));
// else
// tempd3 = *(r_turb_pdest);
temp3 = tempd3;
if (foguse)
*r_turb_pdest = foggmap[waterTable[temp][temp3]+ (ferg >> 2 & 0xFF00)];
else
*r_turb_pdest = waterTable[temp][temp3];
}
*r_turb_pdest++;
izi += izistep;
pz++;
r_turb_s += r_turb_sstep;
r_turb_t += r_turb_tstep;
} while (--r_turb_spancount > 0);
}
void D_DrawTurbulent8SpanAlpha (void)
{
int sturb, tturb;
unsigned char temp;
do
{
if (*pz <= (izi >> 16))
{
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;
temp = *(r_turb_pbase + (tturb<<6) + sturb);
if (foguse)
*r_turb_pdest = foggmap[waterTable[temp][*r_turb_pdest]+ (ferg >> 2 & 0xFF00)];
else
*r_turb_pdest = waterTable[temp][*r_turb_pdest];
}
*r_turb_pdest++;
izi += izistep;
pz++;
r_turb_s += r_turb_sstep;
r_turb_t += r_turb_tstep;
} while (--r_turb_spancount > 0);
}
// Leilei - this is very simple.
void D_DrawGelWaterSpan (void)
{
do
{
if (*pz <= (izi >> 16))
{
if (foguse)
*r_turb_pdest = foggmap[menumap[*r_turb_pdest][gmcol] + (ferg >> 2 & 0xFF00)];
else
*r_turb_pdest = menumap[*r_turb_pdest][gmcol];
}
*r_turb_pdest++;
izi += izistep;
pz++;
} while (--r_turb_spancount > 0);
}
void D_DrawGelWaterSpanRefractions (void)
{
int refsturb, reftturb;
int refractsturb, refracttturb;
int pixsize = 2;
unsigned char temp, tempd2, tempd3, temp3, temp4;
depthen = (depthen) >> 2;
do
{
if (*pz <= (izi >> 16))
{
refractsturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)] * 4)>>16)&16;
refracttturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)] * 4)>>16)&16;
tempd3 = transTable[*(r_turb_pdest + ((refracttturb)+refractsturb >> 2))][*(r_turb_pdest+((refractsturb) + refracttturb >> 2))];
temp3 = tempd3;
if (foguse)
*r_turb_pdest = foggmap[menumap[temp3][gmcol] + (ferg >> 2 & 0xFF00)];
else
*r_turb_pdest = menumap[temp3][gmcol];
}
*r_turb_pdest++;
izi += izistep;
pz++;
r_turb_s += r_turb_sstep;
r_turb_t += r_turb_tstep;
} while (--r_turb_spancount > 0);
}
extern cvar_t *r_waterblend;
/*
=============
Turbulent8
=============
*/
extern int waterinsight; // leilei - water pixel shader
extern vec3_t reflectorg; // leilei - water reflection
extern cvar_t *r_wateralpha;
void Turbulent8 (espan_t *pspan)
{
int count;
fixed16_t snext, tnext;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivz16stepu, tdivz16stepu, zi16stepu;
int wb;
int gelmode;
int watqual;
float zer;
wb = (int)r_waterblend->value;
if (wb == 3 || r_wateralpha->value < 1)
gelmode = 1; // leilei - skip the turb crap when in gelmode
watqual = (int)r_waterquality->value;
r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
r_turb_sstep = 0; // keep compiler happy
r_turb_tstep = 0; // ditto
r_turb_pbase = (unsigned char *)cacheblock;
sdivz16stepu = d_sdivzstepu * 16;
tdivz16stepu = d_tdivzstepu * 16;
zi16stepu = d_zistepu * 16;
// mk transwater - begin
// we count on FP exceptions being turned off to avoid range problems
izistep = (int)(d_zistepu * 0x8000 * 0x10000);
izistep2 = izistep*2;
// mk transwater - end
// leilei - this is for the simple water
// reuses our menu background tables to blend it
// finds the nearest 'average' color from the color index
if (wb == 3){
// old values: 57 (breaks e3m1 slime/teleport),
//
gmcol = r_turb_pbase[2836]; // sample a pixel (TODO: Average a pixel on load)
if (gmcol < 16) gmcol = 0;
else if (gmcol < 32) gmcol = 1;
else if (gmcol < 48) gmcol = 2;
else if (gmcol < 64) gmcol = 3;
else if (gmcol < 80) gmcol = 4;
else if (gmcol < 96) gmcol = 5;
else if (gmcol < 112) gmcol = 6;
else if (gmcol < 128) gmcol = 7;
else if (gmcol < 144) gmcol = 8;
else if (gmcol < 160) gmcol = 9;
else if (gmcol < 176) gmcol = 10;
else if (gmcol < 192) gmcol = 11;
else if (gmcol < 208) gmcol = 12;
else if (gmcol < 224) gmcol = 13; // stupid elses huh?
else if (gmcol < 240) gmcol = 14;
else gmcol = 2; // stupid.
}
do
{
r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; // mk - transwater
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
// we count on FP exceptions being turned off to avoid range problems // mk transwoter
izi = (int)(zi * 0x8000 * 0x10000); // mk transwarter
r_turb_s = (int)(sdivz * z) + sadjust;
if (r_turb_s > bbextents)
r_turb_s = bbextents;
else if (r_turb_s < 0)
r_turb_s = 0;
r_turb_t = (int)(tdivz * z) + tadjust;
if (r_turb_t > bbextentt)
r_turb_t = bbextentt;
else if (r_turb_t < 0)
r_turb_t = 0;
do
{
// calculate s and t at the far end of the span
if (count >= 16)
r_turb_spancount = 16;
else
r_turb_spancount = count;
count -= r_turb_spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivz16stepu;
tdivz += tdivz16stepu;
zi += zi16stepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
r_turb_sstep = (snext - r_turb_s) >> 4;
r_turb_tstep = (tnext - r_turb_t) >> 4;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(r_turb_spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
if (r_turb_spancount > 1)
{
r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
}
}
r_turb_s = r_turb_s & ((CYCLE<<16)-1);
r_turb_t = r_turb_t & ((CYCLE<<16)-1);
if (foguse){ ferg = (int)(z / 1024); if (ferg > 32762) ferg = 32762; } // leilei - fog
depthen = (int)z / 1024;
// skip_turb:
// mk transwater begin
// leilei modified this to accomodate our waterTable
// TODO: for hlbsp, use the rendertype/renderamt stuff
// and add/transtable instead of watertable
if (r_wateralpha->value < 1){
if (r_drawwater){
if (watqual){
if (wb == 3){
D_DrawGelWaterSpanRefractions ();
}
else{
D_DrawTurbulent8SpanAlphaRefractions ();
}
}
else
{
if (wb == 3){
D_DrawGelWaterSpan ();
}
else{
D_DrawTurbulent8SpanAlpha ();
}
}
}
}
else
{
if (foguse){
D_DrawTurbulent8Span_Fog ();
} else {
D_DrawTurbulent8Span ();
}
}
r_turb_s = snext;
r_turb_t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
#if !id386
/*
=============
D_DrawSpans8
=============
*/
void D_DrawSpans8 (espan_t *pspan)
{
int count, spancount;
unsigned char *pbase, *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivz8stepu, tdivz8stepu, zi8stepu;
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivz8stepu = d_sdivzstepu * 8;
tdivz8stepu = d_tdivzstepu * 8;
zi8stepu = d_zistepu * 8;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
if (count >= 8)
spancount = 8;
else
spancount = count;
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivz8stepu;
tdivz += tdivz8stepu;
zi += zi8stepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
sstep = (snext - s) >> 3;
tstep = (tnext - t) >> 3;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
}
pdest += spancount;
switch (spancount)
{
case 8: pdest[-8] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 7: pdest[-7] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 6: pdest[-6] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 5: pdest[-5] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 4: pdest[-4] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 3: pdest[-3] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 2: pdest[-2] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 1: pdest[-1] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
}
s = snext;
t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
#endif
/*
=============
D_DrawSpans
qbism/mh
=============
*/
void D_DrawSpans16_C (espan_t *pspan) //qbism up it from 8 to 16. This + unroll = big speed gain!
{
int count, spancount;
unsigned char *pbase, *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivzstepu, tdivzstepu, zistepu;
int forg= 0; // leilei - fog
// float zf; // leilei - fog
// int fogcount, fogcount2; // leilei - fog
int beep = 512;
int boop = 512;
int feg = 0;
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivzstepu = d_sdivzstepu * 16;
tdivzstepu = d_tdivzstepu * 16;
zistepu = d_zistepu * 16;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// fogcount2 = count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
spancount = count > 15 ? 16 : count; // mh
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivzstepu;
tdivz += tdivzstepu;
zi += zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext <= 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
feg++;
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
sstep = (snext - s) >> 4;
tstep = (tnext - t) >> 4;
feg++;
if (foguse){ int te;
forg = (int)(z / 1024);
if (forg > 32762) forg = 32762; } // leilei - fog
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
feg++;
}
if (foguse){ int te;
forg = (int)(z / 1024);
if (forg > 32762) forg = 32762;
} // leilei - fog
//qbism- Duff's Device loop unroll per mh.
pdest += spancount;
if (foguse){
switch (spancount)
{
case 16: pdest[-16] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 15: pdest[-15] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg + 512 >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 14: pdest[-14] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 13: pdest[-13] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg + 512 >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 12: pdest[-12] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 11: pdest[-11] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg + 512 >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 10: pdest[-10] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 9: pdest[-9] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg + 512 >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 8: pdest[-8] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 7: pdest[-7] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg + 512 >> 2 & 0xFF00)]; s += sstep; t += tstep;;
case 6: pdest[-6] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 5: pdest[-5] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg + 512 >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 4: pdest[-4] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 3: pdest[-3] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg + 512 >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 2: pdest[-2] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)]; s += sstep; t += tstep;
case 1: pdest[-1] = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg + 512 >> 2 & 0xFF00)]; s += sstep; t += tstep;
}
}
else
{
switch (spancount)
{
case 16: pdest[-16] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 15: pdest[-15] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 14: pdest[-14] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 13: pdest[-13] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 12: pdest[-12] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 11: pdest[-11] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 10: pdest[-10] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 9: pdest[-9] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 8: pdest[-8] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 7: pdest[-7] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 6: pdest[-6] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 5: pdest[-5] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 4: pdest[-4] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 3: pdest[-3] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 2: pdest[-2] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 1: pdest[-1] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
}
}
s = snext;
t = tnext;
if(beep){ boop =512; beep = 0; }
else if(boop){ beep =512; boop = 0; }
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
void D_DrawSpansBlank (espan_t *pspan) //Blank version
{
int count, spancount;
unsigned char *pbase, *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivzstepu, tdivzstepu, zistepu;
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivzstepu = d_sdivzstepu * 16;
tdivzstepu = d_tdivzstepu * 16;
zistepu = d_zistepu * 16;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
spancount = count > 15 ? 16 : count; // mh
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivzstepu;
tdivz += tdivzstepu;
zi += zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext <= 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
sstep = (snext - s) >> 4;
tstep = (tnext - t) >> 4;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
}
//qbism- Duff's Device loop unroll per mh.
pdest += spancount;
switch (spancount)
{
case 16: pdest[-16] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 15: pdest[-15] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 14: pdest[-14] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 13: pdest[-13] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 12: pdest[-12] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 11: pdest[-11] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 10: pdest[-10] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 9: pdest[-9] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 8: pdest[-8] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 7: pdest[-7] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 6: pdest[-6] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 5: pdest[-5] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 4: pdest[-4] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 3: pdest[-3] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 2: pdest[-2] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
case 1: pdest[-1] = pbase[(s >> 16) + (t >> 16) * cachewidth]; s += sstep; t += tstep;
}
s = snext;
t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
/*
=============
D_DrawSpans
qbism/mh
=============
*/
/*
=============
D_DrawSpans8_C_Filter
Code adapted from Fabien Sanglard's Quake2 port
adds filtering from https://github.com/fabiensanglard/Quake-2/tree/master/ref_soft
=============
*/
int kernel[2][2][2] =
{
{
{16384, 0},
{49152, 16384}
},
{
{32768, 49152},
{0, 32768}
}
};
int gernel[2][11][2] =
{
{
{16384, 0},
{16384, 32},
{16384, 64},
{16384, 128},
{16384, 256},
{49152, 512},
{49152, 1024},
{49152, 2048},
{49152, 4096},
{49152, 8192},
{49152, 16384}
},
{
{32768, 49152},
{0, 32768}
}
};
void D_DrawSpans8_C_Filter (espan_t *pspan)
{
int count, spancount;
unsigned char *pbase, *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivz8stepu, tdivz8stepu, zi8stepu;
int forg; // leilei - fog
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivz8stepu = d_sdivzstepu * 8;
tdivz8stepu = d_tdivzstepu * 8;
zi8stepu = d_zistepu * 8;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
spancount = count > 7 ? 8 : count; // mh
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivz8stepu;
tdivz += tdivz8stepu;
zi += zi8stepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
sstep = (snext - s) >> 3;
tstep = (tnext - t) >> 3;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
}
if (foguse){ forg = (int)(z / 1024); if (forg > 32762) forg = 32762; } // leilei - fog
do
{
int idiths = s;
int iditht = t;
int X = (pspan->u + spancount) & 1;
int Y = (pspan->v)&1;
idiths += kernel[X][Y][0];
iditht += kernel[X][Y][1];
idiths = idiths >> 16;
idiths = idiths ? idiths -1 : idiths;
iditht = iditht >> 16;
iditht = iditht ? iditht -1 : iditht;
*pdest++ = *(pbase + idiths + iditht * cachewidth);
s += sstep;
t += tstep;
} while (--spancount > 0);
s = snext;
t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
// leilei experimental rendering
#ifdef EXPREND
void D_DrawDeferredSpans8_C (espan_t *pspan)
{
int count, spancount;
unsigned char *pbase, *pdest, *pshadow;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivz8stepu, tdivz8stepu, zi8stepu;
int forg; // leilei - fog
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivz8stepu = d_sdivzstepu * 8;
tdivz8stepu = d_tdivzstepu * 8;
zi8stepu = d_zistepu * 8;
do
{
// pdest = (unsigned char *)((byte *)d_viewbuffer +
// (screenwidth * pspan->v) + pspan->u);
pdest = (unsigned char *)((byte *)d_shadowbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
spancount = count > 7 ? 8 : count; // mh
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivz8stepu;
tdivz += tdivz8stepu;
zi += zi8stepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
sstep = (snext - s) >> 3;
tstep = (tnext - t) >> 3;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
}
if (foguse){ forg = (int)(z / 1024); if (forg > 32762) forg = 32762; } // leilei - fog
do
{
int idiths = s;
int iditht = t;
int X = (pspan->u + spancount) & 1;
int Y = (pspan->v)&1;
idiths += kernel[X][Y][0];
iditht += kernel[X][Y][1];
idiths = idiths >> 16;
idiths = idiths ? idiths -1 : idiths;
iditht = iditht >> 16;
iditht = iditht ? iditht -1 : iditht;
*pdest++ = *(pbase + idiths + iditht * cachewidth);
s += sstep;
t += tstep;
} while (--spancount > 0);
s = snext;
t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
#endif
// leilei experiment
void D_DrawSpans8_C_FilterAlter (espan_t *pspan)
{
int count, spancount;
unsigned char *pbase, *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivz8stepu, tdivz8stepu, zi8stepu;
int forg; // leilei - fog
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivz8stepu = d_sdivzstepu * 8;
tdivz8stepu = d_tdivzstepu * 8;
zi8stepu = d_zistepu * 8;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
spancount = count > 7 ? 8 : count; // mh
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivz8stepu;
tdivz += tdivz8stepu;
zi += zi8stepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
sstep = (snext - s) >> 3;
tstep = (tnext - t) >> 3;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
}
if (foguse){ forg = (int)(z / 1024); if (forg > 32762) forg = 32762; } // leilei - fog
do
{
int idiths = s;
int iditht = t;
int there;
int teem = temp2->value;
int X = (pspan->u + spancount) & 1;
int Y = (pspan->v)&1;
idiths += kernel[X][Y][0];
iditht += kernel[X][Y][1];
// idiths += noisetable[X>>teem][Y];
// iditht += noisetable[Y<<teem][X];
idiths = idiths >> 16;
// idiths = idiths ? idiths -teem : idiths;
// there = teem >> 16;
iditht = iditht >> 16;
// iditht = iditht ? iditht -teem : iditht;
*pdest++ = *(pbase + 0 * cachewidth);
s += sstep;
t += tstep;
} while (--spancount > 0);
s = snext;
t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
extern qboolean r_dowarp;
extern int r_docrap;
extern byte *r_warpbuffer;
/*
=============
D_DrawSpans16_C_Filter
Code adapted from Fabien Sanglard's Quake2 port
adds filtering from https://github.com/fabiensanglard/Quake-2/tree/master/ref_soft
=============
*/
// leilei - macrofying attempt.........
#define SurfaceSpancount16(i) { switch (spancount) { case 16: i(16); case 15: i(15); case 14: i(14); case 13: i(13); case 12: i(12); case 11: i(11); case 10: i(10); case 9: i(9); case 8: i(8); case 7: i(7); case 6: i(6); case 5: i(5); case 4: i(4); case 3: i(3); case 2: i(2); case 1: i(1); } }
void D_DrawSpans16_C_Filter (espan_t *pspan) //qbism- up it from 8 to 16
{
int count, spancount;
unsigned char *pbase, *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivzstepu, tdivzstepu, zistepu;
int idiths, iditht, X, Y; // filter stuff
int forg= 0; // leilei - fog
int beep, boop, bap;
int fogra = 0;
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivzstepu = d_sdivzstepu * 16;
tdivzstepu = d_tdivzstepu * 16;
zistepu = d_zistepu * 16;
bap = 1;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
spancount = count > 15 ? 16 : count; // mh
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivzstepu;
tdivz += tdivzstepu;
zi += zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext <= 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
sstep = (snext - s) >> 4;
tstep = (tnext - t) >> 4;
bap *= -1;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
bap *= -1;
}
if (foguse){ forg = (int)((float)0x10000 / zi / 1024); if (forg > 32762) forg = 32762; }
beep = 0;
boop = 256 * bap;
// if spans are far apart, filter.
pdest += spancount;
#define SUBDIV16FILTERFOG(i) { idiths = s; iditht = t; X = (pspan->u + i) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths; iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; pdest[-i] = foggmap[*(pbase + idiths + iditht * cachewidth) + (forg + boop >> 2 & 0xFF00)]; s += sstep; t += tstep; boop *= -1; }
#define SUBDIV16FILTERFOGDITHER(i) { idiths = s; iditht = t; X = (pspan->u + i) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths; iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; pdest[-i] = foggmap[*(pbase + idiths + iditht * cachewidth) + (smoothtable[forg][i] >> 2 & 0xFF00)]; s += sstep; t += tstep; }
#define SUBDIV16FILTERNOFOG(i) { idiths = s; iditht = t; X = (pspan->u + i) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths; iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; pdest[-i] = *(pbase + idiths + iditht * cachewidth); s += sstep; t += tstep; }
if (foguse == 2){
SurfaceSpancount16(SUBDIV16FILTERFOGDITHER);
}
else if (foguse){
SurfaceSpancount16(SUBDIV16FILTERFOG);
} else{
SurfaceSpancount16(SUBDIV16FILTERNOFOG);
}
s = snext;
t = tnext;
// if(beep){ boop =256; beep = 0; }
// else if(boop){ beep =256; boop = 0; }
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
void D_DrawSpans16_C_Filter_64 (espan_t *pspan) //qbism- up it from 8 to 16
{
int count, spancount;
unsigned char *pbase, *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivzstepu, tdivzstepu, zistepu;
int idiths, iditht, X, Y; // filter stuff
int forg= 0; // leilei - fog
int beep, boop, bap;
int fogra = 0;
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivzstepu = d_sdivzstepu * 16;
tdivzstepu = d_tdivzstepu * 16;
zistepu = d_zistepu * 16;
bap = 1;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
spancount = count > 15 ? 16 : count; // mh
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivzstepu;
tdivz += tdivzstepu;
zi += zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext <= 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
sstep = (snext - s) >> 4;
tstep = (tnext - t) >> 4;
bap *= -1;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
bap *= -1;
}
if (foguse){ forg = (int)((float)0x10000 / zi / 1024); if (forg > 32762) forg = 32762; }
beep = 0;
boop = 256 * bap;
// if spans are far apart, filter.
pdest += spancount;
#define SUBDIV1664FILTERFOG(i) { idiths = s; iditht = t; X = (pspan->u + i) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][0]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths; iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; pdest[-i] = foggmap[*(pbase + idiths + iditht * cachewidth) + (forg + boop >> 2 & 0xFF00)]; s += sstep; t += tstep; boop *= -1; }
#define SUBDIV1664FILTERFOGDITHER(i) { idiths = s; iditht = t; X = (pspan->u + i) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][0]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths; iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; pdest[-i] = foggmap[*(pbase + idiths + iditht * cachewidth) + (smoothtable[forg][i] >> 2 & 0xFF00)]; s += sstep; t += tstep; }
#define SUBDIV1664FILTERNOFOG(i) { idiths = s; iditht = t; X = (pspan->u + i) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][0]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths; iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; pdest[-i] = *(pbase + idiths + iditht * cachewidth); s += sstep; t += tstep; }
if (foguse == 2){
SurfaceSpancount16(SUBDIV1664FILTERFOGDITHER);
}
else if (foguse){
SurfaceSpancount16(SUBDIV1664FILTERFOG);
} else{
SurfaceSpancount16(SUBDIV1664FILTERNOFOG);
}
s = snext;
t = tnext;
// if(beep){ boop =256; beep = 0; }
// else if(boop){ beep =256; boop = 0; }
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
void D_DrawSpans16_C_Dither (espan_t *pspan) //qbism up it from 8 to 16. This + unroll = big speed gain!
{
int count, spancount;
unsigned char *pbase, *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivzstepu, tdivzstepu, zistepu;
int n;
int forg= 0; // leilei - fog
unsigned char fogg[3];
unsigned short *src;
pbase = (unsigned char *)cacheblock;
sdivzstepu = d_sdivzstepu * 16;
tdivzstepu = d_tdivzstepu * 16;
zistepu = d_zistepu * 16;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
// if (count >= 16)
// spancount = 16;
// else
// spancount = count;
spancount = count > 15 ? 16 : count;
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivzstepu;
tdivz += tdivzstepu;
zi += zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext <= 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
sstep = (snext - s) >> 4;
tstep = (tnext - t) >> 4;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
}
n = ((pspan->v & 1) << 1) | (pspan->u & 1);
pdest += spancount;
if (foguse){ forg = (int)(z / 1024); if (forg > 32762) forg = 32762;
//forgf = forg / 32768; // get down to the 1.0's
} // leilei - fog
if(foguse){
switch (spancount)
{
case 16: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-16] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 15: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-15] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 14: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-14] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 13: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-13] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 12: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-12] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 11: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-11] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 10: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-10] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 9: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-9] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 8: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-8] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 7: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-7] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 6: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-6] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 5: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-5] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 4: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-4] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 3: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-3] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 2: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-2] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
case 1: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-1] = foggmap[ditherTable[*src & 0x7FFF][n] + (forg >> 2 & 0xFF00)]; n ^= 1; s += sstep; t += tstep;
}
}
else
{
switch (spancount)
{
#ifdef THIRTYTWOBITHACK
case 16: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-16] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 15: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-15] = *src & 0x7F00; n ^= 1; s += sstep; t += tstep;
case 14: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-14] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 13: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-13] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 12: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-12] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 11: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-11] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 10: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-10] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 9: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-9] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 8: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-8] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 7: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-7] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 6: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-6] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 5: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-5] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 4: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-4] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 3: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-3] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 2: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-2] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
case 1: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-1] = *src & 0x7FFF; n ^= 1; s += sstep; t += tstep;
#else
case 16: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-16] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 15: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-15] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 14: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-14] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 13: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-13] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 12: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-12] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 11: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-11] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 10: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-10] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 9: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-9] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 8: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-8] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 7: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-7] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 6: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-6] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 5: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-5] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 4: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-4] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 3: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-3] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 2: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-2] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 1: src = (unsigned short *)pbase; src += (s >> 16) + (t >> 16) * cachewidth; pdest[-1] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
#endif
}
}
s = snext;
t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
void D_DrawSpans16_C_Dither_Filter (espan_t *pspan) //the slowest spans on earth.
{
int count, spancount;
unsigned char *pbase, *pdest;
unsigned short *src;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivzstepu, tdivzstepu, zistepu;
int n;
int idiths, iditht, X, Y; // filter stuff
int forg; // leilei - fog
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivzstepu = d_sdivzstepu * 16;
tdivzstepu = d_tdivzstepu * 16;
zistepu = d_zistepu * 16;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
s = s > bbextents ? bbextents : (s < 0 ? 0 : s);
t = (int)(tdivz * z) + tadjust;
t = t > bbextentt ? bbextentt : (t < 0 ? 0 : t);
do
{
// calculate s and t at the far end of the span
spancount = count > 15 ? 16 : count;
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivzstepu;
tdivz += tdivzstepu;
zi += zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext <= 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
sstep = (snext - s) >> 4;
tstep = (tnext - t) >> 4;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 16)
snext = 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 16)
tnext = 16; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
}
n = ((pspan->v & 1) << 1) | (pspan->u & 1);
if (foguse){ forg = (int)(z / 1024); if (forg > 32762) forg = 32762; } // leilei - fog
pdest += spancount;
switch (spancount)
{
case 16: idiths = s; iditht = t; X = (pspan->u + 16) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-16] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 15: idiths = s; iditht = t; X = (pspan->u + 15) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-15] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 14: idiths = s; iditht = t; X = (pspan->u + 14) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-14] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 13: idiths = s; iditht = t; X = (pspan->u + 13) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-13] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 12: idiths = s; iditht = t; X = (pspan->u + 12) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-12] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 11: idiths = s; iditht = t; X = (pspan->u + 11) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-11] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 10: idiths = s; iditht = t; X = (pspan->u + 10) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-10] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 9: idiths = s; iditht = t; X = (pspan->u + 9) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-9] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 8: idiths = s; iditht = t; X = (pspan->u + 8) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-8] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 7: idiths = s; iditht = t; X = (pspan->u + 7) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-7] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 6: idiths = s; iditht = t; X = (pspan->u + 6) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-6] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 5: idiths = s; iditht = t; X = (pspan->u + 5) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-5] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 4: idiths = s; iditht = t; X = (pspan->u + 4) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-4] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 3: idiths = s; iditht = t; X = (pspan->u + 3) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-3] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 2: idiths = s; iditht = t; X = (pspan->u + 2) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-2] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
case 1: idiths = s; iditht = t; X = (pspan->u + 1) & 1; Y = (pspan->v)& 1; idiths += kernel[X][Y][0]; iditht += kernel[X][Y][1]; idiths = idiths >> 16; idiths = idiths ? idiths -1: idiths;
iditht = iditht >> 16; iditht = iditht ? iditht -1 : iditht; src = (unsigned short *)pbase; src += idiths + iditht * cachewidth; pdest[-1] = ditherTable[*src & 0x7FFF][n]; n ^= 1; s += sstep; t += tstep;
}
s = snext;
t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
extern cvar_t *temp2;
// Bilinear filtering from flquake
void D_DrawSpans8_C_Bilinear (espan_t *pspan)
{
int count, spancount;
unsigned char *pbase, *pdest;
fixed16_t s, t, snext, tnext, sstep, tstep;
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
float sdivz8stepu, tdivz8stepu, zi8stepu;
int forg = 0; // leilei - fog
sstep = 0; // keep compiler happy
tstep = 0; // ditto
pbase = (unsigned char *)cacheblock;
sdivz8stepu = d_sdivzstepu * 8;
tdivz8stepu = d_tdivzstepu * 8;
zi8stepu = d_zistepu * 8;
do
{
pdest = (unsigned char *)((byte *)d_viewbuffer +
(screenwidth * pspan->v) + pspan->u);
count = pspan->count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
du = (float)pspan->u;
dv = (float)pspan->v;
sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
s = (int)(sdivz * z) + sadjust;
if (s > bbextents)
s = bbextents;
else if (s < 0)
s = 0;
t = (int)(tdivz * z) + tadjust;
if (t > bbextentt)
t = bbextentt;
else if (t < 0)
t = 0;
do
{
// calculate s and t at the far end of the span
spancount = count > 7 ? 8 : count; // mh
count -= spancount;
if (count)
{
// calculate s/z, t/z, zi->fixed s and t at far end of span,
// calculate s and t steps across span by shifting
sdivz += sdivz8stepu;
tdivz += tdivz8stepu;
zi += zi8stepu;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
sstep = (snext - s) >> 3;
tstep = (tnext - t) >> 3;
}
else
{
// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
spancountminus1 = (float)(spancount - 1);
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < 8)
snext = 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < 8)
tnext = 8; // guard against round-off error on <0 steps
if (spancount > 1)
{
sstep = (snext - s) / (spancount - 1);
tstep = (tnext - t) / (spancount - 1);
}
}
if (foguse){ forg = (int)(z / 1024); if (forg > 32762) forg = 32762; } // leilei - fog
do
{
if (foguse) // leilei - fogged case
*pdest++ = foggmap[pbase[(s >> 16) + (t >> 16) * cachewidth] + (forg >> 2 & 0xFF00)];
else
*pdest++ = pbase[(s >> 16) + (t >> 16) * cachewidth];
s += sstep; t += tstep;
} while (--spancount > 0);
s = snext;
t = tnext;
} while (count > 0);
} while ((pspan = pspan->pnext) != NULL);
}
#if !id386
/*
=============
D_DrawZSpans
=============
*/
void D_DrawZSpans (espan_t *pspan)
{
int count, doublecount, izistep;
int izi;
short *pdest;
unsigned ltemp;
double zi;
float du, dv;
// FIXME: check for clamping/range problems
// we count on FP exceptions being turned off to avoid range problems
izistep = (int)(d_zistepu * 0x8000 * 0x10000);
do
{
pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
count = pspan->count;
// calculate the initial 1/z
du = (float)pspan->u;
dv = (float)pspan->v;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
// we count on FP exceptions being turned off to avoid range problems
izi = (int)(zi * 0x8000 * 0x10000);
if ((long)pdest & 0x02)
{
*pdest++ = (short)(izi >> 16);
izi += izistep;
count--;
}
if ((doublecount = count >> 1) > 0)
{
do
{
ltemp = izi >> 16;
izi += izistep;
ltemp |= izi & 0xFFFF0000;
izi += izistep;
*(int *)pdest = ltemp;
pdest += 2;
} while (--doublecount > 0);
}
if (count & 1)
*pdest = (short)(izi >> 16);
} while ((pspan = pspan->pnext) != NULL);
}
#endif