diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c838e8325..35a01ffd1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2892,15 +2892,57 @@ static void HWR_AddLine(seg_t * line) gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); - // Closed door. - if (gr_backsector->ceilingheight <= gr_frontsector->floorheight || - gr_backsector->floorheight >= gr_frontsector->ceilingheight) - goto clipsolid; +#ifdef ESLOPE + if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope) + { + fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t + fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends + fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends - // Window. - if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight || - gr_backsector->floorheight != gr_frontsector->floorheight) - goto clippass; + v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x); + v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y); + v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x); + v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y); +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, v1x, v1y); \ + end2 = P_GetZAt(slope, v2x, v2y); \ + } else \ + end1 = end2 = normalheight; + + SLOPEPARAMS(gr_frontsector->f_slope, frontf1, frontf2, gr_frontsector->floorheight) + SLOPEPARAMS(gr_frontsector->c_slope, frontc1, frontc2, gr_frontsector->ceilingheight) + SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector->floorheight) + SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight) +#undef SLOPEPARAMS + + // Closed door. + if ((backc1 <= frontf1 && backc2 <= frontf2) + || (backf1 >= frontc1 && backf2 >= frontc2)) + { + goto clipsolid; + } + + // Window. + if (backc1 != frontc1 || backc2 != frontc2 + || backf1 != frontf1 || backf2 != frontf2) + { + goto clippass; + } + } + else +#endif + { + // Closed door. + if (gr_backsector->ceilingheight <= gr_frontsector->floorheight || + gr_backsector->floorheight >= gr_frontsector->ceilingheight) + goto clipsolid; + + // Window. + if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight || + gr_backsector->floorheight != gr_frontsector->floorheight) + goto clippass; + } // Reject empty lines used for triggers and special events. // Identical floor and ceiling on both sides, diff --git a/src/r_main.c b/src/r_main.c index e7c37cce9..97d6876e1 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1324,6 +1324,7 @@ void R_RenderPlayerView(player_t *player) #endif R_RenderBSPNode((INT32)numnodes - 1); + R_ClipSprites(); R_DrawPlanes(); #ifdef FLOORSPLATS R_DrawVisibleFloorSplats(); diff --git a/src/r_segs.c b/src/r_segs.c index 11b4c8aef..ec3eaa180 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1453,34 +1453,45 @@ static void R_RenderSegLoop (void) frontscale[rw_x] = rw_scale; // draw the wall tiers - if (midtexture && yl <= yh && yh < vid.height && yh > 0) + if (midtexture) { // single sided line - dc_yl = yl; - dc_yh = yh; - dc_texturemid = rw_midtexturemid; - dc_source = R_GetColumn(midtexture,texturecolumn); - dc_texheight = textureheight[midtexture]>>FRACBITS; + if (yl <= yh && yh >= 0 && yl < viewheight) + { + dc_yl = yl; + dc_yh = yh; + dc_texturemid = rw_midtexturemid; + dc_source = R_GetColumn(midtexture,texturecolumn); + dc_texheight = textureheight[midtexture]>>FRACBITS; - //profile stuff --------------------------------------------------------- + //profile stuff --------------------------------------------------------- #ifdef TIMING - ProfZeroTimer(); + ProfZeroTimer(); #endif - colfunc(); + colfunc(); #ifdef TIMING - RDMSR(0x10,&mycount); - mytotal += mycount; //64bit add + RDMSR(0x10,&mycount); + mytotal += mycount; //64bit add - if (nombre--==0) - I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1), - (INT32)mytotal); + if (nombre--==0) + I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1), + (INT32)mytotal); #endif - //profile stuff --------------------------------------------------------- + //profile stuff --------------------------------------------------------- - // dont draw anything more for this column, since - // a midtexture blocks the view - ceilingclip[rw_x] = (INT16)viewheight; - floorclip[rw_x] = -1; + // dont draw anything more for this column, since + // a midtexture blocks the view + ceilingclip[rw_x] = (INT16)viewheight; + floorclip[rw_x] = -1; + } + else + { + // note: don't use min/max macros, since casting from INT32 to INT16 is involved here + if (markceiling) + ceilingclip[rw_x] = (yh >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + if (markfloor) + floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + } } else { @@ -1494,21 +1505,28 @@ static void R_RenderSegLoop (void) if (mid >= floorclip[rw_x]) mid = floorclip[rw_x]-1; - if (mid >= yl && yh < vid.height && yh > 0) + if (mid >= yl) // back ceiling lower than front ceiling ? { - dc_yl = yl; - dc_yh = mid; - dc_texturemid = rw_toptexturemid; - dc_source = R_GetColumn(toptexture,texturecolumn); - dc_texheight = textureheight[toptexture]>>FRACBITS; - colfunc(); - ceilingclip[rw_x] = (INT16)mid; + if (yl >= viewheight) // entirely off bottom of screen + ceilingclip[rw_x] = (INT16)viewheight; + else if (mid >= 0) // safe to draw top texture + { + dc_yl = yl; + dc_yh = mid; + dc_texturemid = rw_toptexturemid; + dc_source = R_GetColumn(toptexture,texturecolumn); + dc_texheight = textureheight[toptexture]>>FRACBITS; + colfunc(); + ceilingclip[rw_x] = (INT16)mid; + } + else // entirely off top of screen + ceilingclip[rw_x] = -1; } else - ceilingclip[rw_x] = (INT16)((INT16)yl - 1); + ceilingclip[rw_x] = (yh >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; } else if (markceiling) // no top wall - ceilingclip[rw_x] = (INT16)((INT16)yl - 1); + ceilingclip[rw_x] = (yh >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; if (bottomtexture) { @@ -1520,22 +1538,29 @@ static void R_RenderSegLoop (void) if (mid <= ceilingclip[rw_x]) mid = ceilingclip[rw_x]+1; - if (mid <= yh && yh < vid.height && yh > 0) + if (mid <= yh) // back floor higher than front floor ? { - dc_yl = mid; - dc_yh = yh; - dc_texturemid = rw_bottomtexturemid; - dc_source = R_GetColumn(bottomtexture, - texturecolumn); - dc_texheight = textureheight[bottomtexture]>>FRACBITS; - colfunc(); - floorclip[rw_x] = (INT16)mid; + if (yh < 0) // entirely off top of screen + floorclip[rw_x] = -1; + else if (mid < viewheight) // safe to draw bottom texture + { + dc_yl = mid; + dc_yh = yh; + dc_texturemid = rw_bottomtexturemid; + dc_source = R_GetColumn(bottomtexture, + texturecolumn); + dc_texheight = textureheight[bottomtexture]>>FRACBITS; + colfunc(); + floorclip[rw_x] = (INT16)mid; + } + else // entirely off bottom of screen + floorclip[rw_x] = (INT16)viewheight; } else - floorclip[rw_x] = (INT16)((INT16)yh + 1); + floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } else if (markfloor) // no bottom wall - floorclip[rw_x] = (INT16)((INT16)yh + 1); + floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } if (maskedtexture || numthicksides)