1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126 |
- #include "r_local.h"
- #ifndef id386
- void R_SurfacePatch (void)
- {
- }
- void R_EdgeCodeStart (void)
- {
- }
- void R_EdgeCodeEnd (void)
- {
- }
- #endif
- #if 0
- 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
- 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;
- edge_t *newedges[MAXHEIGHT];
- edge_t *removeedges[MAXHEIGHT];
- espan_t *span_p, *max_span_p;
- int r_currentkey;
- 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;
- static int miplevel;
- float scale_for_mip;
- int ubasestep, errorterm, erroradjustup, erroradjustdown;
- extern void R_RotateBmodel (void);
- extern void R_TransformFrustum (void);
- 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);
- void R_BeginEdgeFrame (void)
- {
- int v;
- edge_p = r_edges;
- edge_max = &r_edges[r_numallocatededges];
- surface_p = &surfaces[2];
-
- surfaces[1].spans = NULL;
- surfaces[1].flags = SURF_DRAWBACKGROUND;
- if (sw_draworder->value)
- {
- pdrawfunc = R_GenerateSpansBackward;
- surfaces[1].key = 0;
- r_currentkey = 1;
- }
- else
- {
- pdrawfunc = R_GenerateSpans;
- surfaces[1].key = 0x7FFfFFFF;
- r_currentkey = 0;
- }
- for (v=r_refdef.vrect.y ; v<r_refdef.vrectbottom ; v++)
- {
- newedges[v] = removeedges[v] = NULL;
- }
- }
- #if !id386
- void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist)
- {
- edge_t *next_edge;
- do
- {
- next_edge = edgestoadd->next;
- 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;
-
- addedge:
- edgestoadd->next = edgelist;
- edgestoadd->prev = edgelist->prev;
- edgelist->prev->next = edgestoadd;
- edgelist->prev = edgestoadd;
- } while ((edgestoadd = next_edge) != NULL);
- }
- #endif
-
- #if !id386
- void R_RemoveEdges (edge_t *pedge)
- {
- do
- {
- pedge->next->prev = pedge->prev;
- pedge->prev->next = pedge->next;
- } while ((pedge = pedge->nextremove) != NULL);
- }
- #endif
- #if !id386
- 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;
-
-
- pnext_edge = pedge->next;
-
- pedge->next->prev = pedge->prev;
- pedge->prev->next = pedge->next;
-
- pwedge = pedge->prev->prev;
- while (pwedge->u > pedge->u)
- {
- pwedge = pwedge->prev;
- }
-
- pedge->next = pwedge->next;
- pedge->prev = pwedge;
- pedge->next->prev = pedge;
- pwedge->next = pedge;
- pedge = pnext_edge;
- if (pedge == &edge_tail)
- return;
- }
- }
- #endif
- void R_CleanupSpan (void)
- {
- surf_t *surf;
- int iu;
- espan_t *span;
- 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;
- }
- do
- {
- surf->spanstate = 0;
- surf = surf->next;
- } while (surf != &surfaces[1]);
- }
- void R_LeadingEdgeBackwards (edge_t *edge)
- {
- espan_t *span;
- surf_t *surf, *surf2;
- int iu;
- surf = &surfaces[edge->surfs[1]];
- if (++surf->spanstate == 1)
- {
- surf2 = surfaces[1].next;
- if (surf->key > surf2->key)
- goto newtop;
-
-
- if (surf->insubmodel && (surf->key == surf2->key))
- {
-
-
- goto newtop;
- }
- continue_search:
- do
- {
- surf2 = surf2->next;
- } while (surf->key < surf2->key);
- if (surf->key == surf2->key)
- {
-
-
- if (!surf->insubmodel)
- goto continue_search;
-
-
- }
- goto gotposition;
- newtop:
-
- 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;
- }
-
- surf->last_u = iu;
-
- gotposition:
-
- surf->next = surf2;
- surf->prev = surf2->prev;
- surf2->prev->next = surf;
- surf2->prev = surf;
- }
- }
- void R_TrailingEdge (surf_t *surf, edge_t *edge)
- {
- espan_t *span;
- int iu;
- if (--surf->spanstate == 0)
- {
- if (surf == surfaces[1].next)
- {
-
- 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;
- }
-
- surf->next->last_u = iu;
- }
- surf->prev->next = surf->next;
- surf->next->prev = surf->prev;
- }
- }
- #if !id386
- void R_LeadingEdge (edge_t *edge)
- {
- espan_t *span;
- surf_t *surf, *surf2;
- int iu;
- float fu, newzi, testzi, newzitop, newzibottom;
- if (edge->surfs[1])
- {
-
- surf = &surfaces[edge->surfs[1]];
-
-
-
- if (++surf->spanstate == 1)
- {
- surf2 = surfaces[1].next;
- if (surf->key < surf2->key)
- goto newtop;
-
-
- if (surf->insubmodel && (surf->key == surf2->key))
- {
-
- 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 (!surf->insubmodel)
- goto continue_search;
-
- 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:
-
- 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;
- }
-
- surf->last_u = iu;
-
- gotposition:
-
- surf->next = surf2;
- surf->prev = surf2->prev;
- surf2->prev->next = surf;
- surf2->prev = surf;
- }
- }
- }
- void R_GenerateSpans (void)
- {
- edge_t *edge;
- surf_t *surf;
- surfaces[1].next = surfaces[1].prev = &surfaces[1];
- surfaces[1].last_u = edge_head_u_shift20;
- for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
- {
- if (edge->surfs[0])
- {
-
- surf = &surfaces[edge->surfs[0]];
- R_TrailingEdge (surf, edge);
- if (!edge->surfs[1])
- continue;
- }
- R_LeadingEdge (edge);
- }
- R_CleanupSpan ();
- }
- #endif
- void R_GenerateSpansBackward (void)
- {
- edge_t *edge;
- surfaces[1].next = surfaces[1].prev = &surfaces[1];
- surfaces[1].last_u = edge_head_u_shift20;
- 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 ();
- }
- 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;
- 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;
- edge_aftertail.u_step = 0;
- edge_aftertail.next = &edge_sentinel;
- edge_aftertail.prev = &edge_tail;
- edge_sentinel.u = 2000 << 24;
- edge_sentinel.prev = &edge_aftertail;
- bottom = r_refdef.vrectbottom - 1;
- for (iv=r_refdef.vrect.y ; iv<bottom ; iv++)
- {
- current_iv = iv;
- fv = (float)iv;
-
- surfaces[1].spanstate = 1;
- if (newedges[iv])
- {
- R_InsertNewEdges (newedges[iv], edge_head.next);
- }
- (*pdrawfunc) ();
-
-
- if (span_p > max_span_p)
- {
- D_DrawSurfaces ();
-
- for (s = &surfaces[1] ; s<surface_p ; s++)
- s->spans = NULL;
- span_p = basespan_p;
- }
- if (removeedges[iv])
- R_RemoveEdges (removeedges[iv]);
- if (edge_head.next != &edge_tail)
- R_StepActiveU (edge_head.next);
- }
- current_iv = iv;
- fv = (float)iv;
- surfaces[1].spanstate = 1;
- if (newedges[iv])
- R_InsertNewEdges (newedges[iv], edge_head.next);
- (*pdrawfunc) ();
- D_DrawSurfaces ();
- }
- msurface_t *pface;
- surfcache_t *pcurrentcache;
- vec3_t transformed_modelorg;
- vec3_t world_transformed_modelorg;
- vec3_t local_modelorg;
- int D_MipLevelForScale (float scale)
- {
- int lmiplevel;
- if (scale >= d_scalemip[0] )
- lmiplevel = 0;
- else if (scale >= d_scalemip[1] )
- lmiplevel = 1;
- else if (scale >= d_scalemip[2] )
- lmiplevel = 2;
- else
- lmiplevel = 3;
- if (lmiplevel < d_minmip)
- lmiplevel = d_minmip;
- return lmiplevel;
- }
- void D_FlatFillSurface (surf_t *surf, int color)
- {
- espan_t *span;
- byte *pdest;
- int u, u2;
-
- for (span=surf->spans ; span ; span=span->pnext)
- {
- pdest = (byte *)d_viewbuffer + r_screenwidth*span->v;
- u = span->u;
- u2 = span->u + span->count - 1;
- for ( ; u <= u2 ; u++)
- pdest[u] = color;
- }
- }
- void D_CalcGradients (msurface_t *pface)
- {
- mplane_t *pplane;
- float mipscale;
- vec3_t p_temp1;
- vec3_t p_saxis, p_taxis;
- float t;
- pplane = pface->plane;
- mipscale = 1.0 / (float)(1 << miplevel);
- TransformVector (pface->texinfo->vecs[0], p_saxis);
- TransformVector (pface->texinfo->vecs[1], p_taxis);
- t = xscaleinv * mipscale;
- d_sdivzstepu = p_saxis[0] * t;
- d_tdivzstepu = p_taxis[0] * t;
- t = yscaleinv * mipscale;
- d_sdivzstepv = -p_saxis[1] * t;
- d_tdivzstepv = -p_taxis[1] * t;
- d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
- ycenter * d_sdivzstepv;
- d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
- ycenter * d_tdivzstepv;
- VectorScale (transformed_modelorg, mipscale, p_temp1);
- t = 0x10000*mipscale;
- sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
- ((pface->texturemins[0] << 16) >> miplevel)
- + pface->texinfo->vecs[0][3]*t;
- tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
- ((pface->texturemins[1] << 16) >> miplevel)
- + pface->texinfo->vecs[1][3]*t;
-
- if (pface->texinfo->flags & SURF_FLOWING)
- {
- if(pface->texinfo->flags & SURF_WARP)
- sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.25) - (int)(r_newrefdef.time * 0.25) ));
- else
- sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.77) - (int)(r_newrefdef.time * 0.77) ));
- }
-
- bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
- bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
- }
- void D_BackgroundSurf (surf_t *s)
- {
- d_zistepu = 0;
- d_zistepv = 0;
- d_ziorigin = -0.9;
- D_FlatFillSurface (s, (int)sw_clearcolor->value & 0xFF);
- D_DrawZSpans (s->spans);
- }
- void D_TurbulentSurf (surf_t *s)
- {
- d_zistepu = s->d_zistepu;
- d_zistepv = s->d_zistepv;
- d_ziorigin = s->d_ziorigin;
- pface = s->msurf;
- miplevel = 0;
- cacheblock = pface->texinfo->image->pixels[0];
- cachewidth = 64;
- if (s->insubmodel)
- {
-
-
- currententity = s->entity;
-
- VectorSubtract (r_origin, currententity->origin,
- local_modelorg);
- TransformVector (local_modelorg, transformed_modelorg);
- R_RotateBmodel ();
-
- }
- D_CalcGradients (pface);
-
- if(!(pface->texinfo->flags & SURF_WARP))
- NonTurbulent8 (s->spans);
- else
- Turbulent8 (s->spans);
- D_DrawZSpans (s->spans);
- if (s->insubmodel)
- {
-
-
-
-
-
- currententity = NULL;
- VectorCopy (world_transformed_modelorg,
- transformed_modelorg);
- VectorCopy (base_vpn, vpn);
- VectorCopy (base_vup, vup);
- VectorCopy (base_vright, vright);
- R_TransformFrustum ();
- }
- }
- void D_SkySurf (surf_t *s)
- {
- pface = s->msurf;
- miplevel = 0;
- if (!pface->texinfo->image)
- return;
- cacheblock = pface->texinfo->image->pixels[0];
- cachewidth = 256;
- d_zistepu = s->d_zistepu;
- d_zistepv = s->d_zistepv;
- d_ziorigin = s->d_ziorigin;
- D_CalcGradients (pface);
- D_DrawSpans16 (s->spans);
- d_zistepu = 0;
- d_zistepv = 0;
- d_ziorigin = -0.9;
- D_DrawZSpans (s->spans);
- }
- void D_SolidSurf (surf_t *s)
- {
- d_zistepu = s->d_zistepu;
- d_zistepv = s->d_zistepv;
- d_ziorigin = s->d_ziorigin;
- if (s->insubmodel)
- {
-
-
- currententity = s->entity;
-
- VectorSubtract (r_origin, currententity->origin, local_modelorg);
- TransformVector (local_modelorg, transformed_modelorg);
- R_RotateBmodel ();
-
- }
- else
- currententity = &r_worldentity;
- pface = s->msurf;
- #if 1
- miplevel = D_MipLevelForScale(s->nearzi * scale_for_mip * pface->texinfo->mipadjust);
- #else
- {
- float dot;
- float normal[3];
- if ( s->insubmodel )
- {
- VectorCopy( pface->plane->normal, normal );
- dot = DotProduct( normal, vpn );
- }
- else
- {
- VectorCopy( pface->plane->normal, normal );
- dot = DotProduct( normal, vpn );
- }
- if ( pface->flags & SURF_PLANEBACK )
- dot = -dot;
- if ( dot > 0 )
- printf( "blah" );
- miplevel = D_MipLevelForScale(s->nearzi * scale_for_mip * pface->texinfo->mipadjust);
- }
- #endif
- pcurrentcache = D_CacheSurface (pface, miplevel);
- cacheblock = (pixel_t *)pcurrentcache->data;
- cachewidth = pcurrentcache->width;
- D_CalcGradients (pface);
- D_DrawSpans16 (s->spans);
- D_DrawZSpans (s->spans);
- if (s->insubmodel)
- {
-
-
-
-
-
- VectorCopy (world_transformed_modelorg,
- transformed_modelorg);
- VectorCopy (base_vpn, vpn);
- VectorCopy (base_vup, vup);
- VectorCopy (base_vright, vright);
- R_TransformFrustum ();
- currententity = NULL;
- }
- }
- void D_DrawflatSurfaces (void)
- {
- surf_t *s;
- for (s = &surfaces[1] ; s<surface_p ; s++)
- {
- if (!s->spans)
- continue;
- d_zistepu = s->d_zistepu;
- d_zistepv = s->d_zistepv;
- d_ziorigin = s->d_ziorigin;
-
-
- D_FlatFillSurface (s, (int)s->msurf & 0xFF);
- D_DrawZSpans (s->spans);
- }
- }
- void D_DrawSurfaces (void)
- {
- surf_t *s;
- VectorSubtract (r_origin, vec3_origin, modelorg);
- TransformVector (modelorg, transformed_modelorg);
- VectorCopy (transformed_modelorg, world_transformed_modelorg);
- if (!sw_drawflat->value)
- {
- for (s = &surfaces[1] ; s<surface_p ; s++)
- {
- if (!s->spans)
- continue;
- r_drawnpolycount++;
- if (! (s->flags & (SURF_DRAWSKYBOX|SURF_DRAWBACKGROUND|SURF_DRAWTURB) ) )
- D_SolidSurf (s);
- else if (s->flags & SURF_DRAWSKYBOX)
- D_SkySurf (s);
- else if (s->flags & SURF_DRAWBACKGROUND)
- D_BackgroundSurf (s);
- else if (s->flags & SURF_DRAWTURB)
- D_TurbulentSurf (s);
- }
- }
- else
- D_DrawflatSurfaces ();
- currententity = NULL;
- VectorSubtract (r_origin, vec3_origin, modelorg);
- R_TransformFrustum ();
- }
|