Merge branch 'software-fixes' into 'master'

Software crashes fix

This branch SHOULD fix the many crashes people have reported lately that all point to the software renderer. Simply put, the software renderer allowed stuff to be drawn out of the screen even though that wasn't safe, and even the existing checks to prevent that didn't work.

If you saw me worrying about the sky HOMs I discovered in AGZ earlier in the commits for this branch, don't worry - it turns out that issue already existed in 2.1.15's srb2win.exe (and probably srb2dd.exe too) anyway, the changes in this branch didn't cause them. Hopefully nothing else broke then.

See merge request !75
This commit is contained in:
Monster Iestyn 2016-06-12 14:33:27 -04:00
commit b4798538e2

View file

@ -1453,9 +1453,11 @@ 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
if (yl <= yh && yh >= 0 && yl < viewheight)
{
dc_yl = yl; dc_yl = yl;
dc_yh = yh; dc_yh = yh;
dc_texturemid = rw_midtexturemid; dc_texturemid = rw_midtexturemid;
@ -1483,6 +1485,15 @@ static void R_RenderSegLoop (void)
floorclip[rw_x] = -1; floorclip[rw_x] = -1;
} }
else 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
{ {
// two sided line // two sided line
if (toptexture) if (toptexture)
@ -1494,7 +1505,11 @@ 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 (mid >= yl) // back ceiling lower than front ceiling ?
{
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_yl = yl;
dc_yh = mid; dc_yh = mid;
@ -1504,11 +1519,14 @@ static void R_RenderSegLoop (void)
colfunc(); colfunc();
ceilingclip[rw_x] = (INT16)mid; ceilingclip[rw_x] = (INT16)mid;
} }
else // entirely off top of screen
ceilingclip[rw_x] = -1;
}
else 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 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) if (bottomtexture)
{ {
@ -1520,7 +1538,11 @@ 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 (mid <= yh) // back floor higher than front floor ?
{
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_yl = mid;
dc_yh = yh; dc_yh = yh;
@ -1531,11 +1553,14 @@ static void R_RenderSegLoop (void)
colfunc(); colfunc();
floorclip[rw_x] = (INT16)mid; floorclip[rw_x] = (INT16)mid;
} }
else // entirely off bottom of screen
floorclip[rw_x] = (INT16)viewheight;
}
else 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 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) if (maskedtexture || numthicksides)