diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index bc66955fc..2340b9e8b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1117,8 +1117,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom INT32 gl_toptexture = 0, gl_bottomtexture = 0; fixed_t texturevpeg; - boolean bothceilingssky = false; // turned on if both back and front ceilings are sky - boolean bothfloorssky = false; // likewise, but for floors + bothceilingssky = bothfloorssky = false; SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight) SLOPEPARAMS(gl_backsector->f_slope, worldlow, worldlowslope, gl_backsector->floorheight) @@ -1854,12 +1853,6 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks { fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends - boolean bothceilingssky = false, bothfloorssky = false; - - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - bothceilingssky = true; - if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) - bothfloorssky = true; // GZDoom method of sloped line clipping @@ -2354,13 +2347,16 @@ static void HWR_AddLine(seg_t * line) } else { - boolean bothceilingssky = false, bothfloorssky = false; + bothceilingssky = bothfloorssky = false; gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true); - if (gl_backsector->ceilingpic == skyflatnum && gl_frontsector->ceilingpic == skyflatnum) + if (gl_backsector->ceilingpic == skyflatnum && gl_frontsector->ceilingpic == skyflatnum + && !(gl_backsector->portal_ceiling.exists || gl_frontsector->portal_ceiling.exists)) bothceilingssky = true; - if (gl_backsector->floorpic == skyflatnum && gl_frontsector->floorpic == skyflatnum) + + if (gl_backsector->floorpic == skyflatnum && gl_frontsector->floorpic == skyflatnum + && !(gl_backsector->portal_floor.exists || gl_frontsector->portal_floor.exists)) bothfloorssky = true; if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then diff --git a/src/p_setup.c b/src/p_setup.c index c590bba4f..b9c2b5939 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -980,9 +980,9 @@ static void P_LoadVertices(UINT8 *data) static void InitializeSectorPortal(sectorportal_t *secportal) { - secportal->target = NULL; - secportal->viewpoint.x = secportal->viewpoint.y = secportal->viewpoint.z = 0; - secportal->viewpoint.angle = 0; + secportal->exists = false; + secportal->target.x = secportal->target.y = secportal->target.z = 0; + secportal->target.angle = 0; } static void P_InitializeSector(sector_t *ss) @@ -998,8 +998,8 @@ static void P_InitializeSector(sector_t *ss) ss->lightingdata = NULL; ss->fadecolormapdata = NULL; - InitializeSectorPortal(&ss->portal_plane_floor); - InitializeSectorPortal(&ss->portal_plane_ceiling); + InitializeSectorPortal(&ss->portal_floor); + InitializeSectorPortal(&ss->portal_ceiling); ss->heightsec = -1; ss->camsec = -1; diff --git a/src/p_spec.c b/src/p_spec.c index 5dc99ee5b..57653416a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6186,13 +6186,18 @@ fixed_t P_GetSectorGravityFactor(sector_t *sec) return sec->gravity; } +boolean P_CompareSectorPortals(sectorportal_t *a, sectorportal_t *b) +{ + return !memcmp(a, b, sizeof(sectorportal_t)); +} + static void SetSectorPortal(sectorportal_t *secportal, sector_t *target_sector, fixed_t default_z, INT32 viewpoint_tag) { - secportal->target = target_sector; - secportal->viewpoint.x = target_sector->soundorg.x; - secportal->viewpoint.y = target_sector->soundorg.y; - secportal->viewpoint.z = default_z; - secportal->viewpoint.angle = 0; + secportal->exists = target_sector; + secportal->target.x = target_sector->soundorg.x; + secportal->target.y = target_sector->soundorg.y; + secportal->target.z = default_z; + secportal->target.angle = 0; if (viewpoint_tag <= 0) return; @@ -6210,10 +6215,10 @@ static void SetSectorPortal(sectorportal_t *secportal, sector_t *target_sector, if (!Tag_Find(&mo->spawnpoint->tags, viewpoint_tag)) continue; - secportal->viewpoint.x = mo->x; - secportal->viewpoint.y = mo->y; - secportal->viewpoint.z = mo->z; - secportal->viewpoint.angle = mo->angle; + secportal->target.x = mo->x; + secportal->target.y = mo->y; + secportal->target.z = mo->z; + secportal->target.angle = mo->angle; return; } } @@ -6402,9 +6407,9 @@ void P_SpawnSpecials(boolean fromnetsave) } if (floor) - SetSectorPortal(§ors[s1].portal_plane_floor, target_sector, target_sector->ceilingheight, lines[i].args[3]); + SetSectorPortal(§ors[s1].portal_floor, target_sector, target_sector->ceilingheight, lines[i].args[3]); if (ceiling) - SetSectorPortal(§ors[s1].portal_plane_ceiling, target_sector, target_sector->floorheight, lines[i].args[3]); + SetSectorPortal(§ors[s1].portal_ceiling, target_sector, target_sector->floorheight, lines[i].args[3]); } } break; diff --git a/src/p_spec.h b/src/p_spec.h index 50ab6410f..71c9dcf3a 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -521,6 +521,8 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max); void P_SetupSignExit(player_t *player); boolean P_IsFlagAtBase(mobjtype_t flag); +boolean P_CompareSectorPortals(sectorportal_t *a, sectorportal_t *b); + boolean P_IsMobjTouchingSectorPlane(mobj_t *mo, sector_t *sec); boolean P_IsMobjTouching3DFloor(mobj_t *mo, ffloor_t *ffloor, sector_t *sec); boolean P_IsMobjTouchingPolyobj(mobj_t *mo, polyobj_t *po, sector_t *polysec); diff --git a/src/r_bsp.c b/src/r_bsp.c index 5c9aa3ff9..70f08e127 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -36,6 +36,9 @@ drawseg_t *curdrawsegs = NULL; /**< This is used to handle multiple lists for ma drawseg_t *drawsegs = NULL; drawseg_t *ds_p = NULL; +boolean bothceilingssky = false; // turned on if both back and front ceilings are sky +boolean bothfloorssky = false; // likewise, but for floors + // indicates doors closed wrt automap bugfix: INT32 doorclosed; @@ -391,7 +394,6 @@ static void R_AddLine(seg_t *line) INT32 x1, x2; angle_t angle1, angle2, span, tspan; static sector_t tempsec; - boolean bothceilingssky = false, bothfloorssky = false; portalline = false; @@ -481,10 +483,17 @@ static void R_AddLine(seg_t *line) backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); doorclosed = 0; + bothceilingssky = bothfloorssky = false; - if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum) + // hack to allow height changes in outdoor areas + // This is what gets rid of the upper textures if there should be sky + if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum + && !(backsector->portal_ceiling.exists || frontsector->portal_ceiling.exists)) bothceilingssky = true; - if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum) + + // likewise, but for floors and upper textures + if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum + && !(backsector->portal_floor.exists || frontsector->portal_floor.exists)) bothfloorssky = true; if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then @@ -909,7 +918,7 @@ static void R_Subsector(size_t num) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) { floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope, frontsector->portal_plane_floor.target != NULL ? &frontsector->portal_plane_floor : NULL); + frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope, frontsector->portal_floor.exists ? &frontsector->portal_floor : NULL); } else floorplane = NULL; @@ -920,7 +929,7 @@ static void R_Subsector(size_t num) { ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingangle, - ceilingcolormap, NULL, NULL, frontsector->c_slope, frontsector->portal_plane_ceiling.target != NULL ? &frontsector->portal_plane_ceiling : NULL); + ceilingcolormap, NULL, NULL, frontsector->c_slope, frontsector->portal_ceiling.exists ? &frontsector->portal_ceiling : NULL); } else ceilingplane = NULL; diff --git a/src/r_bsp.h b/src/r_bsp.h index 55199405a..f36f7e64d 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -25,13 +25,15 @@ 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 - extern INT32 checkcoord[12][4]; extern drawseg_t *curdrawsegs; extern drawseg_t *drawsegs; extern drawseg_t *ds_p; + +extern boolean bothceilingssky; +extern boolean bothfloorssky; + extern INT32 doorclosed; // BSP? diff --git a/src/r_defs.h b/src/r_defs.h index d9fe6193d..d435f69ab 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -210,11 +210,11 @@ typedef enum typedef struct sectorportal_s { - struct sector_s *target; + boolean exists; struct { fixed_t x, y, z; angle_t angle; - } viewpoint; + } target; } sectorportal_t; typedef struct ffloor_s @@ -505,8 +505,8 @@ typedef struct sector_s extracolormap_t *spawn_extra_colormap; // portals - sectorportal_t portal_plane_floor; - sectorportal_t portal_plane_ceiling; + sectorportal_t portal_floor; + sectorportal_t portal_ceiling; } sector_t; // diff --git a/src/r_plane.c b/src/r_plane.c index 5cd791023..d9051ae05 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -441,8 +441,6 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li hash = visplane_hash(picnum, lightlevel, height); for (check = visplanes[hash]; check; check = check->next) { - if (polyobj != check->polyobj) - continue; if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel && xoff == check->xoffs && yoff == check->yoffs @@ -452,6 +450,7 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li && check->viewangle == viewangle && check->plangle == plangle && check->slope == slope + && check->polyobj == polyobj && check->portalsector == portalsector) { return check; diff --git a/src/r_portal.c b/src/r_portal.c index b4328a56e..136eb4fac 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -22,7 +22,6 @@ #include "r_sky.h" UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */ -UINT8 floorportalrender; /**< Same deal, but for floorportals. */ // Linked list for portals. portal_t *portal_base, *portal_cap; @@ -36,7 +35,6 @@ boolean portalline; // is curline a portal seg? void Portal_InitList (void) { portalrender = 0; - floorportalrender = 0; portal_base = portal_cap = NULL; } @@ -317,7 +315,7 @@ void Portal_AddSectorPortal (const visplane_t* plane) { INT16 start, end; sector_t *source = plane->sector; - sectorportal_t *target = plane->portalsector; + sectorportal_t *secportal = plane->portalsector; if (TrimVisplaneBounds(plane, &start, &end)) return; @@ -329,18 +327,19 @@ void Portal_AddSectorPortal (const visplane_t* plane) fixed_t refx = source->soundorg.x - viewx; fixed_t refy = source->soundorg.y - viewy; - if (target->viewpoint.angle) + // Rotate the X/Y to match the target angle + if (secportal->target.angle) { fixed_t x = refx, y = refy; - angle_t ang = target->viewpoint.angle >> ANGLETOFINESHIFT; + angle_t ang = secportal->target.angle >> ANGLETOFINESHIFT; refx = FixedMul(x, FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); refy = FixedMul(x, FINESINE(ang)) + FixedMul(y, FINECOSINE(ang)); } - portal->viewx = target->viewpoint.x - refx; - portal->viewy = target->viewpoint.y - refy; - portal->viewz = target->viewpoint.z + viewz; - portal->viewangle = target->viewpoint.angle + viewangle; + portal->viewx = secportal->target.x - refx; + portal->viewy = secportal->target.y - refy; + portal->viewz = secportal->target.z + viewz; + portal->viewangle = secportal->target.angle + viewangle; portal->clipline = -1; } @@ -358,21 +357,17 @@ void Portal_AddSkyboxPortals (void) { boolean added_portal = false; - // skybox portal - if (pl->picnum == skyflatnum) - { - if (cv_skybox.value && skyboxmo[0]) - { - Portal_AddSkybox(pl); - added_portal = true; - } - } - - // floor portal - if (pl->portalsector && pl->portalsector->target && floorportalrender < cv_maxportals.value) + // Render sector portal if recursiveness limit hasn't been reached + if (pl->portalsector && portalrender < cv_maxportals.value) { Portal_AddSectorPortal(pl); - floorportalrender++; + added_portal = true; + } + + // Render skybox portal + if (!added_portal && pl->picnum == skyflatnum && cv_skybox.value && skyboxmo[0]) + { + Portal_AddSkybox(pl); added_portal = true; } diff --git a/src/r_portal.h b/src/r_portal.h index 6e2a6dedb..1e4bbfb12 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -44,7 +44,6 @@ typedef struct portal_s extern portal_t* portal_base; extern portal_t* portal_cap; extern UINT8 portalrender; -extern UINT8 floorportalrender; extern line_t *portalclipline; extern sector_t *portalcullsector; diff --git a/src/r_segs.c b/src/r_segs.c index 9af83f0c7..a8fb635d1 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1787,8 +1787,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) else { // two sided line - boolean bothceilingssky = false; // turned on if both back and front ceilings are sky - boolean bothfloorssky = false; // likewise, but for floors + bothceilingssky = bothfloorssky = false; SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight) SLOPEPARAMS(backsector->f_slope, worldlow, worldlowslope, backsector->floorheight) @@ -1797,21 +1796,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldlow -= viewz; worldlowslope -= viewz; - // hack to allow height changes in outdoor areas - // This is what gets rid of the upper textures if there should be sky - if (frontsector->ceilingpic == skyflatnum - && backsector->ceilingpic == skyflatnum) - { - bothceilingssky = true; - } - - // likewise, but for floors and upper textures - if (frontsector->floorpic == skyflatnum - && backsector->floorpic == skyflatnum) - { - bothfloorssky = true; - } - ds_p->sprtopclip = ds_p->sprbottomclip = NULL; ds_p->silhouette = 0; @@ -1909,6 +1893,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) || backsector->floorlightsec != frontsector->floorlightsec //SoM: 4/3/2000: Check for colormaps || frontsector->extra_colormap != backsector->extra_colormap + || !P_CompareSectorPortals(&frontsector->portal_floor, &backsector->portal_floor) || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) { markfloor = true; @@ -1942,6 +1927,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) || backsector->ceilinglightsec != frontsector->ceilinglightsec //SoM: 4/3/2000: Check for colormaps || frontsector->extra_colormap != backsector->extra_colormap + || !P_CompareSectorPortals(&frontsector->portal_ceiling, &backsector->portal_ceiling) || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) { markceiling = true;