From 9973bedd5f3711773b5b5f2e276e400893398b99 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 5 Feb 2016 16:38:33 +0000 Subject: [PATCH 1/4] Free the memory of all clipping arrays for each portal properly Not the actual fix I'm intending to make with this branch, but it's needed anyway --- src/r_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/r_main.c b/src/r_main.c index a4e72cba9..ccaa14b8e 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1360,6 +1360,9 @@ void R_RenderPlayerView(player_t *player) // okay done. free it. portalcullsector = NULL; // Just in case... portal_base = portal->next; + Z_Free(portal->ceilingclip); + Z_Free(portal->floorclip); + Z_Free(portal->frontscale); Z_Free(portal); } // END PORTAL RENDERING From 166fafd71708553539c753783b924496387ba4d0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 6 Feb 2016 18:57:26 +0000 Subject: [PATCH 2/4] 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. --- src/r_bsp.c | 4 +++- src/r_bsp.h | 1 + src/r_defs.h | 2 ++ src/r_main.c | 11 +---------- src/r_segs.c | 5 +++++ src/r_things.c | 3 +++ 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index c87d8baa7..52be9a0e3 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -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) { diff --git a/src/r_bsp.h b/src/r_bsp.h index 14b11ea77..3d0429fec 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -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 diff --git a/src/r_defs.h b/src/r_defs.h index f18410fe8..a982a598b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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 diff --git a/src/r_main.c b/src/r_main.c index ccaa14b8e..a6b13302e 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -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(); diff --git a/src/r_segs.c b/src/r_segs.c index 04873b29c..0106a1bac 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -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) { diff --git a/src/r_things.c b/src/r_things.c index 2a3f8e771..667a26e0f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -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; From ae2b1e8ea1ba860107d036e316011f0427ec329d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 6 Feb 2016 21:06:52 +0000 Subject: [PATCH 3/4] Use <= instead of ==, so that sprites for second-tier portals and beyond still display thx Red for spotting this --- src/r_defs.h | 2 +- src/r_things.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index a982a598b..107b8a83f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -675,7 +675,7 @@ typedef struct drawseg_s INT32 numthicksides; fixed_t frontscale[MAXVIDWIDTH]; - UINT8 portalpass; // if > 0 and == portalrender, do not clip sprites + UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping #ifdef ESLOPE fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures diff --git a/src/r_things.c b/src/r_things.c index 667a26e0f..3767b02be 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2058,7 +2058,7 @@ void R_ClipSprites(void) continue; } - if (ds->portalpass > 0 && ds->portalpass == portalrender) + if (ds->portalpass > 0 && ds->portalpass <= portalrender) continue; // is a portal r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; From dabc4415af553ec8a1bc14e381635e7d9879d279 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 13 Feb 2016 18:11:50 +0000 Subject: [PATCH 4/4] Fix crash caused by drawing scaled, mirrored sprites semi-covered on the left side by portal edge I suspect this crash was possible even outside the context of portals, but whatever --- src/r_things.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 3767b02be..87879a415 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -839,10 +839,10 @@ static void R_DrawVisSprite(vissprite_t *vis) dc_texturemid = FixedDiv(dc_texturemid,this_scale); //Oh lordy, mercy me. Don't freak out if sprites go offscreen! - if (vis->xiscale > 0) + /*if (vis->xiscale > 0) frac = FixedDiv(frac, this_scale); else if (vis->x1 <= 0) - frac = (vis->x1 - vis->x2) * vis->xiscale; + frac = (vis->x1 - vis->x2) * vis->xiscale;*/ sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); //dc_hires = 1; @@ -1306,7 +1306,7 @@ static void R_ProjectSprite(mobj_t *thing) } if (vis->x1 > x1) - vis->startfrac += vis->xiscale*(vis->x1-x1); + vis->startfrac += FixedDiv(vis->xiscale, this_scale)*(vis->x1-x1); //Fab: lumppat is the lump number of the patch to use, this is different // than lumpid for sprites-in-pwad : the graphics are patched