diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 93efb8d30..84987a32d 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -439,7 +439,7 @@ static void R_AddLine(seg_t *line) static sector_t tempsec; boolean bothceilingssky = false, bothfloorssky = false; - portalline = false; + g_portal = NULL; if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; diff --git a/src/r_bsp.h b/src/r_bsp.h index 051253a5e..66d1ff9cc 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -14,6 +14,8 @@ #ifndef __R_BSP__ #define __R_BSP__ +#include "typedef.h" + #ifdef __cplusplus extern "C" { #endif @@ -27,7 +29,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? +extern portal_t *g_portal; // is curline a portal seg? // drawsegs are allocated on the fly... see r_segs.c diff --git a/src/r_portal.c b/src/r_portal.c index aa0164eb6..e66d4343c 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -30,7 +30,7 @@ line_t *portalclipline; sector_t *portalcullsector; INT32 portalclipstart, portalclipend; -boolean portalline; // is curline a portal seg? +portal_t *g_portal; // is curline a portal seg? void Portal_InitList (void) { @@ -38,32 +38,6 @@ void Portal_InitList (void) portal_base = portal_cap = NULL; } -/** Store the clipping window for a portal in its given range. - * - * The window is copied from the current window at the time - * the function is called, so it is useful for converting one-sided - * lines into portals. - */ -void Portal_ClipRange (portal_t* portal) -{ - INT32 start = portal->start; - INT32 end = portal->end; - INT16 *ceil = portal->ceilingclip; - INT16 *floor = portal->floorclip; - fixed_t *scale = portal->frontscale; - - INT32 i; - for (i = 0; i < end-start; i++) - { - *ceil = ceilingclip[start+i]; - ceil++; - *floor = floorclip[start+i]; - floor++; - *scale = frontscale[start+i]; - scale++; - } -} - /** Apply the clipping window from a portal. */ void Portal_ClipApply (const portal_t* portal) @@ -187,9 +161,7 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con portal->clipline = line2; - Portal_ClipRange(portal); - - portalline = true; // this tells R_StoreWallRange that curline is a portal seg + g_portal = portal; // this tells R_StoreWallRange that curline is a portal seg } /** Store the clipping window for a portal using a visplane. diff --git a/src/r_portal.h b/src/r_portal.h index 460c8a036..4798030f0 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -60,7 +60,6 @@ void Portal_Remove (portal_t* portal); void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); void Portal_AddSkybox (const player_t* player, const visplane_t* plane); -void Portal_ClipRange (portal_t* portal); void Portal_ClipApply (const portal_t* portal); void Portal_AddSkyboxPortals (const player_t* player); diff --git a/src/r_segs.c b/src/r_segs.c index 44784b087..2b6f471d6 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1526,6 +1526,21 @@ static void R_RenderSegLoop (void) frontscale[rw_x] = rw_scale; + const INT16 topclip = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + const INT16 bottomclip = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + + // Portal line + // Spans the entire height of a single-sided line or + // the "window" of a double-sided line. + if (g_portal) + { + I_Assert(rw_x >= g_portal->start && rw_x < g_portal->end); + i = rw_x - g_portal->start; + g_portal->frontscale[i] = rw_scale; + g_portal->ceilingclip[i] = topclip; + g_portal->floorclip[i] = bottomclip; + } + // draw the wall tiers if (midtexture) { @@ -1567,16 +1582,13 @@ static void R_RenderSegLoop (void) { // note: don't use min/max macros, since casting from INT32 to INT16 is involved here if (markceiling && (!rw_ceilingmarked)) - ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw_x] = topclip; if (markfloor && (!rw_floormarked)) - floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw_x] = bottomclip; } } else { - INT16 topclip = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; - INT16 bottomclip = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; - // two sided line if (toptexture) { @@ -2146,7 +2158,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) || backsector->floorlightsec != frontsector->floorlightsec //SoM: 4/3/2000: Check for colormaps || frontsector->extra_colormap != backsector->extra_colormap - || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) + || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)) + // Portals block traversal behind them + || g_portal) { markfloor = true; } @@ -2179,7 +2193,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) || backsector->ceilinglightsec != frontsector->ceilinglightsec //SoM: 4/3/2000: Check for colormaps || frontsector->extra_colormap != backsector->extra_colormap - || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) + || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)) + // Portals block traversal behind them + || g_portal) { markceiling = true; } @@ -2974,7 +2990,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) R_RenderSegLoop(); R_SetColumnFunc(BASEDRAWFUNC, false); - if (portalline) // if curline is a portal, set portalrender for drawseg + if (g_portal) // if curline is a portal, set portalrender for drawseg ds_p->portalpass = portalrender+1; else ds_p->portalpass = 0;