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; INT32 gl_toptexture = 0, gl_bottomtexture = 0;
fixed_t texturevpeg; fixed_t texturevpeg;
boolean bothceilingssky = false; // turned on if both back and front ceilings are sky bothceilingssky = bothfloorssky = false;
boolean bothfloorssky = false; // likewise, but for floors
SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight) SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight)
SLOPEPARAMS(gl_backsector->f_slope, worldlow, worldlowslope, gl_backsector->floorheight) 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 frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1, backf2, backc1, backc2; // back 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 // GZDoom method of sloped line clipping
@ -2354,13 +2347,16 @@ static void HWR_AddLine(seg_t * line)
} }
else else
{ {
boolean bothceilingssky = false, bothfloorssky = false; bothceilingssky = bothfloorssky = false;
gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true); 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; 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; bothfloorssky = true;
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then 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) static void InitializeSectorPortal(sectorportal_t *secportal)
{ {
secportal->target = NULL; secportal->exists = false;
secportal->viewpoint.x = secportal->viewpoint.y = secportal->viewpoint.z = 0; secportal->target.x = secportal->target.y = secportal->target.z = 0;
secportal->viewpoint.angle = 0; secportal->target.angle = 0;
} }
static void P_InitializeSector(sector_t *ss) static void P_InitializeSector(sector_t *ss)
@ -998,8 +998,8 @@ static void P_InitializeSector(sector_t *ss)
ss->lightingdata = NULL; ss->lightingdata = NULL;
ss->fadecolormapdata = NULL; ss->fadecolormapdata = NULL;
InitializeSectorPortal(&ss->portal_plane_floor); InitializeSectorPortal(&ss->portal_floor);
InitializeSectorPortal(&ss->portal_plane_ceiling); InitializeSectorPortal(&ss->portal_ceiling);
ss->heightsec = -1; ss->heightsec = -1;
ss->camsec = -1; ss->camsec = -1;

View file

@ -6186,13 +6186,18 @@ fixed_t P_GetSectorGravityFactor(sector_t *sec)
return sec->gravity; 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) static void SetSectorPortal(sectorportal_t *secportal, sector_t *target_sector, fixed_t default_z, INT32 viewpoint_tag)
{ {
secportal->target = target_sector; secportal->exists = target_sector;
secportal->viewpoint.x = target_sector->soundorg.x; secportal->target.x = target_sector->soundorg.x;
secportal->viewpoint.y = target_sector->soundorg.y; secportal->target.y = target_sector->soundorg.y;
secportal->viewpoint.z = default_z; secportal->target.z = default_z;
secportal->viewpoint.angle = 0; secportal->target.angle = 0;
if (viewpoint_tag <= 0) if (viewpoint_tag <= 0)
return; return;
@ -6210,10 +6215,10 @@ static void SetSectorPortal(sectorportal_t *secportal, sector_t *target_sector,
if (!Tag_Find(&mo->spawnpoint->tags, viewpoint_tag)) if (!Tag_Find(&mo->spawnpoint->tags, viewpoint_tag))
continue; continue;
secportal->viewpoint.x = mo->x; secportal->target.x = mo->x;
secportal->viewpoint.y = mo->y; secportal->target.y = mo->y;
secportal->viewpoint.z = mo->z; secportal->target.z = mo->z;
secportal->viewpoint.angle = mo->angle; secportal->target.angle = mo->angle;
return; return;
} }
} }
@ -6402,9 +6407,9 @@ void P_SpawnSpecials(boolean fromnetsave)
} }
if (floor) 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) 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; break;

View file

