Allow sector portals to be displayed properly on sky sectors

This commit is contained in:
Lactozilla 2023-08-23 13:43:02 -03:00
parent 2b64698c4e
commit 03daf721ef
11 changed files with 73 additions and 80 deletions

View file

@ -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

View file

@ -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;

View file

@ -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(&sectors[s1].portal_plane_floor, target_sector, target_sector->ceilingheight, lines[i].args[3]);
SetSectorPortal(&sectors[s1].portal_floor, target_sector, target_sector->ceilingheight, lines[i].args[3]);
if (ceiling)
SetSectorPortal(&sectors[s1].portal_plane_ceiling, target_sector, target_sector->floorheight, lines[i].args[3]);
SetSectorPortal(&sectors[s1].portal_ceiling, target_sector, target_sector->floorheight, lines[i].args[3]);
}
}
break;

View file

@ -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);

View file

@ -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;

View file

@ -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?

View file

@ -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;
//

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;