Fixed div-by-zero crash relating to portals, drawsegs and midtextures

Had to remove Red's scale hack in order to do so, because it utterly fails when the drawseg doesn't actually belong to the portal in the first place.
This commit is contained in:
Monster Iestyn 2016-02-06 18:57:26 +00:00
parent 9973bedd5f
commit 166fafd717
6 changed files with 15 additions and 11 deletions

View File

@ -26,6 +26,7 @@ side_t *sidedef;
line_t *linedef;
sector_t *frontsector;
sector_t *backsector;
boolean portalline; // is curline a portal seg?
// very ugly realloc() of drawsegs at run-time, I upped it to 512
// instead of 256.. and someone managed to send me a level with
@ -378,6 +379,7 @@ static void R_AddLine(seg_t *line)
return;
curline = line;
portalline = false;
// OPTIMIZE: quickly reject orthogonal back sides.
angle1 = R_PointToAngle(line->v1->x, line->v1->y);
@ -431,7 +433,7 @@ static void R_AddLine(seg_t *line)
backsector = line->backsector;
// Portal line
if (line->linedef->special == 40 && P_PointOnLineSide(viewx, viewy, line->linedef) == 0)
if (line->linedef->special == 40 && line->side == 0)
{
if (portalrender < cv_maxportals.value)
{

View File

@ -23,6 +23,7 @@ extern side_t *sidedef;
extern line_t *linedef;
extern sector_t *frontsector;
extern sector_t *backsector;
extern boolean portalline; // is curline a portal seg?
// drawsegs are allocated on the fly... see r_segs.c

View File

@ -675,6 +675,8 @@ typedef struct drawseg_s
INT32 numthicksides;
fixed_t frontscale[MAXVIDWIDTH];
UINT8 portalpass; // if > 0 and == portalrender, do not clip sprites
#ifdef ESLOPE
fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures

View File

@ -91,7 +91,6 @@ typedef struct portal_pair
INT16 *ceilingclip;
INT16 *floorclip;
fixed_t *frontscale;
size_t seg;
} portal_pair;
portal_pair *portal_base, *portal_cap;
line_t *portalclipline;
@ -1230,7 +1229,7 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
portal->start = x1;
portal->end = x2;
portal->seg = ds_p-drawsegs;
portalline = true; // this tells R_StoreWallRange that curline is a portal seg
portal->viewx = viewx;
portal->viewy = viewy;
@ -1344,14 +1343,6 @@ void R_RenderPlayerView(player_t *player)
validcount++;
if (portal->seg)
{
// Push the portal's old drawseg out of the way so it isn't interfering with sprite clipping. -Red
drawseg_t *seg = drawsegs+portal->seg;
seg->scale1 = 0;
seg->scale2 = 0;
}
R_RenderBSPNode((INT32)numnodes - 1);
R_ClipSprites();
//R_DrawPlanes();

View File

@ -2887,6 +2887,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
R_RenderSegLoop();
colfunc = wallcolfunc;
if (portalline) // if curline is a portal, set portalrender for drawseg
ds_p->portalpass = portalrender+1;
else
ds_p->portalpass = 0;
// save sprite clipping info
if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
{

View File

@ -2058,6 +2058,9 @@ void R_ClipSprites(void)
continue;
}
if (ds->portalpass > 0 && ds->portalpass == portalrender)
continue; // is a portal
r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;