@ -521,6 +521,8 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max);
void P_SetupSignExit(player_t *player); void P_SetupSignExit(player_t *player);
boolean P_IsFlagAtBase(mobjtype_t flag); 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_IsMobjTouchingSectorPlane(mobj_t *mo, sector_t *sec);
boolean P_IsMobjTouching3DFloor(mobj_t *mo, ffloor_t *ffloor, 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); 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 *drawsegs = NULL;
drawseg_t *ds_p = 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: // indicates doors closed wrt automap bugfix:
INT32 doorclosed; INT32 doorclosed;
@ -391,7 +394,6 @@ static void R_AddLine(seg_t *line)
INT32 x1, x2; INT32 x1, x2;
angle_t angle1, angle2, span, tspan; angle_t angle1, angle2, span, tspan;
static sector_t tempsec; static sector_t tempsec;
boolean bothceilingssky = false, bothfloorssky = false;
portalline = false; portalline = false;
@ -481,10 +483,17 @@ static void R_AddLine(seg_t *line)
backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true);
doorclosed = 0; 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; 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; bothfloorssky = true;
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then 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)) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
{ {
floorplane = R_FindPlane(frontsector, frontsector->floorheight, frontsector->floorpic, floorlightlevel, 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 else
floorplane = NULL; floorplane = NULL;
@ -920,7 +929,7 @@ static void R_Subsector(size_t num)
{ {
ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic, ceilingplane = R_FindPlane(frontsector, frontsector->ceilingheight, frontsector->ceilingpic,
ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingangle, 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 else
ceilingplane = NULL; ceilingplane = NULL;

View file

@ -25,13 +25,15 @@ extern sector_t *frontsector;
extern sector_t *backsector; extern sector_t *backsector;
extern boolean portalline; // is curline a portal seg? extern boolean portalline; // is curline a portal seg?
// drawsegs are allocated on the fly... see r_segs.c
extern INT32 checkcoord[12][4]; extern INT32 checkcoord[12][4];
extern drawseg_t *curdrawsegs; extern drawseg_t *curdrawsegs;
extern drawseg_t *drawsegs; extern drawseg_t *drawsegs;
extern drawseg_t *ds_p; extern drawseg_t *ds_p;
extern boolean bothceilingssky;
extern boolean bothfloorssky;
extern INT32 doorclosed; extern INT32 doorclosed;
// BSP? // BSP?

View file

@ -210,11 +210,11 @@ typedef enum
typedef struct sectorportal_s typedef struct sectorportal_s
{ {
struct sector_s *target; boolean exists;
struct { struct {
fixed_t x, y, z; fixed_t x, y, z;
angle_t angle; angle_t angle;
} viewpoint; } target;
} sectorportal_t; } sectorportal_t;
typedef struct ffloor_s typedef struct ffloor_s
@ -505,8 +505,8 @@ typedef struct sector_s
extracolormap_t *spawn_extra_colormap; extracolormap_t *spawn_extra_colormap;
// portals // portals
sectorportal_t portal_plane_floor; sectorportal_t portal_floor;
sectorportal_t portal_plane_ceiling; sectorportal_t portal_ceiling;
} sector_t; } 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); hash = visplane_hash(picnum, lightlevel, height);
for (check = visplanes[hash]; check; check = check->next) for (check = visplanes[hash]; check; check = check->next)
{ {
if (polyobj != check->polyobj)
continue;
if (height == check->height && picnum == check->picnum if (height == check->height && picnum == check->picnum
&& lightlevel == check->lightlevel && lightlevel == check->lightlevel
&& xoff == check->xoffs && yoff == check->yoffs && 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->viewangle == viewangle
&& check->plangle == plangle && check->plangle == plangle
&& check->slope == slope && check->slope == slope
&& check->polyobj == polyobj
&& check->portalsector == portalsector) && check->portalsector == portalsector)
{ {
return check; return check;

View file

@ -22,7 +22,6 @@
#include "r_sky.h" #include "r_sky.h"
UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */ 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. // Linked list for portals.
portal_t *portal_base, *portal_cap; portal_t *portal_base, *portal_cap;
@ -36,7 +35,6 @@ boolean portalline; // is curline a portal seg?
void Portal_InitList (void) void Portal_InitList (void)
{ {
portalrender = 0; portalrender = 0;
floorportalrender = 0;
portal_base = portal_cap = NULL; portal_base = portal_cap = NULL;
} }
@ -317,7 +315,7 @@ void Portal_AddSectorPortal (const visplane_t* plane)
{ {
INT16 start, end; INT16 start, end;
sector_t *source = plane->sector; sector_t *source = plane->sector;
sectorportal_t *target = plane->portalsector; sectorportal_t *secportal = plane->portalsector;
if (TrimVisplaneBounds(plane, &start, &end)) if (TrimVisplaneBounds(plane, &start, &end))
return; return;
@ -329,18 +327,19 @@ void Portal_AddSectorPortal (const visplane_t* plane)
fixed_t refx = source->soundorg.x - viewx; fixed_t refx = source->soundorg.x - viewx;
fixed_t refy = source->soundorg.y - viewy; 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; 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)); refx = FixedMul(x, FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
refy = FixedMul(x, FINESINE(ang)) + FixedMul(y, FINECOSINE(ang)); refy = FixedMul(x, FINESINE(ang)) + FixedMul(y, FINECOSINE(ang));
} }
portal->viewx = target->viewpoint.x - refx; portal->viewx = secportal->target.x - refx;
portal->viewy = target->viewpoint.y - refy; portal->viewy = secportal->target.y - refy;
portal->viewz = target->viewpoint.z + viewz; portal->viewz = secportal->target.z + viewz;
portal->viewangle = target->viewpoint.angle + viewangle; portal->viewangle = secportal->target.angle + viewangle;
portal->clipline = -1; portal->clipline = -1;
} }
@ -358,21 +357,17 @@ void Portal_AddSkyboxPortals (void)
{ {
boolean added_portal = false; boolean added_portal = false;
// skybox portal // Render sector portal if recursiveness limit hasn't been reached
if (pl->picnum == skyflatnum) if (pl->portalsector && portalrender < cv_maxportals.value)
{
if (cv_skybox.value && skyboxmo[0])
{
Portal_AddSkybox(pl);
added_portal = true;
}
}
// floor portal
if (pl->portalsector && pl->portalsector->target && floorportalrender < cv_maxportals.value)
{ {
Portal_AddSectorPortal(pl); 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; added_portal = true;
} }

View file

@ -44,7 +44,6 @@ typedef struct portal_s
extern portal_t* portal_base; extern portal_t* portal_base;
extern portal_t* portal_cap; extern portal_t* portal_cap;
extern UINT8 portalrender; extern UINT8 portalrender;
extern UINT8 floorportalrender;
extern line_t *portalclipline; extern line_t *portalclipline;
extern sector_t *portalcullsector; extern sector_t *portalcullsector;

View file

@ -1787,8 +1787,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else else
{ {
// two sided line // two sided line
boolean bothceilingssky = false; // turned on if both back and front ceilings are sky bothceilingssky = bothfloorssky = false;
boolean bothfloorssky = false; // likewise, but for floors
SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight) SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight)
SLOPEPARAMS(backsector->f_slope, worldlow, worldlowslope, backsector->floorheight) SLOPEPARAMS(backsector->f_slope, worldlow, worldlowslope, backsector->floorheight)
@ -1797,21 +1796,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
worldlow -= viewz; worldlow -= viewz;
worldlowslope -= 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->sprtopclip = ds_p->sprbottomclip = NULL;
ds_p->silhouette = 0; ds_p->silhouette = 0;
@ -1909,6 +1893,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|| backsector->floorlightsec != frontsector->floorlightsec || backsector->floorlightsec != frontsector->floorlightsec
//SoM: 4/3/2000: Check for colormaps //SoM: 4/3/2000: Check for colormaps
|| frontsector->extra_colormap != backsector->extra_colormap || frontsector->extra_colormap != backsector->extra_colormap
|| !P_CompareSectorPortals(&frontsector->portal_floor, &backsector->portal_floor)
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
{ {
markfloor = true; markfloor = true;
@ -1942,6 +1927,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|| backsector->ceilinglightsec != frontsector->ceilinglightsec || backsector->ceilinglightsec != frontsector->ceilinglightsec
//SoM: 4/3/2000: Check for colormaps //SoM: 4/3/2000: Check for colormaps
|| frontsector->extra_colormap != backsector->extra_colormap || frontsector->extra_colormap != backsector->extra_colormap
|| !P_CompareSectorPortals(&frontsector->portal_ceiling, &backsector->portal_ceiling)
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
{ {
markceiling = true; markceiling = true;