Reimplement sector portals

This commit is contained in:
Lactozilla 2023-08-23 04:24:06 -03:00
parent 13ac83a208
commit 1506909a1f
9 changed files with 121 additions and 76 deletions

View file

@ -12822,28 +12822,6 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
skyboxviewpnts[tag] = mobj;
break;
}
case MT_PORTALREFPOINT:
{
size_t i;
for (i = 0; i < numsectors; i++)
{
sector_t *targetsec = &sectors[i];
for (int j = 0; j < targetsec->tags.count; j++)
{
if ((mthing->extrainfo == targetsec->tags.tags[j]) && (GETSECSPECIAL(targetsec->special, 3) == 1))
{
// origin
if (targetsec == mobj->subsector->sector)
targetsec->portals[1] = mobj;
// target
else
targetsec->portals[0] = mobj;
break;
}
}
}
}
break;
case MT_EGGSTATUE:
if (mthing->args[1])
{

View file

@ -978,6 +978,13 @@ 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;
}
static void P_InitializeSector(sector_t *ss)
{
memset(&ss->soundorg, 0, sizeof(ss->soundorg));
@ -989,10 +996,11 @@ static void P_InitializeSector(sector_t *ss)
ss->floordata = NULL;
ss->ceilingdata = NULL;
ss->lightingdata = NULL;
ss->portals[0] = NULL;
ss->portals[1] = NULL;
ss->fadecolormapdata = NULL;
InitializeSectorPortal(&ss->portal_plane_floor);
InitializeSectorPortal(&ss->portal_plane_ceiling);
ss->heightsec = -1;
ss->camsec = -1;

View file

@ -6186,6 +6186,38 @@ fixed_t P_GetSectorGravityFactor(sector_t *sec)
return sec->gravity;
}
static void SetSectorPortal(sectorportal_t *secportal, sector_t *target_sector, INT32 viewpoint_tag)
{
secportal->target = target_sector;
secportal->viewpoint.x = target_sector->soundorg.x;
secportal->viewpoint.y = target_sector->soundorg.y;
secportal->viewpoint.z = target_sector->ceilingheight;
secportal->viewpoint.angle = 0;
if (viewpoint_tag <= 0)
return;
for (thinker_t *th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue;
mobj_t *mo = (mobj_t *)th;
if (mo->type != MT_PORTALREFPOINT || mo->spawnpoint == NULL)
continue;
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;
return;
}
}
/** After the map has loaded, scans for specials that spawn 3Dfloors and
* thinkers.
*
@ -6351,6 +6383,33 @@ void P_SpawnSpecials(boolean fromnetsave)
P_AddCameraScanner(&sectors[sec], &sectors[s], R_PointToAngle2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y));
break;
case 6: // Sector portal
{
INT32 s1, s2;
TAG_ITER_SECTORS(lines[i].args[0], s1) // Target sector tag
{
TAG_ITER_SECTORS(lines[i].args[1], s2) // Sector tag to make a portal to
{
sector_t *target_sector = &sectors[s2];
boolean floor, ceiling;
if (lines[i].args[2] == TMP_BOTH)
floor = ceiling = true;
else
{
floor = lines[i].args[2] == TMP_FLOOR;
ceiling = lines[i].args[2] == TMP_CEILING;
}
if (floor)
SetSectorPortal(&sectors[s1].portal_plane_floor, target_sector, lines[i].args[3]);
if (ceiling)
SetSectorPortal(&sectors[s1].portal_plane_ceiling, target_sector, lines[i].args[3]);
}
}
break;
}
case 7: // Flat alignment - redone by toast
{
// Set calculated offsets such that line's v1 is the apparent origin

View file

@ -909,7 +909,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->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope, frontsector->portal_plane_floor.target != NULL ? &frontsector->portal_plane_floor : NULL);
}
else
floorplane = NULL;
@ -920,7 +920,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);
ceilingcolormap, NULL, NULL, frontsector->c_slope, frontsector->portal_plane_ceiling.target != NULL ? &frontsector->portal_plane_ceiling : NULL);
}
else
ceilingplane = NULL;
@ -963,7 +963,7 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope);
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope, NULL);
ffloor[numffloors].slope = *rover->b_slope;
@ -992,7 +992,7 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope);
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope, NULL);
ffloor[numffloors].slope = *rover->t_slope;
@ -1036,12 +1036,11 @@ static void R_Subsector(size_t num)
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floorxoffset, polysec->flooryoffset,
polysec->floorangle-po->angle,
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
NULL); // will ffloors be slopable eventually?
NULL, NULL);
ffloor[numffloors].height = polysec->floorheight;
ffloor[numffloors].polyobj = po;
ffloor[numffloors].slope = NULL;
//ffloor[numffloors].ffloor = rover;
po->visplane = ffloor[numffloors].plane;
numffloors++;
}
@ -1059,12 +1058,11 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = R_FindPlane(polysec, polysec->ceilingheight, polysec->ceilingpic,
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceilingxoffset, polysec->ceilingyoffset, polysec->ceilingangle-po->angle,
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
NULL); // will ffloors be slopable eventually?
NULL, NULL);
ffloor[numffloors].polyobj = po;
ffloor[numffloors].height = polysec->ceilingheight;
ffloor[numffloors].slope = NULL;
//ffloor[numffloors].ffloor = rover;
po->visplane = ffloor[numffloors].plane;
numffloors++;
}

View file

@ -208,6 +208,15 @@ typedef enum
BT_STRONG,
} busttype_e;
typedef struct sectorportal_s
{
struct sector_s *target;
struct {
fixed_t x, y, z;
angle_t angle;
} viewpoint;
} sectorportal_t;
typedef struct ffloor_s
{
fixed_t *topheight;
@ -495,8 +504,9 @@ typedef struct sector_s
// colormap structure
extracolormap_t *spawn_extra_colormap;
// floor portals
mobj_t *portals[2];
// portals
sectorportal_t portal_plane_floor;
sectorportal_t portal_plane_ceiling;
} sector_t;
//

View file

@ -392,7 +392,7 @@ static visplane_t *new_visplane(unsigned hash)
//
visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap,
ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope)
ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope, sectorportal_t *portalsector)
{
visplane_t *check;
unsigned hash;
@ -451,7 +451,8 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li
&& check->viewx == viewx && check->viewy == viewy && check->viewz == viewz
&& check->viewangle == viewangle
&& check->plangle == plangle
&& check->slope == slope)
&& check->slope == slope
&& check->portalsector == portalsector)
{
return check;
}
@ -479,6 +480,7 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li
check->viewangle = viewangle;
check->plangle = plangle;
check->sector = sector;
check->portalsector = portalsector;
check->polyobj = polyobj;
check->slope = slope;
@ -558,6 +560,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
new_pl->sector = pl->sector;
new_pl->polyobj = pl->polyobj;
new_pl->slope = pl->slope;
new_pl->portalsector = pl->portalsector;
pl = new_pl;
pl->minx = start;
pl->maxx = stop;

View file

@ -54,6 +54,7 @@ typedef struct visplane_s
struct ffloor_s *ffloor;
polyobj_t *polyobj;
pslope_t *slope;
sectorportal_t *portalsector;
} visplane_t;
extern visplane_t *visplanes[MAXVISPLANES];
@ -77,7 +78,7 @@ void R_ClearFFloorClips (void);
void R_DrawPlanes(void);
visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle,
extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope);
extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope, sectorportal_t *portalsector);
visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_PlaneBounds(visplane_t *plane);

View file

@ -309,41 +309,38 @@ void Portal_AddSkybox (const visplane_t* plane)
portal->clipline = -1;
}
/** Creates a floor portal out of a visplane.
/** Creates a sector portal out of a visplane.
*
* Mostly the same as Portal_AddSkybox.
*/
void Portal_AddFloorPortal (const visplane_t* plane)
void Portal_AddSectorPortal (const visplane_t* plane)
{
INT16 start, end;
portal_t* portal;
sector_t *portalsector = plane->sector;
mobj_t *portalmobj = portalsector->portals[0];
mobj_t *refmobj = portalsector->portals[1];
fixed_t refx, refy;
sector_t *source = plane->sector;
sectorportal_t *target = plane->portalsector;
if (TrimVisplaneBounds(plane, &start, &end))
return;
portal = Portal_Add(start, end);
portal_t* portal = Portal_Add(start, end);
Portal_ClipVisplane(plane, portal);
if ((refmobj != NULL) && !(P_MobjWasRemoved(refmobj)))
fixed_t refx = source->soundorg.x - viewx;
fixed_t refy = source->soundorg.y - viewy;
if (target->viewpoint.angle)
{
refx = (refmobj->x - viewx);
refy = (refmobj->y - viewy);
}
else
{
refx = (portalsector->soundorg.x - viewx);
refy = (portalsector->soundorg.y - viewy);
fixed_t x = refx, y = refy;
angle_t ang = target->viewpoint.angle >> ANGLETOFINESHIFT;
refx = FixedMul(x, FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
refy = FixedMul(x, FINESINE(ang)) + FixedMul(y, FINECOSINE(ang));
}
portal->viewx = portalmobj->x - refx;
portal->viewy = portalmobj->y - refy;
portal->viewz = portalmobj->z + viewz;
portal->viewangle = viewangle + portalmobj->angle;
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->clipline = -1;
}
@ -354,16 +351,12 @@ void Portal_AddFloorPortal (const visplane_t* plane)
void Portal_AddSkyboxPortals (void)
{
visplane_t *pl;
INT32 i;
UINT16 count = 0;
for (i = 0; i < MAXVISPLANES; i++, pl++)
for (INT32 i = 0; i < MAXVISPLANES; i++, pl++)
{
for (pl = visplanes[i]; pl; pl = pl->next)
{
// true if added a portal for this visplane
boolean addedportal = false;
boolean floorportalpresent = (pl->sector->portals[0] != NULL && !P_MobjWasRemoved(pl->sector->portals[0]));
boolean added_portal = false;
// skybox portal
if (pl->picnum == skyflatnum)
@ -371,29 +364,24 @@ void Portal_AddSkyboxPortals (void)
if (cv_skybox.value && skyboxmo[0])
{
Portal_AddSkybox(pl);
addedportal = true;
added_portal = true;
}
}
// floor portal
else if (floorportalpresent)
if (pl->portalsector && pl->portalsector->target && floorportalrender < cv_maxportals.value)
{
if (floorportalrender < cv_maxportals.value)
{
Portal_AddFloorPortal(pl);
Portal_AddSectorPortal(pl);
floorportalrender++;
addedportal = true;
}
added_portal = true;
}
// don't render this visplane anymore
if (addedportal)
if (added_portal)
{
pl->minx = 0;
pl->maxx = -1;
count++;
}
}
}
CONS_Debug(DBG_RENDER, "Skybox portals: %d\n", count);
}

View file

@ -54,7 +54,7 @@ void Portal_InitList (void);
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 visplane_t* plane);
void Portal_AddFloorPortal (const visplane_t* plane);
void Portal_AddSectorPortal (const visplane_t* plane);
void Portal_ClipRange (portal_t* portal);
void Portal_ClipApply (const portal_t* portal);