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,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, 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 else
{ {
@ -1494,21 +1505,28 @@ 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 ?
{ {
dc_yl = yl; if (yl >= viewheight) // entirely off bottom of screen
dc_yh = mid; ceilingclip[rw_x] = (INT16)viewheight;
dc_texturemid = rw_toptexturemid; else if (mid >= 0) // safe to draw top texture
dc_source = R_GetColumn(toptexture,texturecolumn); {
dc_texheight = textureheight[toptexture]>>FRACBITS; dc_yl = yl;
colfunc(); dc_yh = mid;
ceilingclip[rw_x] = (INT16)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 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,22 +1538,29 @@ 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 ?
{ {
dc_yl = mid; if (yh < 0) // entirely off top of screen
dc_yh = yh; floorclip[rw_x] = -1;
dc_texturemid = rw_bottomtexturemid; else if (mid < viewheight) // safe to draw bottom texture
dc_source = R_GetColumn(bottomtexture, {
texturecolumn); dc_yl = mid;
dc_texheight = textureheight[bottomtexture]>>FRACBITS; dc_yh = yh;
colfunc(); dc_texturemid = rw_bottomtexturemid;
floorclip[rw_x] = (INT16)mid; 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 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)