diff --git a/nzportable.3dsx b/nzportable.3dsx index e558039..9687a52 100644 Binary files a/nzportable.3dsx and b/nzportable.3dsx differ diff --git a/nzportable.elf b/nzportable.elf index 3ec9cc6..9b07058 100755 Binary files a/nzportable.elf and b/nzportable.elf differ diff --git a/source/gl_draw.c b/source/gl_draw.c index 0675b07..95d3f26 100644 --- a/source/gl_draw.c +++ b/source/gl_draw.c @@ -1780,39 +1780,13 @@ int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolea /****************************************/ - -//Diabolickal HLBSP start -byte vid_gamma_table[256]; -void Build_Gamma_Table (void) { - int i; - float inf; - float in_gamma; - - if ((i = COM_CheckParm("-gamma")) != 0 && i+1 < com_argc) { - in_gamma = Q_atof(com_argv[i+1]); - if (in_gamma < 0.3) in_gamma = 0.3; - if (in_gamma > 1) in_gamma = 1.0; - } else { - in_gamma = 1; - } - - if (in_gamma != 1) { - for (i=0 ; i<256 ; i++) { - inf = min(255 * pow((i + 0.5) / 255.5, in_gamma) + 0.5, 255); - vid_gamma_table[i] = inf; - } - } else { - for (i=0 ; i<256 ; i++) - vid_gamma_table[i] = i; - } - -} - /* ================ GL_LoadTexture32 ================ */ +extern byte vid_gamma_table[256]; + int GL_LoadTexture32 (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha) { qboolean noalpha; @@ -1846,17 +1820,11 @@ int GL_LoadTexture32 (char *identifier, int width, int height, byte *data, qbool GL_Bind(texture_extension_number ); -#if 1 - // Baker: this applies our -gamma parameter table - if (1) { - //extern byte vid_gamma_table[256]; - for (i = 0; i < image_size; i++){ - data[4 * i] = vid_gamma_table[data[4 * i]]; - data[4 * i + 1] = vid_gamma_table[data[4 * i + 1]]; - data[4 * i + 2] = vid_gamma_table[data[4 * i + 2]]; - } - } -#endif + for (i = 0; i < image_size; i++){ + data[4 * i] = gammatable[data[4 * i]]; + data[4 * i + 1] = gammatable[data[4 * i + 1]]; + data[4 * i + 2] = gammatable[data[4 * i + 2]]; + } GL_Upload32 ((unsigned *)data, width, height, mipmap, alpha); diff --git a/source/gl_model.h b/source/gl_model.h index 2d2975c..b7f143e 100644 --- a/source/gl_model.h +++ b/source/gl_model.h @@ -430,7 +430,7 @@ mleaf_t *Mod_PointInLeaf (float *p, model_t *model); byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); int GL_LoadTexture32 (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha); //Diabolickal HLBSP -void Build_Gamma_Table (void); //Diabolickal HLBSP +void BuildGammaTable (float g); int loadtextureimage (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap); //Diabolickal TGA #endif // __MODEL__ diff --git a/source/gl_rsurf.c b/source/gl_rsurf.c index 5452a91..e272c6f 100644 --- a/source/gl_rsurf.c +++ b/source/gl_rsurf.c @@ -803,8 +803,9 @@ void R_BlendLightmaps (int specialrender) float *v; glRect_t *theRect; - if (r_fullbright.value) + if (r_fullbright.value) { return; + } glEnable(GL_MODULATE); glColor4f(1,1,1,1); diff --git a/source/gl_vidctr.c b/source/gl_vidctr.c index 5607631..d125b6e 100644 --- a/source/gl_vidctr.c +++ b/source/gl_vidctr.c @@ -171,6 +171,8 @@ static void Check_Gamma (unsigned char *pal) else vid_gamma = Q_atof(com_argv[i+1]); + Con_Printf("in check_gamma: %f\n", vid_gamma); + for (i=0 ; i<768 ; i++) { f = pow ( (pal[i]+1)/256.0 , vid_gamma ); @@ -184,7 +186,7 @@ static void Check_Gamma (unsigned char *pal) memcpy (pal, palette, sizeof(palette)); - Build_Gamma_Table (); //Diabolickal HLBSP + BuildGammaTable (vid_gamma); //Diabolickal HLBSP } void VID_Init (unsigned char *palette) diff --git a/source/r_aclip.c b/source/r_aclip.c deleted file mode 100644 index 61fef0c..0000000 --- a/source/r_aclip.c +++ /dev/null @@ -1,350 +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_aclip.c: clip routines for drawing Alias models directly to the screen - -#include "quakedef.h" -#include "r_local.h" -#include "d_local.h" - -static finalvert_t fv[2][8]; -static auxvert_t av[8]; - -void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av); -void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, - finalvert_t *out); -void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1, - finalvert_t *out); -void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, - finalvert_t *out); -void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, - finalvert_t *out); - - -/* -================ -R_Alias_clip_z - -pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex -================ -*/ -void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) -{ - float scale; - auxvert_t *pav0, *pav1, avout; - - pav0 = &av[pfv0 - &fv[0][0]]; - pav1 = &av[pfv1 - &fv[0][0]]; - - if (pfv0->v[1] >= pfv1->v[1]) - { - scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) / - (pav1->fv[2] - pav0->fv[2]); - - avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale; - avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale; - avout.fv[2] = ALIAS_Z_CLIP_PLANE; - - out->v[2] = pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale; - out->v[3] = pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale; - out->v[4] = pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale; - } - else - { - scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) / - (pav0->fv[2] - pav1->fv[2]); - - avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale; - avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale; - avout.fv[2] = ALIAS_Z_CLIP_PLANE; - - out->v[2] = pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale; - out->v[3] = pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale; - out->v[4] = pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale; - } - - R_AliasProjectFinalVert (out, &avout); - - if (out->v[0] < r_refdef.aliasvrect.x) - out->flags |= ALIAS_LEFT_CLIP; - if (out->v[1] < r_refdef.aliasvrect.y) - out->flags |= ALIAS_TOP_CLIP; - if (out->v[0] > r_refdef.aliasvrectright) - out->flags |= ALIAS_RIGHT_CLIP; - if (out->v[1] > r_refdef.aliasvrectbottom) - out->flags |= ALIAS_BOTTOM_CLIP; -} - - -#if !id386 - -void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) -{ - float scale; - int i; - - if (pfv0->v[1] >= pfv1->v[1]) - { - scale = (float)(r_refdef.aliasvrect.x - pfv0->v[0]) / - (pfv1->v[0] - pfv0->v[0]); - for (i=0 ; i<6 ; i++) - out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; - } - else - { - scale = (float)(r_refdef.aliasvrect.x - pfv1->v[0]) / - (pfv0->v[0] - pfv1->v[0]); - for (i=0 ; i<6 ; i++) - out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; - } -} - - -void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, - finalvert_t *out) -{ - float scale; - int i; - - if (pfv0->v[1] >= pfv1->v[1]) - { - scale = (float)(r_refdef.aliasvrectright - pfv0->v[0]) / - (pfv1->v[0] - pfv0->v[0]); - for (i=0 ; i<6 ; i++) - out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; - } - else - { - scale = (float)(r_refdef.aliasvrectright - pfv1->v[0]) / - (pfv0->v[0] - pfv1->v[0]); - for (i=0 ; i<6 ; i++) - out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; - } -} - - -void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) -{ - float scale; - int i; - - if (pfv0->v[1] >= pfv1->v[1]) - { - scale = (float)(r_refdef.aliasvrect.y - pfv0->v[1]) / - (pfv1->v[1] - pfv0->v[1]); - for (i=0 ; i<6 ; i++) - out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; - } - else - { - scale = (float)(r_refdef.aliasvrect.y - pfv1->v[1]) / - (pfv0->v[1] - pfv1->v[1]); - for (i=0 ; i<6 ; i++) - out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; - } -} - - -void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1, - finalvert_t *out) -{ - float scale; - int i; - - if (pfv0->v[1] >= pfv1->v[1]) - { - scale = (float)(r_refdef.aliasvrectbottom - pfv0->v[1]) / - (pfv1->v[1] - pfv0->v[1]); - - for (i=0 ; i<6 ; i++) - out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; - } - else - { - scale = (float)(r_refdef.aliasvrectbottom - pfv1->v[1]) / - (pfv0->v[1] - pfv1->v[1]); - - for (i=0 ; i<6 ; i++) - out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; - } -} - -#endif - - -int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count, - void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) ) -{ - int i,j,k; - int flags, oldflags; - - j = count-1; - k = 0; - for (i=0 ; i r_refdef.aliasvrectright) - out[k].flags |= ALIAS_RIGHT_CLIP; - if (out[k].v[1] > r_refdef.aliasvrectbottom) - out[k].flags |= ALIAS_BOTTOM_CLIP; - k++; - } - if (!flags) - { - out[k] = in[i]; - k++; - } - } - - return k; -} - - -/* -================ -R_AliasClipTriangle -================ -*/ -void R_AliasClipTriangle (mtriangle_t *ptri) -{ - int i, k, pingpong; - mtriangle_t mtri; - unsigned clipflags; - -// copy vertexes and fix seam texture coordinates - if (ptri->facesfront) - { - fv[0][0] = pfinalverts[ptri->vertindex[0]]; - fv[0][1] = pfinalverts[ptri->vertindex[1]]; - fv[0][2] = pfinalverts[ptri->vertindex[2]]; - } - else - { - for (i=0 ; i<3 ; i++) - { - fv[0][i] = pfinalverts[ptri->vertindex[i]]; - - if (!ptri->facesfront && (fv[0][i].flags & ALIAS_ONSEAM) ) - fv[0][i].v[2] += r_affinetridesc.seamfixupX16; - } - } - -// clip - clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags; - - if (clipflags & ALIAS_Z_CLIP) - { - for (i=0 ; i<3 ; i++) - av[i] = pauxverts[ptri->vertindex[i]]; - - k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z); - if (k == 0) - return; - - pingpong = 1; - clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags; - } - else - { - pingpong = 0; - k = 3; - } - - if (clipflags & ALIAS_LEFT_CLIP) - { - k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], - ALIAS_LEFT_CLIP, k, R_Alias_clip_left); - if (k == 0) - return; - - pingpong ^= 1; - } - - if (clipflags & ALIAS_RIGHT_CLIP) - { - k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], - ALIAS_RIGHT_CLIP, k, R_Alias_clip_right); - if (k == 0) - return; - - pingpong ^= 1; - } - - if (clipflags & ALIAS_BOTTOM_CLIP) - { - k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], - ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom); - if (k == 0) - return; - - pingpong ^= 1; - } - - if (clipflags & ALIAS_TOP_CLIP) - { - k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], - ALIAS_TOP_CLIP, k, R_Alias_clip_top); - if (k == 0) - return; - - pingpong ^= 1; - } - - for (i=0 ; i r_refdef.aliasvrectright) - fv[pingpong][i].v[0] = r_refdef.aliasvrectright; - - if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y) - fv[pingpong][i].v[1] = r_refdef.aliasvrect.y; - else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom) - fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom; - - fv[pingpong][i].flags = 0; - } - -// draw triangles - mtri.facesfront = ptri->facesfront; - r_affinetridesc.ptriangles = &mtri; - r_affinetridesc.pfinalverts = fv[pingpong]; - -// FIXME: do all at once as trifan? - mtri.vertindex[0] = 0; - for (i=1 ; itrivial_accept = 0; - pmodel = currententity->model; - pahdr = Mod_Extradata (pmodel); - pmdl = (mdl_t *)((byte *)pahdr + pahdr->model); - - R_AliasSetUpTransform (0); - -// construct the base bounding box for this frame - frame = currententity->frame; -// TODO: don't repeat this check when drawing? - if ((frame >= pmdl->numframes) || (frame < 0)) - { - Con_DPrintf ("No such frame %d %s\n", frame, - pmodel->name); - frame = 0; - } - - pframedesc = &pahdr->frames[frame]; - -// x worldspace coordinates - basepts[0][0] = basepts[1][0] = basepts[2][0] = basepts[3][0] = - (float)pframedesc->bboxmin.v[0]; - basepts[4][0] = basepts[5][0] = basepts[6][0] = basepts[7][0] = - (float)pframedesc->bboxmax.v[0]; - -// y worldspace coordinates - basepts[0][1] = basepts[3][1] = basepts[5][1] = basepts[6][1] = - (float)pframedesc->bboxmin.v[1]; - basepts[1][1] = basepts[2][1] = basepts[4][1] = basepts[7][1] = - (float)pframedesc->bboxmax.v[1]; - -// z worldspace coordinates - basepts[0][2] = basepts[1][2] = basepts[4][2] = basepts[5][2] = - (float)pframedesc->bboxmin.v[2]; - basepts[2][2] = basepts[3][2] = basepts[6][2] = basepts[7][2] = - (float)pframedesc->bboxmax.v[2]; - - zclipped = false; - zfullyclipped = true; - - minz = 9999; - for (i=0; i<8 ; i++) - { - R_AliasTransformVector (&basepts[i][0], &viewaux[i].fv[0]); - - if (viewaux[i].fv[2] < ALIAS_Z_CLIP_PLANE) - { - // we must clip points that are closer than the near clip plane - viewpts[i].flags = ALIAS_Z_CLIP; - zclipped = true; - } - else - { - if (viewaux[i].fv[2] < minz) - minz = viewaux[i].fv[2]; - viewpts[i].flags = 0; - zfullyclipped = false; - } - } - - - if (zfullyclipped) - { - return false; // everything was near-z-clipped - } - - numv = 8; - - if (zclipped) - { - // organize points by edges, use edges to get new points (possible trivial - // reject) - for (i=0 ; i<12 ; i++) - { - // edge endpoints - pv0 = &viewpts[aedges[i].index0]; - pv1 = &viewpts[aedges[i].index1]; - pa0 = &viewaux[aedges[i].index0]; - pa1 = &viewaux[aedges[i].index1]; - - // if one end is clipped and the other isn't, make a new point - if (pv0->flags ^ pv1->flags) - { - frac = (ALIAS_Z_CLIP_PLANE - pa0->fv[2]) / - (pa1->fv[2] - pa0->fv[2]); - viewaux[numv].fv[0] = pa0->fv[0] + - (pa1->fv[0] - pa0->fv[0]) * frac; - viewaux[numv].fv[1] = pa0->fv[1] + - (pa1->fv[1] - pa0->fv[1]) * frac; - viewaux[numv].fv[2] = ALIAS_Z_CLIP_PLANE; - viewpts[numv].flags = 0; - numv++; - } - } - } - -// project the vertices that remain after clipping - anyclip = 0; - allclip = ALIAS_XY_CLIP_MASK; - -// TODO: probably should do this loop in ASM, especially if we use floats - for (i=0 ; i r_refdef.fvrectright) - flags |= ALIAS_RIGHT_CLIP; - if (v1 > r_refdef.fvrectbottom) - flags |= ALIAS_BOTTOM_CLIP; - - anyclip |= flags; - allclip &= flags; - } - - if (allclip) - return false; // trivial reject off one side - - currententity->trivial_accept = !anyclip & !zclipped; - - if (currententity->trivial_accept) - { - if (minz > (r_aliastransition + (pmdl->size * r_resfudge))) - { - currententity->trivial_accept |= 2; - } - } - - return true; -} - - -/* -================ -R_AliasTransformVector -================ -*/ -void R_AliasTransformVector (vec3_t in, vec3_t out) -{ - out[0] = DotProduct(in, aliastransform[0]) + aliastransform[0][3]; - out[1] = DotProduct(in, aliastransform[1]) + aliastransform[1][3]; - out[2] = DotProduct(in, aliastransform[2]) + aliastransform[2][3]; -} - - -/* -================ -R_AliasPreparePoints - -General clipped case -================ -*/ -void R_AliasPreparePoints (void) -{ - int i; - stvert_t *pstverts; - finalvert_t *fv; - auxvert_t *av; - mtriangle_t *ptri; - finalvert_t *pfv[3]; - - pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts); - r_anumverts = pmdl->numverts; - fv = pfinalverts; - av = pauxverts; - - for (i=0 ; ifv[2] < ALIAS_Z_CLIP_PLANE) - fv->flags |= ALIAS_Z_CLIP; - else - { - R_AliasProjectFinalVert (fv, av); - - if (fv->v[0] < r_refdef.aliasvrect.x) - fv->flags |= ALIAS_LEFT_CLIP; - if (fv->v[1] < r_refdef.aliasvrect.y) - fv->flags |= ALIAS_TOP_CLIP; - if (fv->v[0] > r_refdef.aliasvrectright) - fv->flags |= ALIAS_RIGHT_CLIP; - if (fv->v[1] > r_refdef.aliasvrectbottom) - fv->flags |= ALIAS_BOTTOM_CLIP; - } - } - -// -// clip and draw all triangles -// - r_affinetridesc.numtriangles = 1; - - ptri = (mtriangle_t *)((byte *)paliashdr + paliashdr->triangles); - for (i=0 ; inumtris ; i++, ptri++) - { - pfv[0] = &pfinalverts[ptri->vertindex[0]]; - pfv[1] = &pfinalverts[ptri->vertindex[1]]; - pfv[2] = &pfinalverts[ptri->vertindex[2]]; - - if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags & (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) ) - continue; // completely clipped - - if ( ! ( (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) & - (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) ) ) - { // totally unclipped - r_affinetridesc.pfinalverts = pfinalverts; - r_affinetridesc.ptriangles = ptri; - D_PolysetDraw (); - } - else - { // partially clipped - R_AliasClipTriangle (ptri); - } - } -} - - -/* -================ -R_AliasSetUpTransform -================ -*/ -void R_AliasSetUpTransform (int trivial_accept) -{ - int i; - float rotationmatrix[3][4], t2matrix[3][4]; - static float tmatrix[3][4]; - static float viewmatrix[3][4]; - vec3_t angles; - -// TODO: should really be stored with the entity instead of being reconstructed -// TODO: should use a look-up table -// TODO: could cache lazily, stored in the entity - - angles[ROLL] = currententity->angles[ROLL]; - angles[PITCH] = -currententity->angles[PITCH]; - angles[YAW] = currententity->angles[YAW]; - AngleVectors (angles, alias_forward, alias_right, alias_up); - - tmatrix[0][0] = pmdl->scale[0]; - tmatrix[1][1] = pmdl->scale[1]; - tmatrix[2][2] = pmdl->scale[2]; - - tmatrix[0][3] = pmdl->scale_origin[0]; - tmatrix[1][3] = pmdl->scale_origin[1]; - tmatrix[2][3] = pmdl->scale_origin[2]; - -// TODO: can do this with simple matrix rearrangement - - for (i=0 ; i<3 ; i++) - { - t2matrix[i][0] = alias_forward[i]; - t2matrix[i][1] = -alias_right[i]; - t2matrix[i][2] = alias_up[i]; - } - - t2matrix[0][3] = -modelorg[0]; - t2matrix[1][3] = -modelorg[1]; - t2matrix[2][3] = -modelorg[2]; - -// FIXME: can do more efficiently than full concatenation - R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix); - -// TODO: should be global, set when vright, etc., set - VectorCopy (vright, viewmatrix[0]); - VectorCopy (vup, viewmatrix[1]); - VectorInverse (viewmatrix[1]); - VectorCopy (vpn, viewmatrix[2]); - -// viewmatrix[0][3] = 0; -// viewmatrix[1][3] = 0; -// viewmatrix[2][3] = 0; - - R_ConcatTransforms (viewmatrix, rotationmatrix, aliastransform); - -// do the scaling up of x and y to screen coordinates as part of the transform -// for the unclipped case (it would mess up clipping in the clipped case). -// Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y -// correspondingly so the projected x and y come out right -// FIXME: make this work for clipped case too? - if (trivial_accept) - { - for (i=0 ; i<4 ; i++) - { - aliastransform[0][i] *= aliasxscale * - (1.0 / ((float)0x8000 * 0x10000)); - aliastransform[1][i] *= aliasyscale * - (1.0 / ((float)0x8000 * 0x10000)); - aliastransform[2][i] *= 1.0 / ((float)0x8000 * 0x10000); - - } - } -} - - -/* -================ -R_AliasTransformFinalVert -================ -*/ -void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av, - trivertx_t *pverts, stvert_t *pstverts) -{ - int temp; - float lightcos, *plightnormal; - - av->fv[0] = DotProduct(pverts->v, aliastransform[0]) + - aliastransform[0][3]; - av->fv[1] = DotProduct(pverts->v, aliastransform[1]) + - aliastransform[1][3]; - av->fv[2] = DotProduct(pverts->v, aliastransform[2]) + - aliastransform[2][3]; - - fv->v[2] = pstverts->s; - fv->v[3] = pstverts->t; - - fv->flags = pstverts->onseam; - -// lighting - plightnormal = r_avertexnormals[pverts->lightnormalindex]; - lightcos = DotProduct (plightnormal, r_plightvec); - temp = r_ambientlight; - - if (lightcos < 0) - { - temp += (int)(r_shadelight * lightcos); - - // clamp; because we limited the minimum ambient and shading light, we - // don't have to clamp low light, just bright - if (temp < 0) - temp = 0; - } - - fv->v[4] = temp; -} - - -#if !id386 - -/* -================ -R_AliasTransformAndProjectFinalVerts -================ -*/ -void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv, stvert_t *pstverts) -{ - int i, temp; - float lightcos, *plightnormal, zi; - trivertx_t *pverts; - - pverts = r_apverts; - - for (i=0 ; iv, aliastransform[2]) + - aliastransform[2][3]); - - // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is - // scaled up by 1/2**31, and the scaling cancels out for x and y in the - // projection - fv->v[5] = zi; - - fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) + - aliastransform[0][3]) * zi) + aliasxcenter; - fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) + - aliastransform[1][3]) * zi) + aliasycenter; - - fv->v[2] = pstverts->s; - fv->v[3] = pstverts->t; - fv->flags = pstverts->onseam; - - // lighting - plightnormal = r_avertexnormals[pverts->lightnormalindex]; - lightcos = DotProduct (plightnormal, r_plightvec); - temp = r_ambientlight; - - if (lightcos < 0) - { - temp += (int)(r_shadelight * lightcos); - - // clamp; because we limited the minimum ambient and shading light, we - // don't have to clamp low light, just bright - if (temp < 0) - temp = 0; - } - - fv->v[4] = temp; - } -} - -#endif - - -/* -================ -R_AliasProjectFinalVert -================ -*/ -void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av) -{ - float zi; - -// project points - zi = 1.0 / av->fv[2]; - - fv->v[5] = zi * ziscale; - - fv->v[0] = (av->fv[0] * aliasxscale * zi) + aliasxcenter; - fv->v[1] = (av->fv[1] * aliasyscale * zi) + aliasycenter; -} - - -/* -================ -R_AliasPrepareUnclippedPoints -================ -*/ -void R_AliasPrepareUnclippedPoints (void) -{ - stvert_t *pstverts; - finalvert_t *fv; - - pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts); - r_anumverts = pmdl->numverts; -// FIXME: just use pfinalverts directly? - fv = pfinalverts; - - R_AliasTransformAndProjectFinalVerts (fv, pstverts); - - if (r_affinetridesc.drawtype) - D_PolysetDrawFinalVerts (fv, r_anumverts); - - r_affinetridesc.pfinalverts = pfinalverts; - r_affinetridesc.ptriangles = (mtriangle_t *) - ((byte *)paliashdr + paliashdr->triangles); - r_affinetridesc.numtriangles = pmdl->numtris; - - D_PolysetDraw (); -} - -/* -=============== -R_AliasSetupSkin -=============== -*/ -void R_AliasSetupSkin (void) -{ - int skinnum; - int i, numskins; - maliasskingroup_t *paliasskingroup; - float *pskinintervals, fullskininterval; - float skintargettime, skintime; - - skinnum = currententity->skinnum; - if ((skinnum >= pmdl->numskins) || (skinnum < 0)) - { - Con_DPrintf ("R_AliasSetupSkin: no such skin # %d\n", skinnum); - skinnum = 0; - } - - pskindesc = ((maliasskindesc_t *) - ((byte *)paliashdr + paliashdr->skindesc)) + skinnum; - a_skinwidth = pmdl->skinwidth; - - if (pskindesc->type == ALIAS_SKIN_GROUP) - { - paliasskingroup = (maliasskingroup_t *)((byte *)paliashdr + - pskindesc->skin); - pskinintervals = (float *) - ((byte *)paliashdr + paliasskingroup->intervals); - numskins = paliasskingroup->numskins; - fullskininterval = pskinintervals[numskins-1]; - - skintime = cl.time + currententity->syncbase; - - // when loading in Mod_LoadAliasSkinGroup, we guaranteed all interval - // values are positive, so we don't have to worry about division by 0 - skintargettime = skintime - - ((int)(skintime / fullskininterval)) * fullskininterval; - - for (i=0 ; i<(numskins-1) ; i++) - { - if (pskinintervals[i] > skintargettime) - break; - } - - pskindesc = &paliasskingroup->skindescs[i]; - } - - r_affinetridesc.pskindesc = pskindesc; - r_affinetridesc.pskin = (void *)((byte *)paliashdr + pskindesc->skin); - r_affinetridesc.skinwidth = a_skinwidth; - r_affinetridesc.seamfixupX16 = (a_skinwidth >> 1) << 16; - r_affinetridesc.skinheight = pmdl->skinheight; -} - -/* -================ -R_AliasSetupLighting -================ -*/ -void R_AliasSetupLighting (alight_t *plighting) -{ - -// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have -// to clamp off the bottom - r_ambientlight = plighting->ambientlight; - - if (r_ambientlight < LIGHT_MIN) - r_ambientlight = LIGHT_MIN; - - r_ambientlight = (255 - r_ambientlight) << VID_CBITS; - - if (r_ambientlight < LIGHT_MIN) - r_ambientlight = LIGHT_MIN; - - r_shadelight = plighting->shadelight; - - if (r_shadelight < 0) - r_shadelight = 0; - - r_shadelight *= VID_GRADES; - -// rotate the lighting vector into the model's frame of reference - r_plightvec[0] = DotProduct (plighting->plightvec, alias_forward); - r_plightvec[1] = -DotProduct (plighting->plightvec, alias_right); - r_plightvec[2] = DotProduct (plighting->plightvec, alias_up); -} - -/* -================= -R_AliasSetupFrame - -set r_apverts -================= -*/ -void R_AliasSetupFrame (void) -{ - int frame; - int i, numframes; - maliasgroup_t *paliasgroup; - float *pintervals, fullinterval, targettime, time; - - frame = currententity->frame; - if ((frame >= pmdl->numframes) || (frame < 0)) - { - Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame); - frame = 0; - } - - if (paliashdr->frames[frame].type == ALIAS_SINGLE) - { - r_apverts = (trivertx_t *) - ((byte *)paliashdr + paliashdr->frames[frame].frame); - return; - } - - paliasgroup = (maliasgroup_t *) - ((byte *)paliashdr + paliashdr->frames[frame].frame); - pintervals = (float *)((byte *)paliashdr + paliasgroup->intervals); - numframes = paliasgroup->numframes; - fullinterval = pintervals[numframes-1]; - - time = cl.time + currententity->syncbase; - -// -// when loading in Mod_LoadAliasGroup, we guaranteed all interval values -// are positive, so we don't have to worry about division by 0 -// - targettime = time - ((int)(time / fullinterval)) * fullinterval; - - for (i=0 ; i<(numframes-1) ; i++) - { - if (pintervals[i] > targettime) - break; - } - - r_apverts = (trivertx_t *) - ((byte *)paliashdr + paliasgroup->frames[i].frame); -} - - -/* -================ -R_AliasDrawModel -================ -*/ -void R_AliasDrawModel (alight_t *plighting) -{ - finalvert_t finalverts[MAXALIASVERTS + - ((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 1]; - auxvert_t auxverts[MAXALIASVERTS]; - - r_amodels_drawn++; - -// cache align - pfinalverts = (finalvert_t *) - (((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); - pauxverts = &auxverts[0]; - - paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); - pmdl = (mdl_t *)((byte *)paliashdr + paliashdr->model); - - R_AliasSetupSkin (); - R_AliasSetUpTransform (currententity->trivial_accept); - R_AliasSetupLighting (plighting); - R_AliasSetupFrame (); - - if (!currententity->colormap) - Sys_Error ("R_AliasDrawModel: !currententity->colormap"); - - r_affinetridesc.drawtype = (currententity->trivial_accept == 3) && - r_recursiveaffinetriangles; - - if (r_affinetridesc.drawtype) - { - D_PolysetUpdateTables (); // FIXME: precalc... - } - else - { -#if id386 - D_Aff8Patch (currententity->colormap); -#endif - } - - acolormap = currententity->colormap; - - if (currententity != &cl.viewent) - ziscale = (float)0x8000 * (float)0x10000; - else - ziscale = (float)0x8000 * (float)0x10000 * 3.0; - - if (currententity->trivial_accept) - R_AliasPrepareUnclippedPoints (); - else - R_AliasPreparePoints (); -} - diff --git a/source/r_bsp.c b/source/r_bsp.c deleted file mode 100644 index 70e42f9..0000000 --- a/source/r_bsp.c +++ /dev/null @@ -1,674 +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_bsp.c - -#include "quakedef.h" -#include "r_local.h" - -// -// current entity info -// -qboolean insubmodel; -entity_t *currententity; -vec3_t modelorg, base_modelorg; - // modelorg is the viewpoint reletive to - // the currently rendering entity -vec3_t r_entorigin; // the currently rendering entity in world - // coordinates - -float entity_rotation[3][3]; - -vec3_t r_worldmodelorg; - -int r_currentbkey; - -typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t; - -#define MAX_BMODEL_VERTS 500 // 6K -#define MAX_BMODEL_EDGES 1000 // 12K - -static mvertex_t *pbverts; -static bedge_t *pbedges; -static int numbverts, numbedges; - -static mvertex_t *pfrontenter, *pfrontexit; - -static qboolean makeclippededge; - - -//=========================================================================== - -/* -================ -R_EntityRotate -================ -*/ -void R_EntityRotate (vec3_t vec) -{ - vec3_t tvec; - - VectorCopy (vec, tvec); - vec[0] = DotProduct (entity_rotation[0], tvec); - vec[1] = DotProduct (entity_rotation[1], tvec); - vec[2] = DotProduct (entity_rotation[2], tvec); -} - - -/* -================ -R_RotateBmodel -================ -*/ -void R_RotateBmodel (void) -{ - float angle, s, c, temp1[3][3], temp2[3][3], temp3[3][3]; - -// TODO: should use a look-up table -// TODO: should really be stored with the entity instead of being reconstructed -// TODO: could cache lazily, stored in the entity -// TODO: share work with R_SetUpAliasTransform - -// yaw - angle = currententity->angles[YAW]; - angle = angle * M_PI*2 / 360; - s = sin(angle); - c = cos(angle); - - temp1[0][0] = c; - temp1[0][1] = s; - temp1[0][2] = 0; - temp1[1][0] = -s; - temp1[1][1] = c; - temp1[1][2] = 0; - temp1[2][0] = 0; - temp1[2][1] = 0; - temp1[2][2] = 1; - - -// pitch - angle = currententity->angles[PITCH]; - angle = angle * M_PI*2 / 360; - s = sin(angle); - c = cos(angle); - - temp2[0][0] = c; - temp2[0][1] = 0; - temp2[0][2] = -s; - temp2[1][0] = 0; - temp2[1][1] = 1; - temp2[1][2] = 0; - temp2[2][0] = s; - temp2[2][1] = 0; - temp2[2][2] = c; - - R_ConcatRotations (temp2, temp1, temp3); - -// roll - angle = currententity->angles[ROLL]; - angle = angle * M_PI*2 / 360; - s = sin(angle); - c = cos(angle); - - temp1[0][0] = 1; - temp1[0][1] = 0; - temp1[0][2] = 0; - temp1[1][0] = 0; - temp1[1][1] = c; - temp1[1][2] = s; - temp1[2][0] = 0; - temp1[2][1] = -s; - temp1[2][2] = c; - - R_ConcatRotations (temp1, temp3, entity_rotation); - -// -// rotate modelorg and the transformation matrix -// - R_EntityRotate (modelorg); - R_EntityRotate (vpn); - R_EntityRotate (vright); - R_EntityRotate (vup); - - R_TransformFrustum (); -} - - -/* -================ -R_RecursiveClipBPoly -================ -*/ -void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) -{ - bedge_t *psideedges[2], *pnextedge, *ptedge; - int i, side, lastside; - float dist, frac, lastdist; - mplane_t *splitplane, tplane; - mvertex_t *pvert, *plastvert, *ptvert; - mnode_t *pn; - - psideedges[0] = psideedges[1] = NULL; - - makeclippededge = false; - -// transform the BSP plane into model space -// FIXME: cache these? - splitplane = pnode->plane; - tplane.dist = splitplane->dist - - DotProduct(r_entorigin, splitplane->normal); - tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal); - tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal); - tplane.normal[2] = DotProduct (entity_rotation[2], splitplane->normal); - -// clip edges to BSP plane - for ( ; pedges ; pedges = pnextedge) - { - pnextedge = pedges->pnext; - - // set the status for the last point as the previous point - // FIXME: cache this stuff somehow? - plastvert = pedges->v[0]; - lastdist = DotProduct (plastvert->position, tplane.normal) - - tplane.dist; - - if (lastdist > 0) - lastside = 0; - else - lastside = 1; - - pvert = pedges->v[1]; - - dist = DotProduct (pvert->position, tplane.normal) - tplane.dist; - - if (dist > 0) - side = 0; - else - side = 1; - - if (side != lastside) - { - // clipped - if (numbverts >= MAX_BMODEL_VERTS) - return; - - // generate the clipped vertex - frac = lastdist / (lastdist - dist); - ptvert = &pbverts[numbverts++]; - ptvert->position[0] = plastvert->position[0] + - frac * (pvert->position[0] - - plastvert->position[0]); - ptvert->position[1] = plastvert->position[1] + - frac * (pvert->position[1] - - plastvert->position[1]); - ptvert->position[2] = plastvert->position[2] + - frac * (pvert->position[2] - - plastvert->position[2]); - - // split into two edges, one on each side, and remember entering - // and exiting points - // FIXME: share the clip edge by having a winding direction flag? - if (numbedges >= (MAX_BMODEL_EDGES - 1)) - { - Con_Printf ("Out of edges for bmodel\n"); - return; - } - - ptedge = &pbedges[numbedges]; - ptedge->pnext = psideedges[lastside]; - psideedges[lastside] = ptedge; - ptedge->v[0] = plastvert; - ptedge->v[1] = ptvert; - - ptedge = &pbedges[numbedges + 1]; - ptedge->pnext = psideedges[side]; - psideedges[side] = ptedge; - ptedge->v[0] = ptvert; - ptedge->v[1] = pvert; - - numbedges += 2; - - if (side == 0) - { - // entering for front, exiting for back - pfrontenter = ptvert; - makeclippededge = true; - } - else - { - pfrontexit = ptvert; - makeclippededge = true; - } - } - else - { - // add the edge to the appropriate side - pedges->pnext = psideedges[side]; - psideedges[side] = pedges; - } - } - -// if anything was clipped, reconstitute and add the edges along the clip -// plane to both sides (but in opposite directions) - if (makeclippededge) - { - if (numbedges >= (MAX_BMODEL_EDGES - 2)) - { - Con_Printf ("Out of edges for bmodel\n"); - return; - } - - ptedge = &pbedges[numbedges]; - ptedge->pnext = psideedges[0]; - psideedges[0] = ptedge; - ptedge->v[0] = pfrontexit; - ptedge->v[1] = pfrontenter; - - ptedge = &pbedges[numbedges + 1]; - ptedge->pnext = psideedges[1]; - psideedges[1] = ptedge; - ptedge->v[0] = pfrontenter; - ptedge->v[1] = pfrontexit; - - numbedges += 2; - } - -// draw or recurse further - for (i=0 ; i<2 ; i++) - { - if (psideedges[i]) - { - // draw if we've reached a non-solid leaf, done if all that's left is a - // solid leaf, and continue down the tree if it's not a leaf - pn = pnode->children[i]; - - // we're done with this branch if the node or leaf isn't in the PVS - if (pn->visframe == r_visframecount) - { - if (pn->contents < 0) - { - if (pn->contents != CONTENTS_SOLID) - { - r_currentbkey = ((mleaf_t *)pn)->key; - R_RenderBmodelFace (psideedges[i], psurf); - } - } - else - { - R_RecursiveClipBPoly (psideedges[i], pnode->children[i], - psurf); - } - } - } - } -} - - -/* -================ -R_DrawSolidClippedSubmodelPolygons -================ -*/ -void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel) -{ - int i, j, lindex; - vec_t dot; - msurface_t *psurf; - int numsurfaces; - mplane_t *pplane; - mvertex_t bverts[MAX_BMODEL_VERTS]; - bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; - medge_t *pedge, *pedges; - -// FIXME: use bounding-box-based frustum clipping info? - - psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; - numsurfaces = pmodel->nummodelsurfaces; - pedges = pmodel->edges; - - for (i=0 ; iplane; - - 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? - - // copy the edges to bedges, flipping if necessary so always - // clockwise winding - // FIXME: if edges and vertices get caches, these assignments must move - // outside the loop, and overflow checking must be done here - pbverts = bverts; - pbedges = bedges; - numbverts = numbedges = 0; - - if (psurf->numedges > 0) - { - pbedge = &bedges[numbedges]; - numbedges += psurf->numedges; - - for (j=0 ; jnumedges ; j++) - { - lindex = pmodel->surfedges[psurf->firstedge+j]; - - if (lindex > 0) - { - pedge = &pedges[lindex]; - pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]]; - pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]]; - } - else - { - lindex = -lindex; - pedge = &pedges[lindex]; - pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]]; - pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]]; - } - - pbedge[j].pnext = &pbedge[j+1]; - } - - pbedge[j-1].pnext = NULL; // mark end of edges - - R_RecursiveClipBPoly (pbedge, currententity->topnode, psurf); - } - else - { - Sys_Error ("no edges in bmodel"); - } - } - } -} - - -/* -================ -R_DrawSubmodelPolygons -================ -*/ -void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags) -{ - int i; - vec_t dot; - msurface_t *psurf; - int numsurfaces; - mplane_t *pplane; - -// FIXME: use bounding-box-based frustum clipping info? - - psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; - numsurfaces = pmodel->nummodelsurfaces; - - for (i=0 ; iplane; - - 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))) - { - r_currentkey = ((mleaf_t *)currententity->topnode)->key; - - // FIXME: use bounding-box-based frustum clipping info? - R_RenderFace (psurf, clipflags); - } - } -} - - -/* -================ -R_RecursiveWorldNode -================ -*/ -void R_RecursiveWorldNode (mnode_t *node, int clipflags) -{ - int i, c, side, *pindex; - vec3_t acceptpt, rejectpt; - mplane_t *plane; - msurface_t *surf, **mark; - mleaf_t *pleaf; - double d, dot; - - if (node->contents == CONTENTS_SOLID) - return; // solid - - if (node->visframe != r_visframecount) - return; - -// cull the clipping planes if not trivial accept -// FIXME: the compiler is doing a lousy job of optimizing here; it could be -// twice as fast in ASM - if (clipflags) - { - for (i=0 ; i<4 ; i++) - { - if (! (clipflags & (1<minmaxs[pindex[0]]; - rejectpt[1] = (float)node->minmaxs[pindex[1]]; - rejectpt[2] = (float)node->minmaxs[pindex[2]]; - - d = DotProduct (rejectpt, view_clipplanes[i].normal); - d -= view_clipplanes[i].dist; - - if (d <= 0) - return; - - acceptpt[0] = (float)node->minmaxs[pindex[3+0]]; - acceptpt[1] = (float)node->minmaxs[pindex[3+1]]; - acceptpt[2] = (float)node->minmaxs[pindex[3+2]]; - - d = DotProduct (acceptpt, view_clipplanes[i].normal); - d -= view_clipplanes[i].dist; - - if (d >= 0) - clipflags &= ~(1<contents < 0) - { - pleaf = (mleaf_t *)node; - - mark = pleaf->firstmarksurface; - c = pleaf->nummarksurfaces; - - if (c) - { - do - { - (*mark)->visframe = r_framecount; - mark++; - } while (--c); - } - - // deal with model fragments in this leaf - if (pleaf->efrags) - { - R_StoreEfrags (&pleaf->efrags); - } - - pleaf->key = r_currentkey; - r_currentkey++; // all bmodels in a leaf share the same key - } - else - { - // node is just a decision point, so go down the apropriate sides - - // find which side of the node we are on - plane = node->plane; - - switch (plane->type) - { - case PLANE_X: - dot = modelorg[0] - plane->dist; - break; - case PLANE_Y: - dot = modelorg[1] - plane->dist; - break; - case PLANE_Z: - dot = modelorg[2] - plane->dist; - break; - default: - dot = DotProduct (modelorg, plane->normal) - plane->dist; - break; - } - - if (dot >= 0) - side = 0; - else - side = 1; - - // recurse down the children, front side first - R_RecursiveWorldNode (node->children[side], clipflags); - - // draw stuff - c = node->numsurfaces; - - if (c) - { - surf = cl.worldmodel->surfaces + node->firstsurface; - - if (dot < -BACKFACE_EPSILON) - { - do - { - if ((surf->flags & SURF_PLANEBACK) && - (surf->visframe == r_framecount)) - { - if (r_drawpolys) - { - if (r_worldpolysbacktofront) - { - if (numbtofpolys < MAX_BTOFPOLYS) - { - pbtofpolys[numbtofpolys].clipflags = - clipflags; - pbtofpolys[numbtofpolys].psurf = surf; - numbtofpolys++; - } - } - else - { - R_RenderPoly (surf, clipflags); - } - } - else - { - R_RenderFace (surf, clipflags); - } - } - - surf++; - } while (--c); - } - else if (dot > BACKFACE_EPSILON) - { - do - { - if (!(surf->flags & SURF_PLANEBACK) && - (surf->visframe == r_framecount)) - { - if (r_drawpolys) - { - if (r_worldpolysbacktofront) - { - if (numbtofpolys < MAX_BTOFPOLYS) - { - pbtofpolys[numbtofpolys].clipflags = - clipflags; - pbtofpolys[numbtofpolys].psurf = surf; - numbtofpolys++; - } - } - else - { - R_RenderPoly (surf, clipflags); - } - } - else - { - R_RenderFace (surf, clipflags); - } - } - - surf++; - } while (--c); - } - - // all surfaces on the same node share the same sequence number - r_currentkey++; - } - - // recurse down the back side - R_RecursiveWorldNode (node->children[!side], clipflags); - } -} - - - -/* -================ -R_RenderWorld -================ -*/ -void R_RenderWorld (void) -{ - int i; - model_t *clmodel; - btofpoly_t btofpolys[MAX_BTOFPOLYS]; - - pbtofpolys = btofpolys; - - currententity = &cl_entities[0]; - VectorCopy (r_origin, modelorg); - clmodel = currententity->model; - r_pcurrentvertbase = clmodel->vertexes; - - R_RecursiveWorldNode (clmodel->nodes, 15); - -// if the driver wants the polygons back to front, play the visible ones back -// in that order - if (r_worldpolysbacktofront) - { - for (i=numbtofpolys-1 ; i>=0 ; i--) - { - R_RenderPoly (btofpolys[i].psurf, btofpolys[i].clipflags); - } - } -} - - diff --git a/source/r_draw.c b/source/r_draw.c deleted file mode 100644 index 2ccf316..0000000 --- a/source/r_draw.c +++ /dev/null @@ -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[SIN_BUFFER_SIZE]; -int intsintable[SIN_BUFFER_SIZE]; - -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 ; inumedges ; 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 ; imodel->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 ; inormal) - - 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 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 ; iplane; - - 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); - } - } -} - diff --git a/source/r_edge.c b/source/r_edge.c deleted file mode 100644 index d434799..0000000 --- a/source/r_edge.c +++ /dev/null @@ -1,774 +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_edge.c - -#include "quakedef.h" -#include "r_local.h" - -#if 0 -// FIXME -the complex cases add new polys on most lines, so dont optimize for keeping them the same -have multiple free span lists to try to get better coherence? -low depth complexity -- 1 to 3 or so - -this breaks spans at every edge, even hidden ones (bad) - -have a sentinal at both ends? -#endif - - -edge_t *auxedges; -edge_t *r_edges, *edge_p, *edge_max; - -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 - -edge_t *newedges[MAXHEIGHT]; -edge_t *removeedges[MAXHEIGHT]; - -espan_t *span_p, *max_span_p; - -int r_currentkey; - -extern int screenwidth; - -int current_iv; - -int edge_head_u_shift20, edge_tail_u_shift20; - -static void (*pdrawfunc)(void); - -edge_t edge_head; -edge_t edge_tail; -edge_t edge_aftertail; -edge_t edge_sentinel; - -float fv; - -void R_GenerateSpans (void); -void R_GenerateSpansBackward (void); - -void R_LeadingEdge (edge_t *edge); -void R_LeadingEdgeBackwards (edge_t *edge); -void R_TrailingEdge (surf_t *surf, edge_t *edge); - - -//============================================================================= - - -/* -============== -R_DrawCulledPolys -============== -*/ -void R_DrawCulledPolys (void) -{ - surf_t *s; - msurface_t *pface; - - currententity = &cl_entities[0]; - - if (r_worldpolysbacktofront) - { - for (s=surface_p-1 ; s>&surfaces[1] ; s--) - { - if (!s->spans) - continue; - - if (!(s->flags & SURF_DRAWBACKGROUND)) - { - pface = (msurface_t *)s->data; - R_RenderPoly (pface, 15); - } - } - } - else - { - for (s = &surfaces[1] ; sspans) - continue; - - if (!(s->flags & SURF_DRAWBACKGROUND)) - { - pface = (msurface_t *)s->data; - R_RenderPoly (pface, 15); - } - } - } -} - - -/* -============== -R_BeginEdgeFrame -============== -*/ -void R_BeginEdgeFrame (void) -{ - int v; - - edge_p = r_edges; - edge_max = &r_edges[r_numallocatededges]; - - surface_p = &surfaces[2]; // background is surface 1, - // surface 0 is a dummy - surfaces[1].spans = NULL; // no background spans yet - surfaces[1].flags = SURF_DRAWBACKGROUND; - -// put the background behind everything in the world - if (r_draworder.value) - { - pdrawfunc = R_GenerateSpansBackward; - surfaces[1].key = 0; - r_currentkey = 1; - } - else - { - pdrawfunc = R_GenerateSpans; - surfaces[1].key = 0x7FFFFFFF; - r_currentkey = 0; - } - -// FIXME: set with memset - for (v=r_refdef.vrect.y ; vnext; -edgesearch: - if (edgelist->u >= edgestoadd->u) - goto addedge; - edgelist=edgelist->next; - if (edgelist->u >= edgestoadd->u) - goto addedge; - edgelist=edgelist->next; - if (edgelist->u >= edgestoadd->u) - goto addedge; - edgelist=edgelist->next; - if (edgelist->u >= edgestoadd->u) - goto addedge; - edgelist=edgelist->next; - goto edgesearch; - - // insert edgestoadd before edgelist -addedge: - edgestoadd->next = edgelist; - edgestoadd->prev = edgelist->prev; - edgelist->prev->next = edgestoadd; - edgelist->prev = edgestoadd; - } while ((edgestoadd = next_edge) != NULL); -} - -#endif // !id386 - - -#if !id386 - -/* -============== -R_RemoveEdges -============== -*/ -void R_RemoveEdges (edge_t *pedge) -{ - - do - { - pedge->next->prev = pedge->prev; - pedge->prev->next = pedge->next; - } while ((pedge = pedge->nextremove) != NULL); -} - -#endif // !id386 - - -#if !id386 - -/* -============== -R_StepActiveU -============== -*/ -void R_StepActiveU (edge_t *pedge) -{ - edge_t *pnext_edge, *pwedge; - - while (1) - { -nextedge: - pedge->u += pedge->u_step; - if (pedge->u < pedge->prev->u) - goto pushback; - pedge = pedge->next; - - pedge->u += pedge->u_step; - if (pedge->u < pedge->prev->u) - goto pushback; - pedge = pedge->next; - - pedge->u += pedge->u_step; - if (pedge->u < pedge->prev->u) - goto pushback; - pedge = pedge->next; - - pedge->u += pedge->u_step; - if (pedge->u < pedge->prev->u) - goto pushback; - pedge = pedge->next; - - goto nextedge; - -pushback: - if (pedge == &edge_aftertail) - return; - - // push it back to keep it sorted - pnext_edge = pedge->next; - - // pull the edge out of the edge list - pedge->next->prev = pedge->prev; - pedge->prev->next = pedge->next; - - // find out where the edge goes in the edge list - pwedge = pedge->prev->prev; - - while (pwedge->u > pedge->u) - { - pwedge = pwedge->prev; - } - - // put the edge back into the edge list - pedge->next = pwedge->next; - pedge->prev = pwedge; - pedge->next->prev = pedge; - pwedge->next = pedge; - - pedge = pnext_edge; - if (pedge == &edge_tail) - return; - } -} - -#endif // !id386 - - -/* -============== -R_CleanupSpan -============== -*/ -void R_CleanupSpan () -{ - surf_t *surf; - int iu; - espan_t *span; - -// now that we've reached the right edge of the screen, we're done with any -// unfinished surfaces, so emit a span for whatever's on top - surf = surfaces[1].next; - iu = edge_tail_u_shift20; - if (iu > surf->last_u) - { - span = span_p++; - span->u = surf->last_u; - span->count = iu - span->u; - span->v = current_iv; - span->pnext = surf->spans; - surf->spans = span; - } - -// reset spanstate for all surfaces in the surface stack - do - { - surf->spanstate = 0; - surf = surf->next; - } while (surf != &surfaces[1]); -} - - -/* -============== -R_LeadingEdgeBackwards -============== -*/ -void R_LeadingEdgeBackwards (edge_t *edge) -{ - espan_t *span; - surf_t *surf, *surf2; - int iu; - -// it's adding a new surface in, so find the correct place - surf = &surfaces[edge->surfs[1]]; - -// don't start a span if this is an inverted span, with the end -// edge preceding the start edge (that is, we've already seen the -// end edge) - if (++surf->spanstate == 1) - { - surf2 = surfaces[1].next; - - if (surf->key > surf2->key) - goto newtop; - - // if it's two surfaces on the same plane, the one that's already - // active is in front, so keep going unless it's a bmodel - if (surf->insubmodel && (surf->key == surf2->key)) - { - // must be two bmodels in the same leaf; don't care, because they'll - // never be farthest anyway - goto newtop; - } - -continue_search: - - do - { - surf2 = surf2->next; - } while (surf->key < surf2->key); - - if (surf->key == surf2->key) - { - // if it's two surfaces on the same plane, the one that's already - // active is in front, so keep going unless it's a bmodel - if (!surf->insubmodel) - goto continue_search; - - // must be two bmodels in the same leaf; don't care which is really - // in front, because they'll never be farthest anyway - } - - goto gotposition; - -newtop: - // emit a span (obscures current top) - iu = edge->u >> 20; - - if (iu > surf2->last_u) - { - span = span_p++; - span->u = surf2->last_u; - span->count = iu - span->u; - span->v = current_iv; - span->pnext = surf2->spans; - surf2->spans = span; - } - - // set last_u on the new span - surf->last_u = iu; - -gotposition: - // insert before surf2 - surf->next = surf2; - surf->prev = surf2->prev; - surf2->prev->next = surf; - surf2->prev = surf; - } -} - - -/* -============== -R_TrailingEdge -============== -*/ -void R_TrailingEdge (surf_t *surf, edge_t *edge) -{ - espan_t *span; - int iu; - -// don't generate a span if this is an inverted span, with the end -// edge preceding the start edge (that is, we haven't seen the -// start edge yet) - if (--surf->spanstate == 0) - { - if (surf->insubmodel) - r_bmodelactive--; - - if (surf == surfaces[1].next) - { - // emit a span (current top going away) - iu = edge->u >> 20; - if (iu > surf->last_u) - { - span = span_p++; - span->u = surf->last_u; - span->count = iu - span->u; - span->v = current_iv; - span->pnext = surf->spans; - surf->spans = span; - } - - // set last_u on the surface below - surf->next->last_u = iu; - } - - surf->prev->next = surf->next; - surf->next->prev = surf->prev; - } -} - - -#if !id386 - -/* -============== -R_LeadingEdge -============== -*/ -void R_LeadingEdge (edge_t *edge) -{ - espan_t *span; - surf_t *surf, *surf2; - int iu; - double fu, newzi, testzi, newzitop, newzibottom; - - if (edge->surfs[1]) - { - // it's adding a new surface in, so find the correct place - surf = &surfaces[edge->surfs[1]]; - - // don't start a span if this is an inverted span, with the end - // edge preceding the start edge (that is, we've already seen the - // end edge) - if (++surf->spanstate == 1) - { - if (surf->insubmodel) - r_bmodelactive++; - - surf2 = surfaces[1].next; - - if (surf->key < surf2->key) - goto newtop; - - // if it's two surfaces on the same plane, the one that's already - // active is in front, so keep going unless it's a bmodel - if (surf->insubmodel && (surf->key == surf2->key)) - { - // must be two bmodels in the same leaf; sort on 1/z - fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000); - newzi = surf->d_ziorigin + fv*surf->d_zistepv + - fu*surf->d_zistepu; - newzibottom = newzi * 0.99; - - testzi = surf2->d_ziorigin + fv*surf2->d_zistepv + - fu*surf2->d_zistepu; - - if (newzibottom >= testzi) - { - goto newtop; - } - - newzitop = newzi * 1.01; - if (newzitop >= testzi) - { - if (surf->d_zistepu >= surf2->d_zistepu) - { - goto newtop; - } - } - } - -continue_search: - - do - { - surf2 = surf2->next; - } while (surf->key > surf2->key); - - if (surf->key == surf2->key) - { - // if it's two surfaces on the same plane, the one that's already - // active is in front, so keep going unless it's a bmodel - if (!surf->insubmodel) - goto continue_search; - - // must be two bmodels in the same leaf; sort on 1/z - fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000); - newzi = surf->d_ziorigin + fv*surf->d_zistepv + - fu*surf->d_zistepu; - newzibottom = newzi * 0.99; - - testzi = surf2->d_ziorigin + fv*surf2->d_zistepv + - fu*surf2->d_zistepu; - - if (newzibottom >= testzi) - { - goto gotposition; - } - - newzitop = newzi * 1.01; - if (newzitop >= testzi) - { - if (surf->d_zistepu >= surf2->d_zistepu) - { - goto gotposition; - } - } - - goto continue_search; - } - - goto gotposition; - -newtop: - // emit a span (obscures current top) - iu = edge->u >> 20; - - if (iu > surf2->last_u) - { - span = span_p++; - span->u = surf2->last_u; - span->count = iu - span->u; - span->v = current_iv; - span->pnext = surf2->spans; - surf2->spans = span; - } - - // set last_u on the new span - surf->last_u = iu; - -gotposition: - // insert before surf2 - surf->next = surf2; - surf->prev = surf2->prev; - surf2->prev->next = surf; - surf2->prev = surf; - } - } -} - - -/* -============== -R_GenerateSpans -============== -*/ -void R_GenerateSpans (void) -{ - edge_t *edge; - surf_t *surf; - - r_bmodelactive = 0; - -// clear active surfaces to just the background surface - surfaces[1].next = surfaces[1].prev = &surfaces[1]; - surfaces[1].last_u = edge_head_u_shift20; - -// generate spans - for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next) - { - if (edge->surfs[0]) - { - // it has a left surface, so a surface is going away for this span - surf = &surfaces[edge->surfs[0]]; - - R_TrailingEdge (surf, edge); - - if (!edge->surfs[1]) - continue; - } - - R_LeadingEdge (edge); - } - - R_CleanupSpan (); -} - -#endif // !id386 - - -/* -============== -R_GenerateSpansBackward -============== -*/ -void R_GenerateSpansBackward (void) -{ - edge_t *edge; - - r_bmodelactive = 0; - -// clear active surfaces to just the background surface - surfaces[1].next = surfaces[1].prev = &surfaces[1]; - surfaces[1].last_u = edge_head_u_shift20; - -// generate spans - for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next) - { - if (edge->surfs[0]) - R_TrailingEdge (&surfaces[edge->surfs[0]], edge); - - if (edge->surfs[1]) - R_LeadingEdgeBackwards (edge); - } - - R_CleanupSpan (); -} - - -/* -============== -R_ScanEdges - -Input: -newedges[] array - this has links to edges, which have links to surfaces - -Output: -Each surface has a linked list of its visible spans -============== -*/ -void R_ScanEdges (void) -{ - int iv, bottom; - byte basespans[MAXSPANS*sizeof(espan_t)+CACHE_SIZE]; - espan_t *basespan_p; - surf_t *s; - - basespan_p = (espan_t *) - ((long)(basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); - max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width]; - - span_p = basespan_p; - -// clear active edges to just the background edges around the whole screen -// FIXME: most of this only needs to be set up once - edge_head.u = r_refdef.vrect.x << 20; - edge_head_u_shift20 = edge_head.u >> 20; - edge_head.u_step = 0; - edge_head.prev = NULL; - edge_head.next = &edge_tail; - edge_head.surfs[0] = 0; - edge_head.surfs[1] = 1; - - edge_tail.u = (r_refdef.vrectright << 20) + 0xFFFFF; - edge_tail_u_shift20 = edge_tail.u >> 20; - edge_tail.u_step = 0; - edge_tail.prev = &edge_head; - edge_tail.next = &edge_aftertail; - edge_tail.surfs[0] = 1; - edge_tail.surfs[1] = 0; - - edge_aftertail.u = -1; // force a move - edge_aftertail.u_step = 0; - edge_aftertail.next = &edge_sentinel; - edge_aftertail.prev = &edge_tail; - -// FIXME: do we need this now that we clamp x in r_draw.c? - edge_sentinel.u = 2000 << 24; // make sure nothing sorts past this - edge_sentinel.prev = &edge_aftertail; - -// -// process all scan lines -// - bottom = r_refdef.vrectbottom - 1; - - for (iv=r_refdef.vrect.y ; iv= max_span_p) - { - VID_UnlockBuffer (); - S_ExtraUpdate (); // don't let sound get messed up if going slow - VID_LockBuffer (); - - if (r_drawculledpolys) - { - R_DrawCulledPolys (); - } - else - { - D_DrawSurfaces (); - } - - // clear the surface span pointers - for (s = &surfaces[1] ; sspans = NULL; - - span_p = basespan_p; - } - - if (removeedges[iv]) - R_RemoveEdges (removeedges[iv]); - - if (edge_head.next != &edge_tail) - R_StepActiveU (edge_head.next); - } - -// do the last scan (no need to step or sort or remove on the last scan) - - current_iv = iv; - fv = (float)iv; - -// mark that the head (background start) span is pre-included - surfaces[1].spanstate = 1; - - if (newedges[iv]) - R_InsertNewEdges (newedges[iv], edge_head.next); - - (*pdrawfunc) (); - -// draw whatever's left in the span list - if (r_drawculledpolys) - R_DrawCulledPolys (); - else - D_DrawSurfaces (); -} - - diff --git a/source/r_efrag.c b/source/r_efrag.c deleted file mode 100644 index 5e4d3f9..0000000 --- a/source/r_efrag.c +++ /dev/null @@ -1,276 +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_efrag.c - -#include "quakedef.h" -#include "r_local.h" - -mnode_t *r_pefragtopnode; - - -//=========================================================================== - -/* -=============================================================================== - - ENTITY FRAGMENT FUNCTIONS - -=============================================================================== -*/ - -efrag_t **lastlink; - -vec3_t r_emins, r_emaxs; - -entity_t *r_addent; - - -/* -================ -R_RemoveEfrags - -Call when removing an object from the world or moving it to another position -================ -*/ -void R_RemoveEfrags (entity_t *ent) -{ - efrag_t *ef, *old, *walk, **prev; - - ef = ent->efrag; - - while (ef) - { - prev = &ef->leaf->efrags; - while (1) - { - walk = *prev; - if (!walk) - break; - if (walk == ef) - { // remove this fragment - *prev = ef->leafnext; - break; - } - else - prev = &walk->leafnext; - } - - old = ef; - ef = ef->entnext; - - // put it on the free list - old->entnext = cl.free_efrags; - cl.free_efrags = old; - } - - ent->efrag = NULL; -} - -/* -=================== -R_SplitEntityOnNode -=================== -*/ -void R_SplitEntityOnNode (mnode_t *node) -{ - efrag_t *ef; - mplane_t *splitplane; - mleaf_t *leaf; - int sides; - - if (node->contents == CONTENTS_SOLID) - { - return; - } - -// add an efrag if the node is a leaf - - if ( node->contents < 0) - { - if (!r_pefragtopnode) - r_pefragtopnode = node; - - leaf = (mleaf_t *)node; - -// grab an efrag off the free list - ef = cl.free_efrags; - if (!ef) - { - Con_Printf ("Too many efrags!\n"); - return; // no free fragments... - } - cl.free_efrags = cl.free_efrags->entnext; - - ef->entity = r_addent; - -// add the entity link - *lastlink = ef; - lastlink = &ef->entnext; - ef->entnext = NULL; - -// set the leaf links - ef->leaf = leaf; - ef->leafnext = leaf->efrags; - leaf->efrags = ef; - - return; - } - -// NODE_MIXED - - splitplane = node->plane; - sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane); - - if (sides == 3) - { - // split on this plane - // if this is the first splitter of this bmodel, remember it - if (!r_pefragtopnode) - r_pefragtopnode = node; - } - -// recurse down the contacted sides - if (sides & 1) - R_SplitEntityOnNode (node->children[0]); - - if (sides & 2) - R_SplitEntityOnNode (node->children[1]); -} - - -/* -=================== -R_SplitEntityOnNode2 -=================== -*/ -void R_SplitEntityOnNode2 (mnode_t *node) -{ - mplane_t *splitplane; - int sides; - - if (node->visframe != r_visframecount) - return; - - if (node->contents < 0) - { - if (node->contents != CONTENTS_SOLID) - r_pefragtopnode = node; // we've reached a non-solid leaf, so it's - // visible and not BSP clipped - return; - } - - splitplane = node->plane; - sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane); - - if (sides == 3) - { - // remember first splitter - r_pefragtopnode = node; - return; - } - -// not split yet; recurse down the contacted side - if (sides & 1) - R_SplitEntityOnNode2 (node->children[0]); - else - R_SplitEntityOnNode2 (node->children[1]); -} - - -/* -=========== -R_AddEfrags -=========== -*/ -void R_AddEfrags (entity_t *ent) -{ - model_t *entmodel; - int i; - - if (!ent->model) - return; - - if (ent == cl_entities) - return; // never add the world - - r_addent = ent; - - lastlink = &ent->efrag; - r_pefragtopnode = NULL; - - entmodel = ent->model; - - for (i=0 ; i<3 ; i++) - { - r_emins[i] = ent->origin[i] + entmodel->mins[i]; - r_emaxs[i] = ent->origin[i] + entmodel->maxs[i]; - } - - R_SplitEntityOnNode (cl.worldmodel->nodes); - - ent->topnode = r_pefragtopnode; -} - - -/* -================ -R_StoreEfrags - -// FIXME: a lot of this goes away with edge-based -================ -*/ -void R_StoreEfrags (efrag_t **ppefrag) -{ - entity_t *pent; - model_t *clmodel; - efrag_t *pefrag; - - - while ((pefrag = *ppefrag) != NULL) - { - pent = pefrag->entity; - clmodel = pent->model; - - switch (clmodel->type) - { - case mod_alias: - case mod_brush: - case mod_sprite: - pent = pefrag->entity; - - if ((pent->visframe != r_framecount) && - (cl_numvisedicts < MAX_VISEDICTS)) - { - cl_visedicts[cl_numvisedicts++] = pent; - - // mark that we've recorded this entity for this frame - pent->visframe = r_framecount; - } - - ppefrag = &pefrag->leafnext; - break; - - default: - Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type); - } - } -} - - diff --git a/source/r_misc.c b/source/r_misc.c deleted file mode 100644 index c0aa7e9..0000000 --- a/source/r_misc.c +++ /dev/null @@ -1,523 +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_misc.c - -#include "quakedef.h" -#include "r_local.h" - - -/* -=============== -R_CheckVariables -=============== -*/ -void R_CheckVariables (void) -{ - static float oldbright; - - if (r_fullbright.value != oldbright) - { - oldbright = r_fullbright.value; - D_FlushCaches (); // so all lighting changes - } -} - - -/* -============ -Show - -Debugging use -============ -*/ -void Show (void) -{ - vrect_t vr; - - vr.x = vr.y = 0; - vr.width = vid.width; - vr.height = vid.height; - vr.pnext = NULL; - VID_Update (&vr); -} - - -/* -==================== -R_TimeRefresh_f - -For program optimization -==================== -*/ -void R_TimeRefresh_f (void) -{ - int i; - float start, stop, time; - int startangle; - vrect_t vr; - - startangle = r_refdef.viewangles[1]; - - start = Sys_FloatTime (); - for (i=0 ; i<128 ; i++) - { - r_refdef.viewangles[1] = i/128.0*360.0; - - VID_LockBuffer (); - - R_RenderView (); - - VID_UnlockBuffer (); - - vr.x = r_refdef.vrect.x; - vr.y = r_refdef.vrect.y; - vr.width = r_refdef.vrect.width; - vr.height = r_refdef.vrect.height; - vr.pnext = NULL; - VID_Update (&vr); - } - stop = Sys_FloatTime (); - time = stop-start; - Con_Printf ("%f seconds (%f fps)\n", time, 128/time); - - r_refdef.viewangles[1] = startangle; -} - - -/* -================ -R_LineGraph - -Only called by R_DisplayTime -================ -*/ -void R_LineGraph (int x, int y, int h) -{ - int i; - byte *dest; - int s; - -// FIXME: should be disabled on no-buffer adapters, or should be in the driver - - x += r_refdef.vrect.x; - y += r_refdef.vrect.y; - - dest = vid.buffer + vid.rowbytes*y + x; - - s = r_graphheight.value; - - if (h>s) - h = s; - - for (i=0 ; inormal); - *dist = p->dist - d; -// TODO: when we have rotating entities, this will need to use the view matrix - TransformVector (p->normal, normal); -} - - -/* -=============== -R_SetUpFrustumIndexes -=============== -*/ -void R_SetUpFrustumIndexes (void) -{ - int i, j, *pindex; - - pindex = r_frustum_indexes; - - for (i=0 ; i<4 ; i++) - { - for (j=0 ; j<3 ; j++) - { - if (view_clipplanes[i].normal[j] < 0) - { - pindex[j] = j; - pindex[j+3] = j+3; - } - else - { - pindex[j] = j+3; - pindex[j+3] = j; - } - } - - // FIXME: do just once at start - pfrustum_indexes[i] = pindex; - pindex += 6; - } -} - - -/* -=============== -R_SetupFrame -=============== -*/ -void R_SetupFrame (void) -{ - int edgecount; - vrect_t vrect; - float w, h; - -// don't allow cheats in multiplayer - if (cl.maxclients > 1) - { - Cvar_Set ("r_draworder", "0"); - Cvar_Set ("r_fullbright", "0"); - Cvar_Set ("r_ambient", "0"); - Cvar_Set ("r_drawflat", "0"); - } - - if (r_numsurfs.value) - { - if ((surface_p - surfaces) > r_maxsurfsseen) - r_maxsurfsseen = surface_p - surfaces; - - Con_Printf ("Used %d of %d surfs; %d max\n", surface_p - surfaces, - surf_max - surfaces, r_maxsurfsseen); - } - - if (r_numedges.value) - { - edgecount = edge_p - r_edges; - - if (edgecount > r_maxedgesseen) - r_maxedgesseen = edgecount; - - Con_Printf ("Used %d of %d edges; %d max\n", edgecount, - r_numallocatededges, r_maxedgesseen); - } - - r_refdef.ambientlight = r_ambient.value; - - if (r_refdef.ambientlight < 0) - r_refdef.ambientlight = 0; - - if (!sv.active) - r_draworder.value = 0; // don't let cheaters look behind walls - - R_CheckVariables (); - - R_AnimateLight (); - - r_framecount++; - - numbtofpolys = 0; - -// debugging -#if 0 -r_refdef.vieworg[0]= 80; -r_refdef.vieworg[1]= 64; -r_refdef.vieworg[2]= 40; -r_refdef.viewangles[0]= 0; -r_refdef.viewangles[1]= 46.763641357; -r_refdef.viewangles[2]= 0; -#endif - -// build the transformation matrix for the given view angles - VectorCopy (r_refdef.vieworg, modelorg); - VectorCopy (r_refdef.vieworg, r_origin); - - AngleVectors (r_refdef.viewangles, vpn, vright, vup); - -// current viewleaf - r_oldviewleaf = r_viewleaf; - r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); - - r_dowarpold = r_dowarp; - r_dowarp = r_waterwarp.value && (r_viewleaf->contents <= CONTENTS_WATER); - - if ((r_dowarp != r_dowarpold) || r_viewchanged || lcd_x.value) - { - if (r_dowarp) - { - if ((vid.width <= vid.maxwarpwidth) && - (vid.height <= vid.maxwarpheight)) - { - vrect.x = 0; - vrect.y = 0; - vrect.width = vid.width; - vrect.height = vid.height; - - R_ViewChanged (&vrect, sb_lines, vid.aspect); - } - else - { - w = vid.width; - h = vid.height; - - if (w > vid.maxwarpwidth) - { - h *= (float)vid.maxwarpwidth / w; - w = vid.maxwarpwidth; - } - - if (h > vid.maxwarpheight) - { - h = vid.maxwarpheight; - w *= (float)vid.maxwarpheight / h; - } - - vrect.x = 0; - vrect.y = 0; - vrect.width = (int)w; - vrect.height = (int)h; - - R_ViewChanged (&vrect, - (int)((float)sb_lines * (h/(float)vid.height)), - vid.aspect * (h / w) * - ((float)vid.width / (float)vid.height)); - } - } - else - { - vrect.x = 0; - vrect.y = 0; - vrect.width = vid.width; - vrect.height = vid.height; - - R_ViewChanged (&vrect, sb_lines, vid.aspect); - } - - r_viewchanged = false; - } - -// start off with just the four screen edge clip planes - R_TransformFrustum (); - -// save base values - VectorCopy (vpn, base_vpn); - VectorCopy (vright, base_vright); - VectorCopy (vup, base_vup); - VectorCopy (modelorg, base_modelorg); - - R_SetSkyFrame (); - - R_SetUpFrustumIndexes (); - - r_cache_thrash = false; - -// clear frame counts - c_faceclip = 0; - d_spanpixcount = 0; - r_polycount = 0; - r_drawnpolycount = 0; - r_wholepolycount = 0; - r_amodels_drawn = 0; - r_outofsurfaces = 0; - r_outofedges = 0; - - D_SetupFrame (); -} - diff --git a/source/r_sky.c b/source/r_sky.c deleted file mode 100644 index c8bfffd..0000000 --- a/source/r_sky.c +++ /dev/null @@ -1,280 +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_sky.c - -#include "quakedef.h" -#include "r_local.h" -#include "d_local.h" - - -int iskyspeed = 8; -int iskyspeed2 = 2; -float skyspeed, skyspeed2; - -float skytime; - -byte *r_skysource; - -int r_skymade; -int r_skydirect; // not used? - - -// TODO: clean up these routines - -byte bottomsky[128*131]; -byte bottommask[128*131]; -byte newsky[128*256]; // newsky and topsky both pack in here, 128 bytes - // of newsky on the left of each scan, 128 bytes - // of topsky on the right, because the low-level - // drawers need 256-byte scan widths - - -/* -============= -R_InitSky - -A sky texture is 256*128, with the right side being a masked overlay -============== -*/ -void R_InitSky (texture_t *mt) -{ - int i, j; - byte *src; - - src = (byte *)mt + mt->offsets[0]; - - for (i=0 ; i<128 ; i++) - { - for (j=0 ; j<128 ; j++) - { - newsky[(i*256) + j + 128] = src[i*256 + j + 128]; - } - } - - for (i=0 ; i<128 ; i++) - { - for (j=0 ; j<131 ; j++) - { - if (src[i*256 + (j & 0x7F)]) - { - bottomsky[(i*131) + j] = src[i*256 + (j & 0x7F)]; - bottommask[(i*131) + j] = 0; - } - else - { - bottomsky[(i*131) + j] = 0; - bottommask[(i*131) + j] = 0xff; - } - } - } - - r_skysource = newsky; -} - - -/* -================= -R_MakeSky -================= -*/ -void R_MakeSky (void) -{ - int x, y; - int ofs, baseofs; - int xshift, yshift; - unsigned *pnewsky; - static int xlast = -1, ylast = -1; - - xshift = skytime*skyspeed; - yshift = skytime*skyspeed; - - if ((xshift == xlast) && (yshift == ylast)) - return; - - xlast = xshift; - ylast = yshift; - - pnewsky = (unsigned *)&newsky[0]; - - for (y=0 ; ydist; - pclipnormal = pclipplane->normal; - -// calc dists - if (clip_current) - { - in = clip_verts[1][0]; - outstep = clip_verts[0][0]; - clip_current = 0; - } - else - { - in = clip_verts[0][0]; - outstep = clip_verts[1][0]; - clip_current = 1; - } - - instep = in; - for (i=0 ; i= 0) - { - Q_memcpy (outstep, instep, sizeof (vec5_t)); - outstep += sizeof (vec5_t) / sizeof (float); - outcount++; - } - - if (dists[i] == 0 || dists[i+1] == 0) - continue; - - if ( (dists[i] > 0) == (dists[i+1] > 0) ) - continue; - - // split it into a new vertex - frac = dists[i] / (dists[i] - dists[i+1]); - - vert2 = instep + sizeof (vec5_t) / sizeof (float); - - outstep[0] = instep[0] + frac*(vert2[0] - instep[0]); - outstep[1] = instep[1] + frac*(vert2[1] - instep[1]); - outstep[2] = instep[2] + frac*(vert2[2] - instep[2]); - outstep[3] = instep[3] + frac*(vert2[3] - instep[3]); - outstep[4] = instep[4] + frac*(vert2[4] - instep[4]); - - outstep += sizeof (vec5_t) / sizeof (float); - outcount++; - } - - return outcount; -} - - -/* -================ -R_SetupAndDrawSprite -================ -*/ -void R_SetupAndDrawSprite () -{ - int i, nump; - float dot, scale, *pv; - vec5_t *pverts; - vec3_t left, up, right, down, transformed, local; - emitpoint_t outverts[MAXWORKINGVERTS+1], *pout; - - dot = DotProduct (r_spritedesc.vpn, modelorg); - -// backface cull - if (dot >= 0) - return; - -// build the sprite poster in worldspace - VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->right, right); - VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->up, up); - VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->left, left); - VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->down, down); - - pverts = clip_verts[0]; - - pverts[0][0] = r_entorigin[0] + up[0] + left[0]; - pverts[0][1] = r_entorigin[1] + up[1] + left[1]; - pverts[0][2] = r_entorigin[2] + up[2] + left[2]; - pverts[0][3] = 0; - pverts[0][4] = 0; - - pverts[1][0] = r_entorigin[0] + up[0] + right[0]; - pverts[1][1] = r_entorigin[1] + up[1] + right[1]; - pverts[1][2] = r_entorigin[2] + up[2] + right[2]; - pverts[1][3] = sprite_width; - pverts[1][4] = 0; - - pverts[2][0] = r_entorigin[0] + down[0] + right[0]; - pverts[2][1] = r_entorigin[1] + down[1] + right[1]; - pverts[2][2] = r_entorigin[2] + down[2] + right[2]; - pverts[2][3] = sprite_width; - pverts[2][4] = sprite_height; - - pverts[3][0] = r_entorigin[0] + down[0] + left[0]; - pverts[3][1] = r_entorigin[1] + down[1] + left[1]; - pverts[3][2] = r_entorigin[2] + down[2] + left[2]; - pverts[3][3] = 0; - pverts[3][4] = sprite_height; - -// clip to the frustum in worldspace - nump = 4; - clip_current = 0; - - for (i=0 ; i<4 ; i++) - { - nump = R_ClipSpriteFace (nump, &view_clipplanes[i]); - if (nump < 3) - return; - if (nump >= MAXWORKINGVERTS) - Sys_Error("R_SetupAndDrawSprite: too many points"); - } - -// transform vertices into viewspace and project - pv = &clip_verts[clip_current][0][0]; - r_spritedesc.nearzi = -999999; - - for (i=0 ; izi = 1.0 / transformed[2]; - if (pout->zi > r_spritedesc.nearzi) - r_spritedesc.nearzi = pout->zi; - - pout->s = pv[3]; - pout->t = pv[4]; - - scale = xscale * pout->zi; - pout->u = (xcenter + scale * transformed[0]); - - scale = yscale * pout->zi; - pout->v = (ycenter - scale * transformed[1]); - - pv += sizeof (vec5_t) / sizeof (*pv); - } - -// draw it - r_spritedesc.nump = nump; - r_spritedesc.pverts = outverts; - D_DrawSprite (); -} - - -/* -================ -R_GetSpriteframe -================ -*/ -mspriteframe_t *R_GetSpriteframe (msprite_t *psprite) -{ - mspritegroup_t *pspritegroup; - mspriteframe_t *pspriteframe; - int i, numframes, frame; - float *pintervals, fullinterval, targettime, time; - - frame = currententity->frame; - - if ((frame >= psprite->numframes) || (frame < 0)) - { - Con_Printf ("R_DrawSprite: no such frame %d\n", frame); - frame = 0; - } - - if (psprite->frames[frame].type == SPR_SINGLE) - { - pspriteframe = psprite->frames[frame].frameptr; - } - else - { - pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; - pintervals = pspritegroup->intervals; - numframes = pspritegroup->numframes; - fullinterval = pintervals[numframes-1]; - - time = cl.time + currententity->syncbase; - - // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values - // are positive, so we don't have to worry about division by 0 - targettime = time - ((int)(time / fullinterval)) * fullinterval; - - for (i=0 ; i<(numframes-1) ; i++) - { - if (pintervals[i] > targettime) - break; - } - - pspriteframe = pspritegroup->frames[i]; - } - - return pspriteframe; -} - - -/* -================ -R_DrawSprite -================ -*/ -void R_DrawSprite (void) -{ - int i; - msprite_t *psprite; - vec3_t tvec; - float dot, angle, sr, cr; - - psprite = currententity->model->cache.data; - - r_spritedesc.pspriteframe = R_GetSpriteframe (psprite); - - sprite_width = r_spritedesc.pspriteframe->width; - sprite_height = r_spritedesc.pspriteframe->height; - -// TODO: make this caller-selectable - if (psprite->type == SPR_FACING_UPRIGHT) - { - // generate the sprite's axes, with vup straight up in worldspace, and - // r_spritedesc.vright perpendicular to modelorg. - // This will not work if the view direction is very close to straight up or - // down, because the cross product will be between two nearly parallel - // vectors and starts to approach an undefined state, so we don't draw if - // the two vectors are less than 1 degree apart - tvec[0] = -modelorg[0]; - tvec[1] = -modelorg[1]; - tvec[2] = -modelorg[2]; - VectorNormalize (tvec); - dot = tvec[2]; // same as DotProduct (tvec, r_spritedesc.vup) because - // r_spritedesc.vup is 0, 0, 1 - if ((dot > 0.999848) || (dot < -0.999848)) // cos(1 degree) = 0.999848 - return; - r_spritedesc.vup[0] = 0; - r_spritedesc.vup[1] = 0; - r_spritedesc.vup[2] = 1; - r_spritedesc.vright[0] = tvec[1]; - // CrossProduct(r_spritedesc.vup, -modelorg, - r_spritedesc.vright[1] = -tvec[0]; - // r_spritedesc.vright) - r_spritedesc.vright[2] = 0; - VectorNormalize (r_spritedesc.vright); - r_spritedesc.vpn[0] = -r_spritedesc.vright[1]; - r_spritedesc.vpn[1] = r_spritedesc.vright[0]; - r_spritedesc.vpn[2] = 0; - // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, - // r_spritedesc.vpn) - } - else if (psprite->type == SPR_VP_PARALLEL) - { - // generate the sprite's axes, completely parallel to the viewplane. There - // are no problem situations, because the sprite is always in the same - // position relative to the viewer - for (i=0 ; i<3 ; i++) - { - r_spritedesc.vup[i] = vup[i]; - r_spritedesc.vright[i] = vright[i]; - r_spritedesc.vpn[i] = vpn[i]; - } - } - else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT) - { - // generate the sprite's axes, with vup straight up in worldspace, and - // r_spritedesc.vright parallel to the viewplane. - // This will not work if the view direction is very close to straight up or - // down, because the cross product will be between two nearly parallel - // vectors and starts to approach an undefined state, so we don't draw if - // the two vectors are less than 1 degree apart - dot = vpn[2]; // same as DotProduct (vpn, r_spritedesc.vup) because - // r_spritedesc.vup is 0, 0, 1 - if ((dot > 0.999848) || (dot < -0.999848)) // cos(1 degree) = 0.999848 - return; - r_spritedesc.vup[0] = 0; - r_spritedesc.vup[1] = 0; - r_spritedesc.vup[2] = 1; - r_spritedesc.vright[0] = vpn[1]; - // CrossProduct (r_spritedesc.vup, vpn, - r_spritedesc.vright[1] = -vpn[0]; // r_spritedesc.vright) - r_spritedesc.vright[2] = 0; - VectorNormalize (r_spritedesc.vright); - r_spritedesc.vpn[0] = -r_spritedesc.vright[1]; - r_spritedesc.vpn[1] = r_spritedesc.vright[0]; - r_spritedesc.vpn[2] = 0; - // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, - // r_spritedesc.vpn) - } - else if (psprite->type == SPR_ORIENTED) - { - // generate the sprite's axes, according to the sprite's world orientation - AngleVectors (currententity->angles, r_spritedesc.vpn, - r_spritedesc.vright, r_spritedesc.vup); - } - else if (psprite->type == SPR_VP_PARALLEL_ORIENTED) - { - // generate the sprite's axes, parallel to the viewplane, but rotated in - // that plane around the center according to the sprite entity's roll - // angle. So vpn stays the same, but vright and vup rotate - angle = currententity->angles[ROLL] * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); - - for (i=0 ; i<3 ; i++) - { - r_spritedesc.vpn[i] = vpn[i]; - r_spritedesc.vright[i] = vright[i] * cr + vup[i] * sr; - r_spritedesc.vup[i] = vright[i] * -sr + vup[i] * cr; - } - } - else - { - Sys_Error ("R_DrawSprite: Bad sprite type %d", psprite->type); - } - - R_RotateSprite (psprite->beamlength); - - R_SetupAndDrawSprite (); -} - diff --git a/source/r_vars.c b/source/r_vars.c deleted file mode 100644 index eb41290..0000000 --- a/source/r_vars.c +++ /dev/null @@ -1,39 +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_vars.c: global refresh variables - -#include "quakedef.h" - -#if !id386 - -// all global and static refresh variables are collected in a contiguous block -// to avoid cache conflicts. - -//------------------------------------------------------- -// global refresh variables -//------------------------------------------------------- - -// FIXME: make into one big structure, like cl or sv -// FIXME: do separately for refresh engine and driver - -int r_bmodelactive; - -#endif // !id386 - diff --git a/source/view.c b/source/view.c index 6c5d64f..86f6498 100644 --- a/source/view.c +++ b/source/view.c @@ -338,29 +338,27 @@ cshift_t cshift_water = { {130,80,50}, 128 }; cshift_t cshift_slime = { {0,25,5}, 150 }; cshift_t cshift_lava = { {255,80,0}, 150 }; -cvar_t v_gamma = {"gamma", "2", true}; +cvar_t v_gamma = {"gamma", "1.0", true}; byte gammatable[256]; // palette is sent through this -#ifdef GLQUAKE byte ramps[3][256]; float v_blend[4]; // rgba 0.0 - 1.0 -#endif // GLQUAKE void BuildGammaTable (float g) { int i, inf; - + if (g == 1.0) { for (i=0 ; i<256 ; i++) gammatable[i] = i; return; } - + for (i=0 ; i<256 ; i++) { - inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5; + inf = 255 * powf ( (i+0.5f)/255.5f , g ) + 0.5; if (inf < 0) inf = 0; if (inf > 255) @@ -569,13 +567,13 @@ void V_CalcBlend (void) b = 0; a = 0; - for (j=0 ; j