// // R_AddLine // Clips the given segment // and adds any visible pieces to the line list. // static void R_AddLine(seg_t *line) { int x1; int x2; angle_t angle1; angle_t angle2; angle_t span; angle_t tspan; static sector_t tempsec; // killough 3/8/98: ceiling/water hack curline = line; angle1 = R_PointToAngleEx(line->v1->x, line->v1->y); angle2 = R_PointToAngleEx(line->v2->x, line->v2->y); // Clip to view edges. span = angle1 - angle2; // Back side? I.e. backface culling? if (span >= ANG180) return; // Global angle needed by segcalc. angle1 -= viewangle; angle2 -= viewangle; tspan = angle1 + clipangle; if (tspan > 2 * clipangle) { tspan -= 2 * clipangle; // Totally off the left edge? if (tspan >= span) return; angle1 = clipangle; } tspan = clipangle - angle2; if (tspan > 2 * clipangle) { tspan -= 2 * clipangle; // Totally off the left edge? if (tspan >= span) return; angle2 = 0 - clipangle; } // The seg is in the view range, // but not necessarily visible. angle1 = (angle1 + ANG90) >> ANGLETOFINESHIFT; angle2 = (angle2 + ANG90) >> ANGLETOFINESHIFT; // killough 1/31/98: Here is where "slime trails" can SOMETIMES occur: x1 = viewangletox[angle1]; x2 = viewangletox[angle2]; // Does not cross a pixel? if (x1 >= x2) return; backsector = line->backsector; // Single sided line? if (!backsector) goto clipsolid; // [AM] Interpolate sector movement before // running clipping tests. Frontsector // should already be interpolated. R_MaybeInterpolateSector(backsector); // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); doorclosed = false; // killough 4/16/98 // Closed door. if (backsector->interpceilingheight <= frontsector->interpfloorheight || backsector->interpfloorheight >= frontsector->interpceilingheight) goto clipsolid; // This fixes the automap floor height bug -- killough 1/18/98: // killough 4/7/98: optimize: save result in doorclosed for use in r_segs.c if ((doorclosed = R_DoorClosed())) goto clipsolid; // Window. if (backsector->interpceilingheight != frontsector->interpceilingheight || backsector->interpfloorheight != frontsector->interpfloorheight) goto clippass; // Reject empty lines used for triggers // and special events. // Identical floor and ceiling on both sides, // identical light levels on both sides, // and no middle texture. if (backsector->ceilingpic == frontsector->ceilingpic && backsector->floorpic == frontsector->floorpic && backsector->lightlevel == frontsector->lightlevel && !curline->sidedef->midtexture // killough 3/7/98: Take flats offsets into account: && backsector->floor_xoffs == frontsector->floor_xoffs && backsector->floor_yoffs == frontsector->floor_yoffs && backsector->ceiling_xoffs == frontsector->ceiling_xoffs && backsector->ceiling_yoffs == frontsector->ceiling_yoffs // killough 4/16/98: consider altered lighting && backsector->floorlightsec == frontsector->floorlightsec && backsector->ceilinglightsec == frontsector->ceilinglightsec) return; clippass: R_ClipPassWallSegment(x1, x2 - 1); return; clipsolid: R_ClipSolidWallSegment(x1, x2 - 1); }
// killough 1/28/98: static // CPhipps - const parameter, reformatted static dboolean R_CheckBBox(const fixed_t *bspcoord) { angle_t angle1, angle2; int boxpos; const int* check; // Find the corners of the box // that define the edges from current viewpoint. boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT ] ? 1 : 2) + (viewy >= bspcoord[BOXTOP ] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8); if (boxpos == 5) return true; check = checkcoord[boxpos]; #ifdef GL_DOOM if (V_GetMode() == VID_MODEGL) { angle1 = R_PointToAngleEx (bspcoord[check[0]], bspcoord[check[1]]); angle2 = R_PointToAngleEx (bspcoord[check[2]], bspcoord[check[3]]); return gld_clipper_SafeCheckRange(angle2, angle1); } #endif angle1 = R_PointToAngleEx (bspcoord[check[0]], bspcoord[check[1]]) - viewangle; angle2 = R_PointToAngleEx (bspcoord[check[2]], bspcoord[check[3]]) - viewangle; // cph - replaced old code, which was unclear and badly commented // Much more efficient code now if ((signed)angle1 < (signed)angle2) { /* it's "behind" us */ /* Either angle1 or angle2 is behind us, so it doesn't matter if we * change it to the corect sign */ if ((angle1 >= ANG180) && (angle1 < ANG270)) angle1 = INT_MAX; /* which is ANG180-1 */ else angle2 = INT_MIN; } if ((signed)angle2 >= (signed)clipangle) return false; // Both off left edge if ((signed)angle1 <= -(signed)clipangle) return false; // Both off right edge if ((signed)angle1 >= (signed)clipangle) angle1 = clipangle; // Clip at left edge if ((signed)angle2 <= -(signed)clipangle) angle2 = 0-clipangle; // Clip at right edge // Find the first clippost // that touches the source post // (adjacent pixels are touching). angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT; angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT; { int sx1 = viewangletox[angle1]; int sx2 = viewangletox[angle2]; // const cliprange_t *start; // Does not cross a pixel. if (sx1 == sx2) return false; if (!memchr(solidcol+sx1, 0, sx2-sx1)) return false; // All columns it covers are already solidly covered } return true; }