Significant rework of main seg-rendering code, to eliminate the possibility of drawing off-screen and crashing the game as result

NOTE: HOMs sometimes appear in the sky in maps like AGZ (map40), so this isn't completely fine yet. I'll fix that later
This commit is contained in:
Monster Iestyn 2016-05-30 21:53:29 +01:00
parent d1aab2e418
commit a2aeece419

View file

@ -1453,34 +1453,45 @@ static void R_RenderSegLoop (void)
frontscale[rw_x] = rw_scale; frontscale[rw_x] = rw_scale;
// draw the wall tiers // draw the wall tiers
if (midtexture && yl <= yh && yh < vid.height && yh > 0) if (midtexture)
{ {
// single sided line // single sided line
dc_yl = yl; if (yl <= yh && yh >= 0 && yl < viewheight)
dc_yh = yh; {
dc_texturemid = rw_midtexturemid; dc_yl = yl;
dc_source = R_GetColumn(midtexture,texturecolumn); dc_yh = yh;
dc_texheight = textureheight[midtexture]>>FRACBITS; dc_texturemid = rw_midtexturemid;
dc_source = R_GetColumn(midtexture,texturecolumn);
dc_texheight = textureheight[midtexture]>>FRACBITS;
//profile stuff --------------------------------------------------------- //profile stuff ---------------------------------------------------------
#ifdef TIMING #ifdef TIMING
ProfZeroTimer(); ProfZeroTimer();
#endif #endif
colfunc(); colfunc();
#ifdef TIMING #ifdef TIMING
RDMSR(0x10,&mycount); RDMSR(0x10,&mycount);
mytotal += mycount; //64bit add mytotal += mycount; //64bit add
if (nombre--==0) if (nombre--==0)
I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1), I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1),
(INT32)mytotal); (INT32)mytotal);
#endif #endif
//profile stuff --------------------------------------------------------- //profile stuff ---------------------------------------------------------
// dont draw anything more for this column, since // dont draw anything more for this column, since
// a midtexture blocks the view // a midtexture blocks the view
ceilingclip[rw_x] = (INT16)viewheight; ceilingclip[rw_x] = (INT16)viewheight;
floorclip[rw_x] = -1; floorclip[rw_x] = -1;
}
else
{
// note: don't use min/max macros here
if (markceiling && yl >= 0)
ceilingclip[rw_x] = (yl-1 > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1);
if (markfloor && yh < viewheight)
floorclip[rw_x] = (yh < -1) ? -1 : (INT16)((INT16)yh + 1);
}
} }
else else
{ {
@ -1494,21 +1505,27 @@ static void R_RenderSegLoop (void)
if (mid >= floorclip[rw_x]) if (mid >= floorclip[rw_x])
mid = floorclip[rw_x]-1; mid = floorclip[rw_x]-1;
if (mid >= yl && yh < vid.height && yh > 0) if (yl < 0)
; // do nothing, off-screen
else if (mid >= yl && yl < viewheight)
{ {
dc_yl = yl; if (mid >= 0)
dc_yh = mid; {
dc_texturemid = rw_toptexturemid; dc_yl = yl;
dc_source = R_GetColumn(toptexture,texturecolumn); dc_yh = mid;
dc_texheight = textureheight[toptexture]>>FRACBITS; dc_texturemid = rw_toptexturemid;
colfunc(); dc_source = R_GetColumn(toptexture,texturecolumn);
ceilingclip[rw_x] = (INT16)mid; dc_texheight = textureheight[toptexture]>>FRACBITS;
colfunc();
ceilingclip[rw_x] = (INT16)mid;
}
// else do nothing, off-screen
} }
else else
ceilingclip[rw_x] = (INT16)((INT16)yl - 1); ceilingclip[rw_x] = (yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1);
} }
else if (markceiling) // no top wall else if (markceiling && yl >= 0) // no top wall
ceilingclip[rw_x] = (INT16)((INT16)yl - 1); ceilingclip[rw_x] = (yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1);
if (bottomtexture) if (bottomtexture)
{ {
@ -1520,24 +1537,33 @@ static void R_RenderSegLoop (void)
if (mid <= ceilingclip[rw_x]) if (mid <= ceilingclip[rw_x])
mid = ceilingclip[rw_x]+1; mid = ceilingclip[rw_x]+1;
if (mid <= yh && yh < vid.height && yh > 0) if (yh >= viewheight)
; // do nothing, off-screen
else if (mid <= yh && yh >= 0)
{ {
dc_yl = mid; if (mid < viewheight)
dc_yh = yh; {
dc_texturemid = rw_bottomtexturemid; dc_yl = mid;
dc_source = R_GetColumn(bottomtexture, dc_yh = yh;
texturecolumn); dc_texturemid = rw_bottomtexturemid;
dc_texheight = textureheight[bottomtexture]>>FRACBITS; dc_source = R_GetColumn(bottomtexture,
colfunc(); texturecolumn);
floorclip[rw_x] = (INT16)mid; dc_texheight = textureheight[bottomtexture]>>FRACBITS;
colfunc();
floorclip[rw_x] = (INT16)mid;
}
// else do nothing, off-screen
} }
else else
floorclip[rw_x] = (INT16)((INT16)yh + 1); floorclip[rw_x] = (yh < -1) ? -1 : (INT16)((INT16)yh + 1);
} }
else if (markfloor) // no bottom wall else if (markfloor && yh < viewheight) // no bottom wall
floorclip[rw_x] = (INT16)((INT16)yh + 1); floorclip[rw_x] = (yh < -1) ? -1 : (INT16)((INT16)yh + 1), -1;
} }
if (floorclip[rw_x] > viewheight)
I_Error("floorclip[%d] > viewheight (value is %d)", rw_x, floorclip[rw_x]);
if (maskedtexture || numthicksides) if (maskedtexture || numthicksides)
{ {
// save texturecol // save texturecol