diff --git a/r_bsp.c b/r_bsp.c index 683e766a..3fcbb62d 100644 --- a/r_bsp.c +++ b/r_bsp.c @@ -947,106 +947,3 @@ void R_RenderWorld (void) R_RecursiveWorldNode (RI.currentmodel->nodes, 15); } - - - -/* -================ -R_DrawBrushModel - -not covered by edge drawing -================ -*/ -void R_DrawBrushModel(cl_entity_t *pent) -{ - int i; - vec_t dot; - msurface_t *psurf; - int numsurfaces; - mplane_t *pplane; - vec3_t mins, maxs; - float minmaxs[6]; - int clipflags, k; - model_t *pmodel; - vec3_t oldorigin; - VectorCopy (modelorg, oldorigin); - insubmodel = true; - if( !pent || !pent->model ) - return; - - pmodel = pent->model; - - if (pmodel->type != mod_brush) - return; - - if (pmodel->nummodelsurfaces == 0) - return; // clip brush only -#if 1 -// FIXME: use bounding-box-based frustum clipping info? - RotatedBBox (pmodel->mins, pmodel->maxs, - RI.currententity->angles, mins, maxs); - - VectorAdd (mins, RI.currententity->origin, minmaxs); - VectorAdd (maxs, RI.currententity->origin, (minmaxs+3)); - - clipflags = R_BmodelCheckBBox (minmaxs); - if (clipflags == BMODEL_FULLY_CLIPPED) - return; // off the edge of the screen - - R_RotateBmodel (); - - VectorCopy (RI.currententity->origin, r_entorigin); - VectorSubtract (r_origin, r_entorigin, modelorg); - //VectorSubtract (r_origin, RI.currententity->origin, modelorg); - - r_pcurrentvertbase = pmodel->vertexes; - - // calculate dynamic lighting for bmodel - for( k = 0; k < MAX_DLIGHTS; k++ ) - { - dlight_t *l = gEngfuncs.GetDynamicLight( k ); - - if( l->die < gpGlobals->time || !l->radius ) - continue; - - /*VectorCopy( l->origin, oldorigin ); // save lightorigin - Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l ); - VectorCopy( origin_l, l->origin ); // move light in bmodel space - R_MarkLights( l, 1<nodes + clmodel->hulls[0].firstclipnode ); - VectorCopy( oldorigin, l->origin ); // restore lightorigin*/ - R_MarkLights( l, 1<nodes + pmodel->hulls[0].firstclipnode ); - } -#endif - psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; - numsurfaces = pmodel->nummodelsurfaces; - //R_TransformFrustum (); - - 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_BuildPolygonFromSurface( psurf ); - R_ClipAndDrawPoly( pent->curstate.renderamt / 255, !!(psurf->flags & SURF_DRAWTURB), true ); - - } - } - - // put back world rotation and frustum clipping - // FIXME: R_RotateBmodel should just work off base_vxx - VectorCopy (base_vpn, vpn); - VectorCopy (base_vup, vup); - VectorCopy (base_vright, vright); - VectorCopy (oldorigin, modelorg); - R_TransformFrustum (); -} - - diff --git a/r_edge.c b/r_edge.c index 490204f6..e20d3908 100644 --- a/r_edge.c +++ b/r_edge.c @@ -981,6 +981,109 @@ void D_SkySurf (surf_t *s) D_DrawZSpans (s->spans); } +qboolean alphaspans; + + +void D_AlphaSpans16 (espan_t *pspan); +void D_BlendSpans16 (espan_t *pspan, int alpha ); +void TurbulentZ8 (espan_t *pspan, int alpha ); +/* +============== +D_SolidSurf + +Normal surface cached, texture mapped surface +============== +*/ +void D_AlphaSurf (surf_t *s) +{ + d_zistepu = s->d_zistepu; + d_zistepv = s->d_zistepv; + d_ziorigin = s->d_ziorigin; + if(s->flags & SURF_DRAWSKY) + return; + if (!s->insubmodel) // wtf? how it is possible? + return; + +// FIXME: we don't want to do all this for every polygon! +// TODO: store once at start of frame + RI.currententity = s->entity; //FIXME: make this passed in to + // R_RotateBmodel () + VectorSubtract (RI.vieworg, RI.currententity->origin, local_modelorg); + TransformVector (local_modelorg, transformed_modelorg); + + R_RotateBmodel (); // FIXME: don't mess with the frustum, + // make entity passed in + + + pface = s->msurf; + + + if( !pface ) + return; +#if 1 + + if( pface->flags & SURF_CONVEYOR ) + miplevel = 1; + else + miplevel = 0; +#else + { + float dot; + float normal[3]; + + if ( s->insubmodel ) + { + VectorCopy( pface->plane->normal, normal ); +// TransformVector( 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 + + if (s->flags & SURF_DRAWTURB ) + { + cacheblock = R_GetTexture(pface->texinfo->texture->gl_texturenum)->pixels[0]; + cachewidth = 64; + D_CalcGradients (pface); + TurbulentZ8( s->spans, RI.currententity->curstate.renderamt * 7 / 255 ); + } + else + { + // FIXME: make this passed in to D_CacheSurface + pcurrentcache = D_CacheSurface (pface, miplevel); + + cacheblock = (pixel_t *)pcurrentcache->data; + cachewidth = pcurrentcache->width; + + D_CalcGradients (pface); + + if( RI.currententity->curstate.rendermode == kRenderTransAlpha ) + D_AlphaSpans16(s->spans); + else + D_BlendSpans16(s->spans, RI.currententity->curstate.renderamt * 7 / 255 ); + } + + VectorCopy (world_transformed_modelorg, + transformed_modelorg); + VectorCopy (base_vpn, vpn); + VectorCopy (base_vup, vup); + VectorCopy (base_vright, vright); + R_TransformFrustum (); +} + /* ============== @@ -994,6 +1097,10 @@ void D_SolidSurf (surf_t *s) d_zistepu = s->d_zistepu; d_zistepv = s->d_zistepv; d_ziorigin = s->d_ziorigin; + if(s->flags & SURF_DRAWSKY) + return; + if (s->flags & SURF_DRAWTURB ) + return; if (s->insubmodel) { @@ -1008,7 +1115,11 @@ void D_SolidSurf (surf_t *s) // make entity passed in } else + { + if( alphaspans ) + return; RI.currententity = gEngfuncs.GetEntityByIndex(0); //r_worldentity; + } pface = s->msurf; @@ -1017,6 +1128,7 @@ void D_SolidSurf (surf_t *s) return; #if 1 + if( pface->flags & SURF_CONVEYOR ) miplevel = 1; else @@ -1130,7 +1242,9 @@ void D_DrawSurfaces (void) //r_drawnpolycount++; #if 1 - if(s->flags & SURF_DRAWSKY) + if( alphaspans ) + D_AlphaSurf (s); + else if(s->flags & SURF_DRAWSKY) D_BackgroundSurf (s); else if (s->flags & SURF_DRAWTURB ) D_TurbulentSurf (s); @@ -1151,7 +1265,7 @@ void D_DrawSurfaces (void) else D_DrawflatSurfaces (); - RI.currententity = NULL; //&r_worldentity; + //RI.currententity = NULL; //&r_worldentity; VectorSubtract (RI.vieworg, vec3_origin, modelorg); R_TransformFrustum (); } diff --git a/r_main.c b/r_main.c index 6e21ee2c..3637b419 100644 --- a/r_main.c +++ b/r_main.c @@ -1403,6 +1403,163 @@ void R_DrawBEntitiesOnList (void) insubmodel = false; } + +extern qboolean alphaspans; +/* +============= +R_DrawBEntitiesOnList +============= +*/ +void R_DrawBrushModel(cl_entity_t *pent) +{ + int i, clipflags; + vec3_t oldorigin; + vec3_t mins, maxs; + float minmaxs[6]; + mnode_t *topnode; + int k; + edge_t ledges[NUMSTACKEDGES + + ((CACHE_SIZE - 1) / sizeof(edge_t)) + 1]; + surf_t lsurfs[NUMSTACKSURFACES + + ((CACHE_SIZE - 1) / sizeof(surf_t)) + 1]; + + if ( !RI.drawWorld ) + return; + + if (auxedges) + { + r_edges = auxedges; + } + else + { + r_edges = (edge_t *) + (((long)&ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + } + + if (r_surfsonstack) + { + surfaces = (surf_t *) + (((long)&lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + surf_max = &surfaces[r_cnumsurfs]; + // surface 0 doesn't really exist; it's just a dummy because index 0 + // is used to indicate no edge attached to surface + memset(&surfaces[0], 0, sizeof(surf_t)); + surfaces--; + R_SurfacePatch (); + } + + + R_BeginEdgeFrame(); + + VectorCopy (modelorg, oldorigin); + insubmodel = true; + //r_dlightframecount = r_framecount; + + if (!RI.currentmodel) + return; + if (RI.currentmodel->nummodelsurfaces == 0) + return; // clip brush only + //if ( currententity->flags & RF_BEAM ) + //continue; + if (RI.currentmodel->type != mod_brush) + return; + // see if the bounding box lets us trivially reject, also sets + // trivial accept status + RotatedBBox (RI.currentmodel->mins, RI.currentmodel->maxs, + RI.currententity->angles, mins, maxs); +#if 0 + mins[0] = mins[0] - 100; + mins[1] = mins[1] - 100; + mins[2] = mins[2] - 100; + maxs[0] = maxs[0] + 100; + maxs[1] = maxs[1] + 100; + maxs[2] = maxs[2] + 100; +#endif + VectorAdd (mins, RI.currententity->origin, minmaxs); + VectorAdd (maxs, RI.currententity->origin, (minmaxs+3)); + + clipflags = R_BmodelCheckBBox (minmaxs); + if (clipflags == BMODEL_FULLY_CLIPPED) + return; // off the edge of the screen + //clipflags = 0; + + topnode = R_FindTopnode (minmaxs, minmaxs+3); + if (!topnode) + return; // no part in a visible leaf + + alphaspans = true; + VectorCopy (RI.currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + //VectorSubtract (r_origin, RI.currententity->origin, modelorg); + r_pcurrentvertbase = RI.currentmodel->vertexes; + + // FIXME: stop transforming twice + R_RotateBmodel (); + + // calculate dynamic lighting for bmodel + // this will reset RI.currententity, do we need this? + //R_PushDlights (); + /*if (clmodel->firstmodelsurface != 0) + { + for (k=0 ; knodes + clmodel->firstnode); + } + }*/ + + // calculate dynamic lighting for bmodel + for( k = 0; k < MAX_DLIGHTS; k++ ) + { + dlight_t *l = gEngfuncs.GetDynamicLight( k ); + + if( l->die < gpGlobals->time || !l->radius ) + continue; + + /*VectorCopy( l->origin, oldorigin ); // save lightorigin + Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l ); + VectorCopy( origin_l, l->origin ); // move light in bmodel space + R_MarkLights( l, 1<nodes + clmodel->hulls[0].firstclipnode ); + VectorCopy( oldorigin, l->origin ); // restore lightorigin*/ + R_MarkLights( l, 1<nodes + RI.currentmodel->hulls[0].firstclipnode ); + } + + // RI.currentmodel = tr.draw_list->solid_entities[i]->model; + // RI.currententity = tr.draw_list->solid_entities[i]; + RI.currententity->topnode = topnode; +//ASSERT( RI.currentmodel == tr.draw_list->solid_entities[i]->model ); + if (topnode->contents >= 0) + { + // not a leaf; has to be clipped to the world BSP + r_clipflags = clipflags; + R_DrawSolidClippedSubmodelPolygons (RI.currentmodel, topnode); + } + else + { + // falls entirely in one leaf, so we just put all the + // edges in the edge list and let 1/z sorting handle + // drawing order + //ASSERT( RI.currentmodel == tr.draw_list->solid_entities[i]->model ); + + + R_DrawSubmodelPolygons (RI.currentmodel, clipflags, topnode); + } + RI.currententity->topnode = NULL; + + // put back world rotation and frustum clipping + // FIXME: R_RotateBmodel should just work off base_vxx + VectorCopy (base_vpn, vpn); + VectorCopy (base_vup, vup); + VectorCopy (base_vright, vright); + VectorCopy (oldorigin, modelorg); + R_TransformFrustum (); + + + insubmodel = false; + R_ScanEdges(); + alphaspans = false; +} + #endif /* diff --git a/r_scan.c b/r_scan.c index 0df3f8c9..8a31b90e 100644 --- a/r_scan.c +++ b/r_scan.c @@ -24,9 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "r_local.h" pixel_t *r_turb_pbase, *r_turb_pdest; +short *r_turb_pz; fixed16_t r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep; +int r_turb_izistep, r_turb_izi; int *r_turb_turb; static int r_turb_spancount; +int alpha; void D_DrawTurbulent8Span (void); @@ -115,6 +118,36 @@ void D_DrawTurbulent8Span (void) } while (--r_turb_spancount > 0); } + +/* +============= +D_DrawTurbulent8Span +============= +*/ +void D_DrawTurbulent8ZSpan (void) +{ + int sturb, tturb; + + do + { + sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63; + tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63; + if (*r_turb_pz <= (r_turb_izi >> 16)) + { + pixel_t btemp = *(r_turb_pbase + (tturb<<6) + sturb); + if( alpha == 7 ) + *r_turb_pdest = btemp; + else + *r_turb_pdest = BLEND_ALPHA( alpha, btemp, *r_turb_pdest); + } + r_turb_pdest++; + r_turb_pz++; + r_turb_izi += r_turb_izistep; + r_turb_s += r_turb_sstep; + r_turb_t += r_turb_tstep; + } while (--r_turb_spancount > 0); +} + #endif // !id386 @@ -250,6 +283,146 @@ void Turbulent8 (espan_t *pspan) } while ((pspan = pspan->pnext) != NULL); } + +/* +============= +Turbulent8 +============= +*/ +void TurbulentZ8 (espan_t *pspan, int alpha1) +{ + int count; + fixed16_t snext, tnext; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz16stepu, tdivz16stepu, zi16stepu; + alpha = alpha1; + + r_turb_turb = sintable + ((int)(gpGlobals->time*SPEED)&(CYCLE-1)); + + r_turb_sstep = 0; // keep compiler happy + r_turb_tstep = 0; // ditto + + r_turb_pbase = (unsigned char *)cacheblock; + + sdivz16stepu = d_sdivzstepu * 16; + tdivz16stepu = d_tdivzstepu * 16; + zi16stepu = d_zistepu * 16; + r_turb_izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + r_turb_pdest = (d_viewbuffer + + (r_screenwidth * pspan->v) + pspan->u); + r_turb_pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + r_turb_izi = (int)(zi * 0x8000 * 0x10000); + + r_turb_s = (int)(sdivz * z) + sadjust; + if (r_turb_s > bbextents) + r_turb_s = bbextents; + else if (r_turb_s < 0) + r_turb_s = 0; + + r_turb_t = (int)(tdivz * z) + tadjust; + if (r_turb_t > bbextentt) + r_turb_t = bbextentt; + else if (r_turb_t < 0) + r_turb_t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 16) + r_turb_spancount = 16; + else + r_turb_spancount = count; + + count -= r_turb_spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz16stepu; + tdivz += tdivz16stepu; + zi += zi16stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 16) + snext = 16; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 16) + tnext = 16; // guard against round-off error on <0 steps + + r_turb_sstep = (snext - r_turb_s) >> 4; + r_turb_tstep = (tnext - r_turb_t) >> 4; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(r_turb_spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 16) + snext = 16; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 16) + tnext = 16; // guard against round-off error on <0 steps + + if (r_turb_spancount > 1) + { + r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1); + r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1); + } + } + + r_turb_s = r_turb_s & ((CYCLE<<16)-1); + r_turb_t = r_turb_t & ((CYCLE<<16)-1); + + D_DrawTurbulent8ZSpan (); + + r_turb_s = snext; + r_turb_t = tnext; + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + + + //==================== //PGM /* @@ -570,6 +743,397 @@ void D_DrawSpans16 (espan_t *pspan) } while ((pspan = pspan->pnext) != NULL); } + +/* +============= +D_DrawSpans16 + + FIXME: actually make this subdivide by 16 instead of 8!!! +============= +*/ +void D_AlphaSpans16 (espan_t *pspan) +{ + int count, spancount; + pixel_t *pbase, *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz8stepu, tdivz8stepu, zi8stepu; + int izi, izistep; + short *pz; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + pbase = (unsigned char *)cacheblock; + + sdivz8stepu = d_sdivzstepu * 8; + tdivz8stepu = d_tdivzstepu * 8; + zi8stepu = d_zistepu * 8; + izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + pdest = (d_viewbuffer + + (r_screenwidth * pspan->v) + pspan->u); + pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + izi = (int)(zi * 0x8000 * 0x10000); + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + s = (int)(sdivz * z) + sadjust; + if (s > bbextents) + s = bbextents; + else if (s < 0) + s = 0; + + t = (int)(tdivz * z) + tadjust; + if (t > bbextentt) + t = bbextentt; + else if (t < 0) + t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 8) + spancount = 8; + else + spancount = count; + + count -= spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz8stepu; + tdivz += tdivz8stepu; + zi += zi8stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + sstep = (snext - s) >> 3; + tstep = (tnext - t) >> 3; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + if (spancount > 1) + { + sstep = (snext - s) / (spancount - 1); + tstep = (tnext - t) / (spancount - 1); + } + } + + + // Drawing phrase + if (sw_texfilt->value == 0.0f) + { + do + { + pixel_t btemp; + + btemp = *(pbase + (s >> 16) + (t >> 16) * cachewidth); + if (btemp != TRANSPARENT_COLOR) + { + if (*pz <= (izi >> 16)) + { + *pdest = btemp; + *pz = izi >> 16; + } + } + pdest++; + pz++; + izi += izistep; + s += sstep; + t += tstep; + } while (--spancount > 0); + } + else if (sw_texfilt->value == 1.0f) + { + do + { + if (*pz <= (izi >> 16)) + { + int idiths = s; + int iditht = t; + + int X = (pspan->u + spancount) & 1; + int Y = (pspan->v)&1; + pixel_t btemp; + + //Using the kernel + idiths += kernel[X][Y][0]; + iditht += kernel[X][Y][1]; + + idiths = idiths >> 16; + idiths = idiths ? idiths -1 : idiths; + + + iditht = iditht >> 16; + iditht = iditht ? iditht -1 : iditht; + + + btemp = *(pbase + idiths + iditht * cachewidth); + if (btemp != TRANSPARENT_COLOR) + { + *pdest = btemp; + *pz = izi >> 16; + } + } + pdest++; + pz++; + s += sstep; + t += tstep; + } while (--spancount > 0); + } + + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + + + +/* +============= +D_DrawSpans16 + + FIXME: actually make this subdivide by 16 instead of 8!!! +============= +*/ +void D_BlendSpans16 (espan_t *pspan, int alpha) +{ + int count, spancount; + pixel_t *pbase, *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz8stepu, tdivz8stepu, zi8stepu; + int izi, izistep; + short *pz; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + pbase = (unsigned char *)cacheblock; + + sdivz8stepu = d_sdivzstepu * 8; + tdivz8stepu = d_tdivzstepu * 8; + zi8stepu = d_zistepu * 8; + izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + pdest = (d_viewbuffer + + (r_screenwidth * pspan->v) + pspan->u); + pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + izi = (int)(zi * 0x8000 * 0x10000); + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + s = (int)(sdivz * z) + sadjust; + if (s > bbextents) + s = bbextents; + else if (s < 0) + s = 0; + + t = (int)(tdivz * z) + tadjust; + if (t > bbextentt) + t = bbextentt; + else if (t < 0) + t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 8) + spancount = 8; + else + spancount = count; + + count -= spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz8stepu; + tdivz += tdivz8stepu; + zi += zi8stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + sstep = (snext - s) >> 3; + tstep = (tnext - t) >> 3; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + if (spancount > 1) + { + sstep = (snext - s) / (spancount - 1); + tstep = (tnext - t) / (spancount - 1); + } + } + + + // Drawing phrase + if (sw_texfilt->value == 0.0f) + { + do + { + if (*pz <= (izi >> 16)) + { + pixel_t btemp; + + btemp = *(pbase + (s >> 16) + (t >> 16) * cachewidth); + + if( alpha != 7 ) + btemp = BLEND_ALPHA( alpha, btemp, *pdest); + *pdest = btemp; + //*pz = izi >> 16; + } + pdest++; + pz++; + izi += izistep; + s += sstep; + t += tstep; + } while (--spancount > 0); + } + else if (sw_texfilt->value == 1.0f) + { + do + { + int idiths = s; + int iditht = t; + + int X = (pspan->u + spancount) & 1; + int Y = (pspan->v)&1; + if (*pz <= (izi >> 16)) + { + pixel_t btemp; + + //Using the kernel + idiths += kernel[X][Y][0]; + iditht += kernel[X][Y][1]; + + idiths = idiths >> 16; + idiths = idiths ? idiths -1 : idiths; + + + iditht = iditht >> 16; + iditht = iditht ? iditht -1 : iditht; + + btemp = *(pbase + idiths + iditht * cachewidth); + + if( alpha != 7 ) + btemp = BLEND_ALPHA( alpha, btemp, *pdest); + *pdest = btemp; + //*pz = izi >> 16; + } + pdest++; + pz++; + izi += izistep; + s += sstep; + t += tstep; + } while (--spancount > 0); + } + + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + #endif