mirror of
https://git.code.sf.net/p/quake/quakeforge-old
synced 2024-11-25 13:21:04 +00:00
Another merge from BigM
This commit is contained in:
parent
244297cedc
commit
740177b2c0
8 changed files with 0 additions and 2169 deletions
|
@ -1,446 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
#include "d_local.h"
|
||||
|
||||
unsigned char *r_turb_pbase, *r_turb_pdest;
|
||||
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);
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
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[1024];
|
||||
int column[1280];
|
||||
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 = intsintable + ((int)(cl.time*SPEED)&(CYCLE-1));
|
||||
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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
/*
|
||||
=============
|
||||
Turbulent8
|
||||
=============
|
||||
*/
|
||||
void Turbulent8 (espan_t *pspan)
|
||||
{
|
||||
int count;
|
||||
fixed16_t snext, tnext;
|
||||
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
|
||||
float sdivz16stepu, tdivz16stepu, zi16stepu;
|
||||
|
||||
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;
|
||||
|
||||
do
|
||||
{
|
||||
r_turb_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
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
*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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#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
|
|
@ -1,908 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
// r_draw.c
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
#include "d_local.h" // FIXME: shouldn't need to include this
|
||||
|
||||
#define MAXLEFTCLIPEDGES 100
|
||||
|
||||
// !!! if these are changed, they must be changed in asm_draw.h too !!!
|
||||
#define FULLY_CLIPPED_CACHED 0x80000000
|
||||
#define FRAMECOUNT_MASK 0x7FFFFFFF
|
||||
|
||||
unsigned int cacheoffset;
|
||||
|
||||
int c_faceclip; // number of faces clipped
|
||||
|
||||
zpointdesc_t r_zpointdesc;
|
||||
|
||||
polydesc_t r_polydesc;
|
||||
|
||||
|
||||
|
||||
clipplane_t *entity_clipplanes;
|
||||
clipplane_t view_clipplanes[4];
|
||||
clipplane_t world_clipplanes[16];
|
||||
|
||||
medge_t *r_pedge;
|
||||
|
||||
qboolean r_leftclipped, r_rightclipped;
|
||||
static qboolean makeleftedge, makerightedge;
|
||||
qboolean r_nearzionly;
|
||||
|
||||
int sintable[1280];
|
||||
int intsintable[1280];
|
||||
|
||||
mvertex_t r_leftenter, r_leftexit;
|
||||
mvertex_t r_rightenter, r_rightexit;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float u,v;
|
||||
int ceilv;
|
||||
} evert_t;
|
||||
|
||||
int r_emitted;
|
||||
float r_nearzi;
|
||||
float r_u1, r_v1, r_lzi1;
|
||||
int r_ceilv1;
|
||||
|
||||
qboolean r_lastvertvalid;
|
||||
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
================
|
||||
R_EmitEdge
|
||||
================
|
||||
*/
|
||||
void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
|
||||
{
|
||||
edge_t *edge, *pcheck;
|
||||
int u_check;
|
||||
float u, u_step;
|
||||
vec3_t local, transformed;
|
||||
float *world;
|
||||
int v, v2, ceilv0;
|
||||
float scale, lzi0, u0, v0;
|
||||
int side;
|
||||
|
||||
if (r_lastvertvalid)
|
||||
{
|
||||
u0 = r_u1;
|
||||
v0 = r_v1;
|
||||
lzi0 = r_lzi1;
|
||||
ceilv0 = r_ceilv1;
|
||||
}
|
||||
else
|
||||
{
|
||||
world = &pv0->position[0];
|
||||
|
||||
// transform and project
|
||||
VectorSubtract (world, modelorg, local);
|
||||
TransformVector (local, transformed);
|
||||
|
||||
if (transformed[2] < NEAR_CLIP)
|
||||
transformed[2] = NEAR_CLIP;
|
||||
|
||||
lzi0 = 1.0 / transformed[2];
|
||||
|
||||
// FIXME: build x/yscale into transform?
|
||||
scale = xscale * lzi0;
|
||||
u0 = (xcenter + scale*transformed[0]);
|
||||
if (u0 < r_refdef.fvrectx_adj)
|
||||
u0 = r_refdef.fvrectx_adj;
|
||||
if (u0 > r_refdef.fvrectright_adj)
|
||||
u0 = r_refdef.fvrectright_adj;
|
||||
|
||||
scale = yscale * lzi0;
|
||||
v0 = (ycenter - scale*transformed[1]);
|
||||
if (v0 < r_refdef.fvrecty_adj)
|
||||
v0 = r_refdef.fvrecty_adj;
|
||||
if (v0 > r_refdef.fvrectbottom_adj)
|
||||
v0 = r_refdef.fvrectbottom_adj;
|
||||
|
||||
ceilv0 = (int) ceil(v0);
|
||||
}
|
||||
|
||||
world = &pv1->position[0];
|
||||
|
||||
// transform and project
|
||||
VectorSubtract (world, modelorg, local);
|
||||
TransformVector (local, transformed);
|
||||
|
||||
if (transformed[2] < NEAR_CLIP)
|
||||
transformed[2] = NEAR_CLIP;
|
||||
|
||||
r_lzi1 = 1.0 / transformed[2];
|
||||
|
||||
scale = xscale * r_lzi1;
|
||||
r_u1 = (xcenter + scale*transformed[0]);
|
||||
if (r_u1 < r_refdef.fvrectx_adj)
|
||||
r_u1 = r_refdef.fvrectx_adj;
|
||||
if (r_u1 > r_refdef.fvrectright_adj)
|
||||
r_u1 = r_refdef.fvrectright_adj;
|
||||
|
||||
scale = yscale * r_lzi1;
|
||||
r_v1 = (ycenter - scale*transformed[1]);
|
||||
if (r_v1 < r_refdef.fvrecty_adj)
|
||||
r_v1 = r_refdef.fvrecty_adj;
|
||||
if (r_v1 > r_refdef.fvrectbottom_adj)
|
||||
r_v1 = r_refdef.fvrectbottom_adj;
|
||||
|
||||
if (r_lzi1 > lzi0)
|
||||
lzi0 = r_lzi1;
|
||||
|
||||
if (lzi0 > r_nearzi) // for mipmap finding
|
||||
r_nearzi = lzi0;
|
||||
|
||||
// for right edges, all we want is the effect on 1/z
|
||||
if (r_nearzionly)
|
||||
return;
|
||||
|
||||
r_emitted = 1;
|
||||
|
||||
r_ceilv1 = (int) ceil(r_v1);
|
||||
|
||||
|
||||
// create the edge
|
||||
if (ceilv0 == r_ceilv1)
|
||||
{
|
||||
// we cache unclipped horizontal edges as fully clipped
|
||||
if (cacheoffset != 0x7FFFFFFF)
|
||||
{
|
||||
cacheoffset = FULLY_CLIPPED_CACHED |
|
||||
(r_framecount & FRAMECOUNT_MASK);
|
||||
}
|
||||
|
||||
return; // horizontal edge
|
||||
}
|
||||
|
||||
side = ceilv0 > r_ceilv1;
|
||||
|
||||
edge = edge_p++;
|
||||
|
||||
edge->owner = r_pedge;
|
||||
|
||||
edge->nearzi = lzi0;
|
||||
|
||||
if (side == 0)
|
||||
{
|
||||
// trailing edge (go from p1 to p2)
|
||||
v = ceilv0;
|
||||
v2 = r_ceilv1 - 1;
|
||||
|
||||
edge->surfs[0] = surface_p - surfaces;
|
||||
edge->surfs[1] = 0;
|
||||
|
||||
u_step = ((r_u1 - u0) / (r_v1 - v0));
|
||||
u = u0 + ((float)v - v0) * u_step;
|
||||
}
|
||||
else
|
||||
{
|
||||
// leading edge (go from p2 to p1)
|
||||
v2 = ceilv0 - 1;
|
||||
v = r_ceilv1;
|
||||
|
||||
edge->surfs[0] = 0;
|
||||
edge->surfs[1] = surface_p - surfaces;
|
||||
|
||||
u_step = ((u0 - r_u1) / (v0 - r_v1));
|
||||
u = r_u1 + ((float)v - r_v1) * u_step;
|
||||
}
|
||||
|
||||
edge->u_step = u_step*0x100000;
|
||||
edge->u = u*0x100000 + 0xFFFFF;
|
||||
|
||||
// we need to do this to avoid stepping off the edges if a very nearly
|
||||
// horizontal edge is less than epsilon above a scan, and numeric error causes
|
||||
// it to incorrectly extend to the scan, and the extension of the line goes off
|
||||
// the edge of the screen
|
||||
// FIXME: is this actually needed?
|
||||
if (edge->u < r_refdef.vrect_x_adj_shift20)
|
||||
edge->u = r_refdef.vrect_x_adj_shift20;
|
||||
if (edge->u > r_refdef.vrectright_adj_shift20)
|
||||
edge->u = r_refdef.vrectright_adj_shift20;
|
||||
|
||||
//
|
||||
// sort the edge in normally
|
||||
//
|
||||
u_check = edge->u;
|
||||
if (edge->surfs[0])
|
||||
u_check++; // sort trailers after leaders
|
||||
|
||||
if (!newedges[v] || newedges[v]->u >= u_check)
|
||||
{
|
||||
edge->next = newedges[v];
|
||||
newedges[v] = edge;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcheck = newedges[v];
|
||||
while (pcheck->next && pcheck->next->u < u_check)
|
||||
pcheck = pcheck->next;
|
||||
edge->next = pcheck->next;
|
||||
pcheck->next = edge;
|
||||
}
|
||||
|
||||
edge->nextremove = removeedges[v2];
|
||||
removeedges[v2] = edge;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_ClipEdge
|
||||
================
|
||||
*/
|
||||
void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
|
||||
{
|
||||
float d0, d1, f;
|
||||
mvertex_t clipvert;
|
||||
|
||||
if (clip)
|
||||
{
|
||||
do
|
||||
{
|
||||
d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
|
||||
d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
|
||||
|
||||
if (d0 >= 0)
|
||||
{
|
||||
// point 0 is unclipped
|
||||
if (d1 >= 0)
|
||||
{
|
||||
// both points are unclipped
|
||||
continue;
|
||||
}
|
||||
|
||||
// only point 1 is clipped
|
||||
|
||||
// we don't cache clipped edges
|
||||
cacheoffset = 0x7FFFFFFF;
|
||||
|
||||
f = d0 / (d0 - d1);
|
||||
clipvert.position[0] = pv0->position[0] +
|
||||
f * (pv1->position[0] - pv0->position[0]);
|
||||
clipvert.position[1] = pv0->position[1] +
|
||||
f * (pv1->position[1] - pv0->position[1]);
|
||||
clipvert.position[2] = pv0->position[2] +
|
||||
f * (pv1->position[2] - pv0->position[2]);
|
||||
|
||||
if (clip->leftedge)
|
||||
{
|
||||
r_leftclipped = true;
|
||||
r_leftexit = clipvert;
|
||||
}
|
||||
else if (clip->rightedge)
|
||||
{
|
||||
r_rightclipped = true;
|
||||
r_rightexit = clipvert;
|
||||
}
|
||||
|
||||
R_ClipEdge (pv0, &clipvert, clip->next);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// point 0 is clipped
|
||||
if (d1 < 0)
|
||||
{
|
||||
// both points are clipped
|
||||
// we do cache fully clipped edges
|
||||
if (!r_leftclipped)
|
||||
cacheoffset = FULLY_CLIPPED_CACHED |
|
||||
(r_framecount & FRAMECOUNT_MASK);
|
||||
return;
|
||||
}
|
||||
|
||||
// only point 0 is clipped
|
||||
r_lastvertvalid = false;
|
||||
|
||||
// we don't cache partially clipped edges
|
||||
cacheoffset = 0x7FFFFFFF;
|
||||
|
||||
f = d0 / (d0 - d1);
|
||||
clipvert.position[0] = pv0->position[0] +
|
||||
f * (pv1->position[0] - pv0->position[0]);
|
||||
clipvert.position[1] = pv0->position[1] +
|
||||
f * (pv1->position[1] - pv0->position[1]);
|
||||
clipvert.position[2] = pv0->position[2] +
|
||||
f * (pv1->position[2] - pv0->position[2]);
|
||||
|
||||
if (clip->leftedge)
|
||||
{
|
||||
r_leftclipped = true;
|
||||
r_leftenter = clipvert;
|
||||
}
|
||||
else if (clip->rightedge)
|
||||
{
|
||||
r_rightclipped = true;
|
||||
r_rightenter = clipvert;
|
||||
}
|
||||
|
||||
R_ClipEdge (&clipvert, pv1, clip->next);
|
||||
return;
|
||||
}
|
||||
} while ((clip = clip->next) != NULL);
|
||||
}
|
||||
|
||||
// add the edge
|
||||
R_EmitEdge (pv0, pv1);
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_EmitCachedEdge
|
||||
================
|
||||
*/
|
||||
void R_EmitCachedEdge (void)
|
||||
{
|
||||
edge_t *pedge_t;
|
||||
|
||||
pedge_t = (edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset);
|
||||
|
||||
if (!pedge_t->surfs[0])
|
||||
pedge_t->surfs[0] = surface_p - surfaces;
|
||||
else
|
||||
pedge_t->surfs[1] = surface_p - surfaces;
|
||||
|
||||
if (pedge_t->nearzi > r_nearzi) // for mipmap finding
|
||||
r_nearzi = pedge_t->nearzi;
|
||||
|
||||
r_emitted = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RenderFace
|
||||
================
|
||||
*/
|
||||
void R_RenderFace (msurface_t *fa, int clipflags)
|
||||
{
|
||||
int i, lindex;
|
||||
unsigned mask;
|
||||
mplane_t *pplane;
|
||||
float distinv;
|
||||
vec3_t p_normal;
|
||||
medge_t *pedges, tedge;
|
||||
clipplane_t *pclip;
|
||||
|
||||
// skip out if no more surfs
|
||||
if ((surface_p) >= surf_max)
|
||||
{
|
||||
r_outofsurfaces++;
|
||||
return;
|
||||
}
|
||||
|
||||
// ditto if not enough edges left, or switch to auxedges if possible
|
||||
if ((edge_p + fa->numedges + 4) >= edge_max)
|
||||
{
|
||||
r_outofedges += fa->numedges;
|
||||
return;
|
||||
}
|
||||
|
||||
c_faceclip++;
|
||||
|
||||
// set up clip planes
|
||||
pclip = NULL;
|
||||
|
||||
for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
|
||||
{
|
||||
if (clipflags & mask)
|
||||
{
|
||||
view_clipplanes[i].next = pclip;
|
||||
pclip = &view_clipplanes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// push the edges through
|
||||
r_emitted = 0;
|
||||
r_nearzi = 0;
|
||||
r_nearzionly = false;
|
||||
makeleftedge = makerightedge = false;
|
||||
pedges = currententity->model->edges;
|
||||
r_lastvertvalid = false;
|
||||
|
||||
for (i=0 ; i<fa->numedges ; i++)
|
||||
{
|
||||
lindex = currententity->model->surfedges[fa->firstedge + i];
|
||||
|
||||
if (lindex > 0)
|
||||
{
|
||||
r_pedge = &pedges[lindex];
|
||||
|
||||
// if the edge is cached, we can just reuse the edge
|
||||
if (!insubmodel)
|
||||
{
|
||||
if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
|
||||
{
|
||||
if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
|
||||
r_framecount)
|
||||
{
|
||||
r_lastvertvalid = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((((unsigned long)edge_p - (unsigned long)r_edges) >
|
||||
r_pedge->cachededgeoffset) &&
|
||||
(((edge_t *)((unsigned long)r_edges +
|
||||
r_pedge->cachededgeoffset))->owner == r_pedge))
|
||||
{
|
||||
R_EmitCachedEdge ();
|
||||
r_lastvertvalid = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// assume it's cacheable
|
||||
cacheoffset = (byte *)edge_p - (byte *)r_edges;
|
||||
r_leftclipped = r_rightclipped = false;
|
||||
R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]],
|
||||
&r_pcurrentvertbase[r_pedge->v[1]],
|
||||
pclip);
|
||||
r_pedge->cachededgeoffset = cacheoffset;
|
||||
|
||||
if (r_leftclipped)
|
||||
makeleftedge = true;
|
||||
if (r_rightclipped)
|
||||
makerightedge = true;
|
||||
r_lastvertvalid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
lindex = -lindex;
|
||||
r_pedge = &pedges[lindex];
|
||||
// if the edge is cached, we can just reuse the edge
|
||||
if (!insubmodel)
|
||||
{
|
||||
if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
|
||||
{
|
||||
if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
|
||||
r_framecount)
|
||||
{
|
||||
r_lastvertvalid = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// it's cached if the cached edge is valid and is owned
|
||||
// by this medge_t
|
||||
if ((((unsigned long)edge_p - (unsigned long)r_edges) >
|
||||
r_pedge->cachededgeoffset) &&
|
||||
(((edge_t *)((unsigned long)r_edges +
|
||||
r_pedge->cachededgeoffset))->owner == r_pedge))
|
||||
{
|
||||
R_EmitCachedEdge ();
|
||||
r_lastvertvalid = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// assume it's cacheable
|
||||
cacheoffset = (byte *)edge_p - (byte *)r_edges;
|
||||
r_leftclipped = r_rightclipped = false;
|
||||
R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]],
|
||||
&r_pcurrentvertbase[r_pedge->v[0]],
|
||||
pclip);
|
||||
r_pedge->cachededgeoffset = cacheoffset;
|
||||
|
||||
if (r_leftclipped)
|
||||
makeleftedge = true;
|
||||
if (r_rightclipped)
|
||||
makerightedge = true;
|
||||
r_lastvertvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if there was a clip off the left edge, add that edge too
|
||||
// FIXME: faster to do in screen space?
|
||||
// FIXME: share clipped edges?
|
||||
if (makeleftedge)
|
||||
{
|
||||
r_pedge = &tedge;
|
||||
r_lastvertvalid = false;
|
||||
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
|
||||
}
|
||||
|
||||
// if there was a clip off the right edge, get the right r_nearzi
|
||||
if (makerightedge)
|
||||
{
|
||||
r_pedge = &tedge;
|
||||
r_lastvertvalid = false;
|
||||
r_nearzionly = true;
|
||||
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
|
||||
}
|
||||
|
||||
// if no edges made it out, return without posting the surface
|
||||
if (!r_emitted)
|
||||
return;
|
||||
|
||||
r_polycount++;
|
||||
|
||||
surface_p->data = (void *)fa;
|
||||
surface_p->nearzi = r_nearzi;
|
||||
surface_p->flags = fa->flags;
|
||||
surface_p->insubmodel = insubmodel;
|
||||
surface_p->spanstate = 0;
|
||||
surface_p->entity = currententity;
|
||||
surface_p->key = r_currentkey++;
|
||||
surface_p->spans = NULL;
|
||||
|
||||
pplane = fa->plane;
|
||||
// FIXME: cache this?
|
||||
TransformVector (pplane->normal, p_normal);
|
||||
// FIXME: cache this?
|
||||
distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
|
||||
|
||||
surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
|
||||
surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
|
||||
surface_p->d_ziorigin = p_normal[2] * distinv -
|
||||
xcenter * surface_p->d_zistepu -
|
||||
ycenter * surface_p->d_zistepv;
|
||||
|
||||
//JDC VectorCopy (r_worldmodelorg, surface_p->modelorg);
|
||||
surface_p++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RenderBmodelFace
|
||||
================
|
||||
*/
|
||||
void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf)
|
||||
{
|
||||
int i;
|
||||
unsigned mask;
|
||||
mplane_t *pplane;
|
||||
float distinv;
|
||||
vec3_t p_normal;
|
||||
medge_t tedge;
|
||||
clipplane_t *pclip;
|
||||
|
||||
// skip out if no more surfs
|
||||
if (surface_p >= surf_max)
|
||||
{
|
||||
r_outofsurfaces++;
|
||||
return;
|
||||
}
|
||||
|
||||
// ditto if not enough edges left, or switch to auxedges if possible
|
||||
if ((edge_p + psurf->numedges + 4) >= edge_max)
|
||||
{
|
||||
r_outofedges += psurf->numedges;
|
||||
return;
|
||||
}
|
||||
|
||||
c_faceclip++;
|
||||
|
||||
// this is a dummy to give the caching mechanism someplace to write to
|
||||
r_pedge = &tedge;
|
||||
|
||||
// set up clip planes
|
||||
pclip = NULL;
|
||||
|
||||
for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
|
||||
{
|
||||
if (r_clipflags & mask)
|
||||
{
|
||||
view_clipplanes[i].next = pclip;
|
||||
pclip = &view_clipplanes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// push the edges through
|
||||
r_emitted = 0;
|
||||
r_nearzi = 0;
|
||||
r_nearzionly = false;
|
||||
makeleftedge = makerightedge = false;
|
||||
// FIXME: keep clipped bmodel edges in clockwise order so last vertex caching
|
||||
// can be used?
|
||||
r_lastvertvalid = false;
|
||||
|
||||
for ( ; pedges ; pedges = pedges->pnext)
|
||||
{
|
||||
r_leftclipped = r_rightclipped = false;
|
||||
R_ClipEdge (pedges->v[0], pedges->v[1], pclip);
|
||||
|
||||
if (r_leftclipped)
|
||||
makeleftedge = true;
|
||||
if (r_rightclipped)
|
||||
makerightedge = true;
|
||||
}
|
||||
|
||||
// if there was a clip off the left edge, add that edge too
|
||||
// FIXME: faster to do in screen space?
|
||||
// FIXME: share clipped edges?
|
||||
if (makeleftedge)
|
||||
{
|
||||
r_pedge = &tedge;
|
||||
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
|
||||
}
|
||||
|
||||
// if there was a clip off the right edge, get the right r_nearzi
|
||||
if (makerightedge)
|
||||
{
|
||||
r_pedge = &tedge;
|
||||
r_nearzionly = true;
|
||||
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
|
||||
}
|
||||
|
||||
// if no edges made it out, return without posting the surface
|
||||
if (!r_emitted)
|
||||
return;
|
||||
|
||||
r_polycount++;
|
||||
|
||||
surface_p->data = (void *)psurf;
|
||||
surface_p->nearzi = r_nearzi;
|
||||
surface_p->flags = psurf->flags;
|
||||
surface_p->insubmodel = true;
|
||||
surface_p->spanstate = 0;
|
||||
surface_p->entity = currententity;
|
||||
surface_p->key = r_currentbkey;
|
||||
surface_p->spans = NULL;
|
||||
|
||||
pplane = psurf->plane;
|
||||
// FIXME: cache this?
|
||||
TransformVector (pplane->normal, p_normal);
|
||||
// FIXME: cache this?
|
||||
distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
|
||||
|
||||
surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
|
||||
surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
|
||||
surface_p->d_ziorigin = p_normal[2] * distinv -
|
||||
xcenter * surface_p->d_zistepu -
|
||||
ycenter * surface_p->d_zistepv;
|
||||
|
||||
//JDC VectorCopy (r_worldmodelorg, surface_p->modelorg);
|
||||
surface_p++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RenderPoly
|
||||
================
|
||||
*/
|
||||
void R_RenderPoly (msurface_t *fa, int clipflags)
|
||||
{
|
||||
int i, lindex, lnumverts, s_axis, t_axis;
|
||||
float dist, lastdist, lzi, scale, u, v, frac;
|
||||
unsigned mask;
|
||||
vec3_t local, transformed;
|
||||
clipplane_t *pclip;
|
||||
medge_t *pedges;
|
||||
mplane_t *pplane;
|
||||
mvertex_t verts[2][100]; //FIXME: do real number
|
||||
polyvert_t pverts[100]; //FIXME: do real number, safely
|
||||
int vertpage, newverts, newpage, lastvert;
|
||||
qboolean visible;
|
||||
|
||||
// FIXME: clean this up and make it faster
|
||||
// FIXME: guard against running out of vertices
|
||||
|
||||
s_axis = t_axis = 0; // keep compiler happy
|
||||
|
||||
// set up clip planes
|
||||
pclip = NULL;
|
||||
|
||||
for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
|
||||
{
|
||||
if (clipflags & mask)
|
||||
{
|
||||
view_clipplanes[i].next = pclip;
|
||||
pclip = &view_clipplanes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// reconstruct the polygon
|
||||
// FIXME: these should be precalculated and loaded off disk
|
||||
pedges = currententity->model->edges;
|
||||
lnumverts = fa->numedges;
|
||||
vertpage = 0;
|
||||
|
||||
for (i=0 ; i<lnumverts ; i++)
|
||||
{
|
||||
lindex = currententity->model->surfedges[fa->firstedge + i];
|
||||
|
||||
if (lindex > 0)
|
||||
{
|
||||
r_pedge = &pedges[lindex];
|
||||
verts[0][i] = r_pcurrentvertbase[r_pedge->v[0]];
|
||||
}
|
||||
else
|
||||
{
|
||||
r_pedge = &pedges[-lindex];
|
||||
verts[0][i] = r_pcurrentvertbase[r_pedge->v[1]];
|
||||
}
|
||||
}
|
||||
|
||||
// clip the polygon, done if not visible
|
||||
while (pclip)
|
||||
{
|
||||
lastvert = lnumverts - 1;
|
||||
lastdist = DotProduct (verts[vertpage][lastvert].position,
|
||||
pclip->normal) - pclip->dist;
|
||||
|
||||
visible = false;
|
||||
newverts = 0;
|
||||
newpage = vertpage ^ 1;
|
||||
|
||||
for (i=0 ; i<lnumverts ; i++)
|
||||
{
|
||||
dist = DotProduct (verts[vertpage][i].position, pclip->normal) -
|
||||
pclip->dist;
|
||||
|
||||
if ((lastdist > 0) != (dist > 0))
|
||||
{
|
||||
frac = dist / (dist - lastdist);
|
||||
verts[newpage][newverts].position[0] =
|
||||
verts[vertpage][i].position[0] +
|
||||
((verts[vertpage][lastvert].position[0] -
|
||||
verts[vertpage][i].position[0]) * frac);
|
||||
verts[newpage][newverts].position[1] =
|
||||
verts[vertpage][i].position[1] +
|
||||
((verts[vertpage][lastvert].position[1] -
|
||||
verts[vertpage][i].position[1]) * frac);
|
||||
verts[newpage][newverts].position[2] =
|
||||
verts[vertpage][i].position[2] +
|
||||
((verts[vertpage][lastvert].position[2] -
|
||||
verts[vertpage][i].position[2]) * frac);
|
||||
newverts++;
|
||||
}
|
||||
|
||||
if (dist >= 0)
|
||||
{
|
||||
verts[newpage][newverts] = verts[vertpage][i];
|
||||
newverts++;
|
||||
visible = true;
|
||||
}
|
||||
|
||||
lastvert = i;
|
||||
lastdist = dist;
|
||||
}
|
||||
|
||||
if (!visible || (newverts < 3))
|
||||
return;
|
||||
|
||||
lnumverts = newverts;
|
||||
vertpage ^= 1;
|
||||
pclip = pclip->next;
|
||||
}
|
||||
|
||||
// transform and project, remembering the z values at the vertices and
|
||||
// r_nearzi, and extract the s and t coordinates at the vertices
|
||||
pplane = fa->plane;
|
||||
switch (pplane->type)
|
||||
{
|
||||
case PLANE_X:
|
||||
case PLANE_ANYX:
|
||||
s_axis = 1;
|
||||
t_axis = 2;
|
||||
break;
|
||||
case PLANE_Y:
|
||||
case PLANE_ANYY:
|
||||
s_axis = 0;
|
||||
t_axis = 2;
|
||||
break;
|
||||
case PLANE_Z:
|
||||
case PLANE_ANYZ:
|
||||
s_axis = 0;
|
||||
t_axis = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
r_nearzi = 0;
|
||||
|
||||
for (i=0 ; i<lnumverts ; i++)
|
||||
{
|
||||
// transform and project
|
||||
VectorSubtract (verts[vertpage][i].position, modelorg, local);
|
||||
TransformVector (local, transformed);
|
||||
|
||||
if (transformed[2] < NEAR_CLIP)
|
||||
transformed[2] = NEAR_CLIP;
|
||||
|
||||
lzi = 1.0 / transformed[2];
|
||||
|
||||
if (lzi > r_nearzi) // for mipmap finding
|
||||
r_nearzi = lzi;
|
||||
|
||||
// FIXME: build x/yscale into transform?
|
||||
scale = xscale * lzi;
|
||||
u = (xcenter + scale*transformed[0]);
|
||||
if (u < r_refdef.fvrectx_adj)
|
||||
u = r_refdef.fvrectx_adj;
|
||||
if (u > r_refdef.fvrectright_adj)
|
||||
u = r_refdef.fvrectright_adj;
|
||||
|
||||
scale = yscale * lzi;
|
||||
v = (ycenter - scale*transformed[1]);
|
||||
if (v < r_refdef.fvrecty_adj)
|
||||
v = r_refdef.fvrecty_adj;
|
||||
if (v > r_refdef.fvrectbottom_adj)
|
||||
v = r_refdef.fvrectbottom_adj;
|
||||
|
||||
pverts[i].u = u;
|
||||
pverts[i].v = v;
|
||||
pverts[i].zi = lzi;
|
||||
pverts[i].s = verts[vertpage][i].position[s_axis];
|
||||
pverts[i].t = verts[vertpage][i].position[t_axis];
|
||||
}
|
||||
|
||||
// build the polygon descriptor, including fa, r_nearzi, and u, v, s, t, and z
|
||||
// for each vertex
|
||||
r_polydesc.numverts = lnumverts;
|
||||
r_polydesc.nearzi = r_nearzi;
|
||||
r_polydesc.pcurrentface = fa;
|
||||
r_polydesc.pverts = pverts;
|
||||
|
||||
// draw the polygon
|
||||
D_DrawPoly ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_ZDrawSubmodelPolys
|
||||
================
|
||||
*/
|
||||
void R_ZDrawSubmodelPolys (model_t *pmodel)
|
||||
{
|
||||
int i, numsurfaces;
|
||||
msurface_t *psurf;
|
||||
float dot;
|
||||
mplane_t *pplane;
|
||||
|
||||
psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
|
||||
numsurfaces = pmodel->nummodelsurfaces;
|
||||
|
||||
for (i=0 ; i<numsurfaces ; i++, psurf++)
|
||||
{
|
||||
// find which side of the node we are on
|
||||
pplane = psurf->plane;
|
||||
|
||||
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
|
||||
|
||||
// draw the polygon
|
||||
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
|
||||
{
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
R_RenderPoly (psurf, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,661 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// r_surf.c: surface-related refresh code
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
|
||||
drawsurf_t r_drawsurf;
|
||||
|
||||
int lightleft, sourcesstep, blocksize, sourcetstep;
|
||||
int lightdelta, lightdeltastep;
|
||||
int lightright, lightleftstep, lightrightstep, blockdivshift;
|
||||
unsigned blockdivmask;
|
||||
void *prowdestbase;
|
||||
unsigned char *pbasesource;
|
||||
int surfrowbytes; // used by ASM files
|
||||
unsigned *r_lightptr;
|
||||
int r_stepback;
|
||||
int r_lightwidth;
|
||||
int r_numhblocks, r_numvblocks;
|
||||
unsigned char *r_source, *r_sourcemax;
|
||||
|
||||
void R_DrawSurfaceBlock8_mip0 (void);
|
||||
void R_DrawSurfaceBlock8_mip1 (void);
|
||||
void R_DrawSurfaceBlock8_mip2 (void);
|
||||
void R_DrawSurfaceBlock8_mip3 (void);
|
||||
|
||||
static void (*surfmiptable[4])(void) = {
|
||||
R_DrawSurfaceBlock8_mip0,
|
||||
R_DrawSurfaceBlock8_mip1,
|
||||
R_DrawSurfaceBlock8_mip2,
|
||||
R_DrawSurfaceBlock8_mip3
|
||||
};
|
||||
|
||||
|
||||
|
||||
unsigned blocklights[18*18];
|
||||
|
||||
/*
|
||||
===============
|
||||
R_AddDynamicLights
|
||||
===============
|
||||
*/
|
||||
void R_AddDynamicLights (void)
|
||||
{
|
||||
msurface_t *surf;
|
||||
int lnum;
|
||||
int sd, td;
|
||||
float dist, rad, minlight;
|
||||
vec3_t impact, local;
|
||||
int s, t;
|
||||
int i;
|
||||
int smax, tmax;
|
||||
mtexinfo_t *tex;
|
||||
|
||||
surf = r_drawsurf.surf;
|
||||
smax = (surf->extents[0]>>4)+1;
|
||||
tmax = (surf->extents[1]>>4)+1;
|
||||
tex = surf->texinfo;
|
||||
|
||||
for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
|
||||
{
|
||||
if ( !(surf->dlightbits & (1<<lnum) ) )
|
||||
continue; // not lit by this light
|
||||
|
||||
rad = cl_dlights[lnum].radius;
|
||||
dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) -
|
||||
surf->plane->dist;
|
||||
rad -= fabs(dist);
|
||||
minlight = cl_dlights[lnum].minlight;
|
||||
if (rad < minlight)
|
||||
continue;
|
||||
minlight = rad - minlight;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
impact[i] = cl_dlights[lnum].origin[i] -
|
||||
surf->plane->normal[i]*dist;
|
||||
}
|
||||
|
||||
local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
|
||||
local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
|
||||
|
||||
local[0] -= surf->texturemins[0];
|
||||
local[1] -= surf->texturemins[1];
|
||||
|
||||
for (t = 0 ; t<tmax ; t++)
|
||||
{
|
||||
td = local[1] - t*16;
|
||||
if (td < 0)
|
||||
td = -td;
|
||||
for (s=0 ; s<smax ; s++)
|
||||
{
|
||||
sd = local[0] - s*16;
|
||||
if (sd < 0)
|
||||
sd = -sd;
|
||||
if (sd > td)
|
||||
dist = sd + (td>>1);
|
||||
else
|
||||
dist = td + (sd>>1);
|
||||
if (dist < minlight)
|
||||
blocklights[t*smax + s] += (rad - dist)*256;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_BuildLightMap
|
||||
|
||||
Combine and scale multiple lightmaps into the 8.8 format in blocklights
|
||||
===============
|
||||
*/
|
||||
void R_BuildLightMap (void)
|
||||
{
|
||||
int smax, tmax;
|
||||
int t;
|
||||
int i, size;
|
||||
byte *lightmap;
|
||||
unsigned scale;
|
||||
int maps;
|
||||
msurface_t *surf;
|
||||
|
||||
surf = r_drawsurf.surf;
|
||||
|
||||
smax = (surf->extents[0]>>4)+1;
|
||||
tmax = (surf->extents[1]>>4)+1;
|
||||
size = smax*tmax;
|
||||
lightmap = surf->samples;
|
||||
|
||||
if (/* r_fullbright.value || */ !cl.worldmodel->lightdata)
|
||||
{
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// clear to ambient
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] = r_refdef.ambientlight<<8;
|
||||
|
||||
|
||||
// add all the lightmaps
|
||||
if (lightmap)
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
{
|
||||
scale = r_drawsurf.lightadj[maps]; // 8.8 fraction
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] += lightmap[i] * scale;
|
||||
lightmap += size; // skip to next lightmap
|
||||
}
|
||||
|
||||
// add all the dynamic lights
|
||||
if (surf->dlightframe == r_framecount)
|
||||
R_AddDynamicLights ();
|
||||
|
||||
// bound, invert, and shift
|
||||
for (i=0 ; i<size ; i++)
|
||||
{
|
||||
t = (255*256 - (int)blocklights[i]) >> (8 - VID_CBITS);
|
||||
|
||||
if (t < (1 << 6))
|
||||
t = (1 << 6);
|
||||
|
||||
blocklights[i] = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_TextureAnimation
|
||||
|
||||
Returns the proper texture for a given time and base texture
|
||||
===============
|
||||
*/
|
||||
texture_t *R_TextureAnimation (texture_t *base)
|
||||
{
|
||||
int reletive;
|
||||
int count;
|
||||
|
||||
if (currententity->frame)
|
||||
{
|
||||
if (base->alternate_anims)
|
||||
base = base->alternate_anims;
|
||||
}
|
||||
|
||||
if (!base->anim_total)
|
||||
return base;
|
||||
|
||||
reletive = (int)(cl.time*10) % base->anim_total;
|
||||
|
||||
count = 0;
|
||||
while (base->anim_min > reletive || base->anim_max <= reletive)
|
||||
{
|
||||
base = base->anim_next;
|
||||
if (!base)
|
||||
Sys_Error ("R_TextureAnimation: broken cycle");
|
||||
if (++count > 100)
|
||||
Sys_Error ("R_TextureAnimation: infinite cycle");
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DrawSurface
|
||||
===============
|
||||
*/
|
||||
void R_DrawSurface (void)
|
||||
{
|
||||
unsigned char *basetptr;
|
||||
int smax, tmax, twidth;
|
||||
int u;
|
||||
int soffset, basetoffset, texwidth;
|
||||
int horzblockstep;
|
||||
unsigned char *pcolumndest;
|
||||
void (*pblockdrawer)(void);
|
||||
texture_t *mt;
|
||||
|
||||
// calculate the lightings
|
||||
R_BuildLightMap ();
|
||||
|
||||
surfrowbytes = r_drawsurf.rowbytes;
|
||||
|
||||
mt = r_drawsurf.texture;
|
||||
|
||||
r_source = (byte *)mt + mt->offsets[r_drawsurf.surfmip];
|
||||
|
||||
// the fractional light values should range from 0 to (VID_GRADES - 1) << 16
|
||||
// from a source range of 0 - 255
|
||||
|
||||
texwidth = mt->width >> r_drawsurf.surfmip;
|
||||
|
||||
blocksize = 16 >> r_drawsurf.surfmip;
|
||||
blockdivshift = 4 - r_drawsurf.surfmip;
|
||||
blockdivmask = (1 << blockdivshift) - 1;
|
||||
|
||||
r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1;
|
||||
|
||||
r_numhblocks = r_drawsurf.surfwidth >> blockdivshift;
|
||||
r_numvblocks = r_drawsurf.surfheight >> blockdivshift;
|
||||
|
||||
//==============================
|
||||
|
||||
if (r_pixbytes == 1)
|
||||
{
|
||||
pblockdrawer = surfmiptable[r_drawsurf.surfmip];
|
||||
// TODO: only needs to be set when there is a display settings change
|
||||
horzblockstep = blocksize;
|
||||
}
|
||||
else
|
||||
{
|
||||
pblockdrawer = R_DrawSurfaceBlock16;
|
||||
// TODO: only needs to be set when there is a display settings change
|
||||
horzblockstep = blocksize << 1;
|
||||
}
|
||||
|
||||
smax = mt->width >> r_drawsurf.surfmip;
|
||||
twidth = texwidth;
|
||||
tmax = mt->height >> r_drawsurf.surfmip;
|
||||
sourcetstep = texwidth;
|
||||
r_stepback = tmax * twidth;
|
||||
|
||||
r_sourcemax = r_source + (tmax * smax);
|
||||
|
||||
soffset = r_drawsurf.surf->texturemins[0];
|
||||
basetoffset = r_drawsurf.surf->texturemins[1];
|
||||
|
||||
// << 16 components are to guarantee positive values for %
|
||||
soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax;
|
||||
basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip)
|
||||
+ (tmax << 16)) % tmax) * twidth)];
|
||||
|
||||
pcolumndest = r_drawsurf.surfdat;
|
||||
|
||||
for (u=0 ; u<r_numhblocks; u++)
|
||||
{
|
||||
r_lightptr = blocklights + u;
|
||||
|
||||
prowdestbase = pcolumndest;
|
||||
|
||||
pbasesource = basetptr + soffset;
|
||||
|
||||
(*pblockdrawer)();
|
||||
|
||||
soffset = soffset + blocksize;
|
||||
if (soffset >= smax)
|
||||
soffset = 0;
|
||||
|
||||
pcolumndest += horzblockstep;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
#if !id386
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSurfaceBlock8_mip0
|
||||
================
|
||||
*/
|
||||
void R_DrawSurfaceBlock8_mip0 (void)
|
||||
{
|
||||
int v, i, b, lightstep, lighttemp, light;
|
||||
unsigned char pix, *psource, *prowdest;
|
||||
|
||||
psource = pbasesource;
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v=0 ; v<r_numvblocks ; v++)
|
||||
{
|
||||
// FIXME: make these locals?
|
||||
// FIXME: use delta rather than both right and left, like ASM?
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 4;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 4;
|
||||
|
||||
for (i=0 ; i<16 ; i++)
|
||||
{
|
||||
lighttemp = lightleft - lightright;
|
||||
lightstep = lighttemp >> 4;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b=15; b>=0; b--)
|
||||
{
|
||||
pix = psource[b];
|
||||
prowdest[b] = ((unsigned char *)vid.colormap)
|
||||
[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += surfrowbytes;
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSurfaceBlock8_mip1
|
||||
================
|
||||
*/
|
||||
void R_DrawSurfaceBlock8_mip1 (void)
|
||||
{
|
||||
int v, i, b, lightstep, lighttemp, light;
|
||||
unsigned char pix, *psource, *prowdest;
|
||||
|
||||
psource = pbasesource;
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v=0 ; v<r_numvblocks ; v++)
|
||||
{
|
||||
// FIXME: make these locals?
|
||||
// FIXME: use delta rather than both right and left, like ASM?
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 3;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 3;
|
||||
|
||||
for (i=0 ; i<8 ; i++)
|
||||
{
|
||||
lighttemp = lightleft - lightright;
|
||||
lightstep = lighttemp >> 3;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b=7; b>=0; b--)
|
||||
{
|
||||
pix = psource[b];
|
||||
prowdest[b] = ((unsigned char *)vid.colormap)
|
||||
[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += surfrowbytes;
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSurfaceBlock8_mip2
|
||||
================
|
||||
*/
|
||||
void R_DrawSurfaceBlock8_mip2 (void)
|
||||
{
|
||||
int v, i, b, lightstep, lighttemp, light;
|
||||
unsigned char pix, *psource, *prowdest;
|
||||
|
||||
psource = pbasesource;
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v=0 ; v<r_numvblocks ; v++)
|
||||
{
|
||||
// FIXME: make these locals?
|
||||
// FIXME: use delta rather than both right and left, like ASM?
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 2;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 2;
|
||||
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
lighttemp = lightleft - lightright;
|
||||
lightstep = lighttemp >> 2;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b=3; b>=0; b--)
|
||||
{
|
||||
pix = psource[b];
|
||||
prowdest[b] = ((unsigned char *)vid.colormap)
|
||||
[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += surfrowbytes;
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSurfaceBlock8_mip3
|
||||
================
|
||||
*/
|
||||
void R_DrawSurfaceBlock8_mip3 (void)
|
||||
{
|
||||
int v, i, b, lightstep, lighttemp, light;
|
||||
unsigned char pix, *psource, *prowdest;
|
||||
|
||||
psource = pbasesource;
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v=0 ; v<r_numvblocks ; v++)
|
||||
{
|
||||
// FIXME: make these locals?
|
||||
// FIXME: use delta rather than both right and left, like ASM?
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 1;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 1;
|
||||
|
||||
for (i=0 ; i<2 ; i++)
|
||||
{
|
||||
lighttemp = lightleft - lightright;
|
||||
lightstep = lighttemp >> 1;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b=1; b>=0; b--)
|
||||
{
|
||||
pix = psource[b];
|
||||
prowdest[b] = ((unsigned char *)vid.colormap)
|
||||
[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += surfrowbytes;
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawSurfaceBlock16
|
||||
|
||||
FIXME: make this work
|
||||
================
|
||||
*/
|
||||
void R_DrawSurfaceBlock16 (void)
|
||||
{
|
||||
int k;
|
||||
unsigned char *psource;
|
||||
int lighttemp, lightstep, light;
|
||||
unsigned short *prowdest;
|
||||
|
||||
prowdest = (unsigned short *)prowdestbase;
|
||||
|
||||
for (k=0 ; k<blocksize ; k++)
|
||||
{
|
||||
unsigned short *pdest;
|
||||
unsigned char pix;
|
||||
int b;
|
||||
|
||||
psource = pbasesource;
|
||||
lighttemp = lightright - lightleft;
|
||||
lightstep = lighttemp >> blockdivshift;
|
||||
|
||||
light = lightleft;
|
||||
pdest = prowdest;
|
||||
|
||||
for (b=0; b<blocksize; b++)
|
||||
{
|
||||
pix = *psource;
|
||||
*pdest = vid.colormap16[(light & 0xFF00) + pix];
|
||||
psource += sourcesstep;
|
||||
pdest++;
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
pbasesource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest = (unsigned short *)((long)prowdest + surfrowbytes);
|
||||
}
|
||||
|
||||
prowdestbase = prowdest;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
R_GenTurbTile
|
||||
================
|
||||
*/
|
||||
void R_GenTurbTile (pixel_t *pbasetex, void *pdest)
|
||||
{
|
||||
int *turb;
|
||||
int i, j, s, t;
|
||||
byte *pd;
|
||||
|
||||
turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
|
||||
pd = (byte *)pdest;
|
||||
|
||||
for (i=0 ; i<TILE_SIZE ; i++)
|
||||
{
|
||||
for (j=0 ; j<TILE_SIZE ; j++)
|
||||
{
|
||||
s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
|
||||
t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
|
||||
*pd++ = *(pbasetex + (t<<6) + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_GenTurbTile16
|
||||
================
|
||||
*/
|
||||
void R_GenTurbTile16 (pixel_t *pbasetex, void *pdest)
|
||||
{
|
||||
int *turb;
|
||||
int i, j, s, t;
|
||||
unsigned short *pd;
|
||||
|
||||
turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
|
||||
pd = (unsigned short *)pdest;
|
||||
|
||||
for (i=0 ; i<TILE_SIZE ; i++)
|
||||
{
|
||||
for (j=0 ; j<TILE_SIZE ; j++)
|
||||
{
|
||||
s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
|
||||
t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
|
||||
*pd++ = d_8to16table[*(pbasetex + (t<<6) + s)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_GenTile
|
||||
================
|
||||
*/
|
||||
void R_GenTile (msurface_t *psurf, void *pdest)
|
||||
{
|
||||
if (psurf->flags & SURF_DRAWTURB)
|
||||
{
|
||||
if (r_pixbytes == 1)
|
||||
{
|
||||
R_GenTurbTile ((pixel_t *)
|
||||
((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_GenTurbTile16 ((pixel_t *)
|
||||
((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
|
||||
}
|
||||
}
|
||||
else if (psurf->flags & SURF_DRAWSKY)
|
||||
{
|
||||
if (r_pixbytes == 1)
|
||||
{
|
||||
R_GenSkyTile (pdest);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_GenSkyTile16 (pdest);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Error ("Unknown tile type");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef GLQUAKE
|
||||
// r_shared.h: general refresh-related stuff shared between the refresh and the
|
||||
// driver
|
||||
|
||||
// FIXME: clean up and move into d_iface.h
|
||||
|
||||
#ifndef _R_SHARED_H_
|
||||
#define _R_SHARED_H_
|
||||
|
||||
#define MAXVERTS 16 // max points in a surface polygon
|
||||
#define MAXWORKINGVERTS (MAXVERTS+4) // max points in an intermediate
|
||||
// polygon (while processing)
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
#define MAXHEIGHT 1024
|
||||
#define MAXWIDTH 1280
|
||||
|
||||
#define INFINITE_DISTANCE 0x10000 // distance that's always guaranteed to
|
||||
// be farther away than anything in
|
||||
// the scene
|
||||
|
||||
//===================================================================
|
||||
|
||||
extern void R_DrawLine (polyvert_t *polyvert0, polyvert_t *polyvert1);
|
||||
|
||||
extern int cachewidth;
|
||||
extern pixel_t *cacheblock;
|
||||
extern int screenwidth;
|
||||
|
||||
extern float pixelAspect;
|
||||
|
||||
extern int r_drawnpolycount;
|
||||
|
||||
extern cvar_t r_clearcolor;
|
||||
|
||||
extern int sintable[1280];
|
||||
extern int intsintable[1280];
|
||||
|
||||
extern vec3_t vup, base_vup;
|
||||
extern vec3_t vpn, base_vpn;
|
||||
extern vec3_t vright, base_vright;
|
||||
extern entity_t *currententity;
|
||||
|
||||
#define NUMSTACKEDGES 2000
|
||||
#define MINEDGES NUMSTACKEDGES
|
||||
#define NUMSTACKSURFACES 1000
|
||||
#define MINSURFACES NUMSTACKSURFACES
|
||||
#define MAXSPANS 3000
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct espan_s
|
||||
{
|
||||
int u, v, count;
|
||||
struct espan_s *pnext;
|
||||
} espan_t;
|
||||
|
||||
// FIXME: compress, make a union if that will help
|
||||
// insubmodel is only 1, flags is fewer than 32, spanstate could be a byte
|
||||
typedef struct surf_s
|
||||
{
|
||||
struct surf_s *next; // active surface stack in r_edge.c
|
||||
struct surf_s *prev; // used in r_edge.c for active surf stack
|
||||
struct espan_s *spans; // pointer to linked list of spans to draw
|
||||
int key; // sorting key (BSP order)
|
||||
int last_u; // set during tracing
|
||||
int spanstate; // 0 = not in span
|
||||
// 1 = in span
|
||||
// -1 = in inverted span (end before
|
||||
// start)
|
||||
int flags; // currentface flags
|
||||
void *data; // associated data like msurface_t
|
||||
entity_t *entity;
|
||||
float nearzi; // nearest 1/z on surface, for mipmapping
|
||||
qboolean insubmodel;
|
||||
float d_ziorigin, d_zistepu, d_zistepv;
|
||||
|
||||
int pad[2]; // to 64 bytes
|
||||
} surf_t;
|
||||
|
||||
extern surf_t *surfaces, *surface_p, *surf_max;
|
||||
|
||||
// surfaces are generated in back to front order by the bsp, so if a surf
|
||||
// pointer is greater than another one, it should be drawn in front
|
||||
// surfaces[1] is the background, and is used as the active surface stack.
|
||||
// surfaces[0] is a dummy, because index 0 is used to indicate no surface
|
||||
// attached to an edge_t
|
||||
|
||||
//===================================================================
|
||||
|
||||
extern vec3_t sxformaxis[4]; // s axis transformed into viewspace
|
||||
extern vec3_t txformaxis[4]; // t axis transformed into viewspac
|
||||
|
||||
extern vec3_t modelorg, base_modelorg;
|
||||
|
||||
extern float xcenter, ycenter;
|
||||
extern float xscale, yscale;
|
||||
extern float xscaleinv, yscaleinv;
|
||||
extern float xscaleshrink, yscaleshrink;
|
||||
|
||||
extern int d_lightstylevalue[256]; // 8.8 frac of base light value
|
||||
|
||||
extern void TransformVector (vec3_t in, vec3_t out);
|
||||
extern void SetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
|
||||
fixed8_t endvertu, fixed8_t endvertv);
|
||||
|
||||
extern int r_skymade;
|
||||
extern void R_MakeSky (void);
|
||||
|
||||
extern int ubasestep, errorterm, erroradjustup, erroradjustdown;
|
||||
|
||||
// flags in finalvert_t.flags
|
||||
#define ALIAS_LEFT_CLIP 0x0001
|
||||
#define ALIAS_TOP_CLIP 0x0002
|
||||
#define ALIAS_RIGHT_CLIP 0x0004
|
||||
#define ALIAS_BOTTOM_CLIP 0x0008
|
||||
#define ALIAS_Z_CLIP 0x0010
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
#define ALIAS_ONSEAM 0x0020 // also defined in modelgen.h;
|
||||
// must be kept in sync
|
||||
#define ALIAS_XY_CLIP_MASK 0x000F
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct edge_s
|
||||
{
|
||||
fixed16_t u;
|
||||
fixed16_t u_step;
|
||||
struct edge_s *prev, *next;
|
||||
unsigned short surfs[2];
|
||||
struct edge_s *nextremove;
|
||||
float nearzi;
|
||||
medge_t *owner;
|
||||
} edge_t;
|
||||
|
||||
#endif // _R_SHARED_H_
|
||||
|
||||
#endif // GLQUAKE
|
Loading…
Reference in a new issue