// // R_AddLine // Clips the given segment and adds any visible pieces to the line list. // static void R_AddLine(seg_t *line) { INT32 x1, x2; angle_t angle1, angle2, span, tspan; static sector_t tempsec; // ceiling/water hack if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; curline = line; // OPTIMIZE: quickly reject orthogonal back sides. angle1 = R_PointToAngle(line->v1->x, line->v1->y); angle2 = R_PointToAngle(line->v2->x, line->v2->y); // Clip to view edges. span = angle1 - angle2; // Back side? i.e. backface culling? if (span >= ANGLE_180) return; // Global angle needed by segcalc. rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; tspan = angle1 + clipangle; if (tspan > doubleclipangle) { tspan -= doubleclipangle; // Totally off the left edge? if (tspan >= span) return; angle1 = clipangle; } tspan = clipangle - angle2; if (tspan > doubleclipangle) { tspan -= doubleclipangle; // Totally off the left edge? if (tspan >= span) return; angle2 = -(signed)clipangle; } // The seg is in the view range, but not necessarily visible. angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT; angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT; x1 = viewangletox[angle1]; x2 = viewangletox[angle2]; // Does not cross a pixel? if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness return; backsector = line->backsector; // Portal line if (line->linedef->special == 40 && P_PointOnLineSide(viewx, viewy, line->linedef) == 0) { if (portalrender < cv_maxportals.value) { // Find the other side! INT32 line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, -1); if (line->linedef == &lines[line2]) line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2); if (line2 >= 0) // found it! { R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering //return; // Don't fill in that space now! goto clipsolid; } } // Recursed TOO FAR (viewing a portal within a portal) // So uhhh, render it as a normal wall instead or something ??? } // Single sided line? if (!backsector) goto clipsolid; backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); doorclosed = 0; // Closed door. #ifdef ESLOPE // Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than // random renderer stopping around slopes... if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) #endif if (backsector->ceilingheight <= frontsector->floorheight || backsector->floorheight >= frontsector->ceilingheight) { goto clipsolid; } // Check for automap fix. Store in doorclosed for r_segs.c doorclosed = R_DoorClosed(); if (doorclosed) goto clipsolid; // Window. if (backsector->ceilingheight != frontsector->ceilingheight || backsector->floorheight != frontsector->floorheight) { 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 ( #ifdef POLYOBJECTS !line->polyseg && #endif backsector->ceilingpic == frontsector->ceilingpic && backsector->floorpic == frontsector->floorpic #ifdef ESLOPE && backsector->f_slope == frontsector->f_slope && backsector->c_slope == frontsector->c_slope #endif && backsector->lightlevel == frontsector->lightlevel && !curline->sidedef->midtexture // Check offsets too! && backsector->floor_xoffs == frontsector->floor_xoffs && backsector->floor_yoffs == frontsector->floor_yoffs && backsector->floorpic_angle == frontsector->floorpic_angle && backsector->ceiling_xoffs == frontsector->ceiling_xoffs && backsector->ceiling_yoffs == frontsector->ceiling_yoffs && backsector->ceilingpic_angle == frontsector->ceilingpic_angle // Consider altered lighting. && backsector->floorlightsec == frontsector->floorlightsec && backsector->ceilinglightsec == frontsector->ceilinglightsec // Consider colormaps && backsector->extra_colormap == frontsector->extra_colormap && ((!frontsector->ffloors && !backsector->ffloors) || frontsector->tag == backsector->tag)) { return; } clippass: R_ClipPassWallSegment(x1, x2 - 1); return; clipsolid: R_ClipSolidWallSegment(x1, x2 - 1); }
// // R_AddLine // Clips the given segment and adds any visible pieces to the line list. // static void R_AddLine(seg_t *line) { INT32 x1, x2; angle_t angle1, angle2, span, tspan; static sector_t tempsec; // ceiling/water hack if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; curline = line; portalline = false; // OPTIMIZE: quickly reject orthogonal back sides. angle1 = R_PointToAngle(line->v1->x, line->v1->y); angle2 = R_PointToAngle(line->v2->x, line->v2->y); // Clip to view edges. span = angle1 - angle2; // Back side? i.e. backface culling? if (span >= ANGLE_180) return; // Global angle needed by segcalc. rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; tspan = angle1 + clipangle; if (tspan > doubleclipangle) { tspan -= doubleclipangle; // Totally off the left edge? if (tspan >= span) return; angle1 = clipangle; } tspan = clipangle - angle2; if (tspan > doubleclipangle) { tspan -= doubleclipangle; // Totally off the left edge? if (tspan >= span) return; angle2 = -(signed)clipangle; } // The seg is in the view range, but not necessarily visible. angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT; angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT; x1 = viewangletox[angle1]; x2 = viewangletox[angle2]; // Does not cross a pixel? if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness return; backsector = line->backsector; // Portal line if (line->linedef->special == 40 && line->side == 0) { if (portalrender < cv_maxportals.value) { // Find the other side! INT32 line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, -1); if (line->linedef == &lines[line2]) line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2); if (line2 >= 0) // found it! { R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering //return; // Don't fill in that space now! goto clipsolid; } } // Recursed TOO FAR (viewing a portal within a portal) // So uhhh, render it as a normal wall instead or something ??? } // Single sided line? if (!backsector) goto clipsolid; backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); doorclosed = 0; // Closed door. #ifdef ESLOPE if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope) { fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends #define SLOPEPARAMS(slope, end1, end2, normalheight) \ if (slope) { \ end1 = P_GetZAt(slope, line->v1->x, line->v1->y); \ end2 = P_GetZAt(slope, line->v2->x, line->v2->y); \ } else \ end1 = end2 = normalheight; SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector->floorheight) SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight) SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector->floorheight) SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) #undef SLOPEPARAMS if ((backc1 <= frontf1 && backc2 <= frontf2) || (backf1 >= frontc1 && backf2 >= frontc2)) { goto clipsolid; } // Check for automap fix. Store in doorclosed for r_segs.c doorclosed = (backc1 <= backf1 && backc2 <= backf2 && ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture) && ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture) && (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum)); if (doorclosed) goto clipsolid; // Window. if (backc1 != frontc1 || backc2 != frontc2 || backf1 != frontf1 || backf2 != frontf2) { goto clippass; } }