Implement "copy portal to line" sector portal type

This commit is contained in:
Lactozilla 2023-08-24 17:36:38 -03:00
parent ff5d53e54d
commit 9335ee3031
11 changed files with 186 additions and 74 deletions

View file

@ -461,6 +461,7 @@ enums
2 = "Skybox"; 2 = "Skybox";
3 = "Plane"; 3 = "Plane";
4 = "Horizon"; 4 = "Horizon";
5 = "Transfer to line";
7 = "Sector"; 7 = "Sector";
8 = "Object"; 8 = "Object";
} }

View file

@ -577,7 +577,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
for (i = 0; i < subsector->numlines; i++, line++) for (i = 0; i < subsector->numlines; i++, line++)
{ {
if (!line->glseg && line->linedef->special == HORIZONSPECIAL && R_PointOnSegSide(dup_viewx, dup_viewy, line) == 0) if (!line->glseg && line->linedef->special == SPECIAL_HORIZON_LINE && R_PointOnSegSide(dup_viewx, dup_viewy, line) == 0)
{ {
P_ClosestPointOnLine(viewx, viewy, line->linedef, &v); P_ClosestPointOnLine(viewx, viewy, line->linedef, &v);
dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y)); dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y));
@ -1466,7 +1466,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
else else
{ {
// Single sided line... Deal only with the middletexture (if one exists) // Single sided line... Deal only with the middletexture (if one exists)
if (gl_midtexture && gl_linedef->special != HORIZONSPECIAL) // (Ignore horizon line for OGL) if (gl_midtexture && gl_linedef->special != SPECIAL_HORIZON_LINE) // (Ignore horizon line for OGL)
{ {
fixed_t texturevpeg; fixed_t texturevpeg;

View file

@ -3473,7 +3473,7 @@ static void PTR_GlideClimbTraverse(line_t *li)
} }
// see about climbing on the wall // see about climbing on the wall
if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) if (!(checkline->flags & ML_NOCLIMB) && checkline->special != SPECIAL_HORIZON_LINE)
{ {
boolean canclimb; boolean canclimb;
angle_t climbangle, climbline; angle_t climbangle, climbline;

View file

@ -886,6 +886,7 @@ static void P_NetUnArchiveWaypoints(void)
#define LD_ARGS 0x10 #define LD_ARGS 0x10
#define LD_STRINGARGS 0x20 #define LD_STRINGARGS 0x20
#define LD_EXECUTORDELAY 0x40 #define LD_EXECUTORDELAY 0x40
#define LD_TRANSFPORTAL 0x80
static boolean P_AreArgsEqual(const line_t *li, const line_t *spawnli) static boolean P_AreArgsEqual(const line_t *li, const line_t *spawnli)
{ {
@ -1312,6 +1313,9 @@ static void ArchiveLines(void)
if (li->executordelay != spawnli->executordelay) if (li->executordelay != spawnli->executordelay)
diff2 |= LD_EXECUTORDELAY; diff2 |= LD_EXECUTORDELAY;
if (li->secportal != spawnli->secportal)
diff2 |= LD_TRANSFPORTAL;
if (li->sidenum[0] != 0xffff) if (li->sidenum[0] != 0xffff)
{ {
si = &sides[li->sidenum[0]]; si = &sides[li->sidenum[0]];
@ -1402,6 +1406,8 @@ static void ArchiveLines(void)
} }
if (diff2 & LD_EXECUTORDELAY) if (diff2 & LD_EXECUTORDELAY)
WRITEINT32(save_p, li->executordelay); WRITEINT32(save_p, li->executordelay);
if (diff2 & LD_TRANSFPORTAL)
WRITEUINT32(save_p, li->secportal);
} }
} }
WRITEUINT16(save_p, 0xffff); WRITEUINT16(save_p, 0xffff);
@ -1486,7 +1492,8 @@ static void UnArchiveLines(void)
} }
if (diff2 & LD_EXECUTORDELAY) if (diff2 & LD_EXECUTORDELAY)
li->executordelay = READINT32(save_p); li->executordelay = READINT32(save_p);
if (diff2 & LD_TRANSFPORTAL)
li->secportal = READUINT32(save_p);
} }
} }

View file

@ -1108,6 +1108,7 @@ static void P_InitializeLinedef(line_t *ld)
ld->polyobj = NULL; ld->polyobj = NULL;
ld->callcount = 0; ld->callcount = 0;
ld->secportal = UINT32_MAX;
// cph 2006/09/30 - fix sidedef errors right away. // cph 2006/09/30 - fix sidedef errors right away.
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them // cph 2002/07/20 - these errors are fatal if not fixed, so apply them

View file

@ -6214,7 +6214,7 @@ UINT32 P_NewSectorPortal(void)
return (UINT32)i; return (UINT32)i;
} }
static boolean P_IsSectorPortalValid(sectorportal_t *secportal) boolean P_IsSectorPortalValid(sectorportal_t *secportal)
{ {
if (secportal == NULL) if (secportal == NULL)
return false; return false;
@ -6325,28 +6325,59 @@ static void P_DoPortalCopyFromLine(sector_t *dest_sector, int plane_type, int ta
} }
} }
static sectorportal_t *P_SectorGetFloorPortalOrCreate(sector_t *sector) static sectorportal_t *P_SectorGetFloorPortalOrCreate(sector_t *sector, UINT32 *result)
{ {
sectorportal_t *secportal = P_SectorGetFloorPortal(sector); *result = sector->portal_floor;
if (secportal == NULL)
if (*result >= secportalcount)
{ {
sector->portal_floor = P_NewSectorPortal(); *result = P_NewSectorPortal();
return &secportals[sector->portal_floor]; sector->portal_floor = *result;
} }
return secportal; return &secportals[sector->portal_floor];
} }
static sectorportal_t *P_SectorGetCeilingPortalOrCreate(sector_t *sector) static sectorportal_t *P_SectorGetCeilingPortalOrCreate(sector_t *sector, UINT32 *result)
{ {
sectorportal_t *secportal = P_SectorGetCeilingPortal(sector); *result = sector->portal_floor;
if (secportal == NULL)
if (*result >= secportalcount)
{ {
sector->portal_ceiling = P_NewSectorPortal(); *result = P_NewSectorPortal();
return &secportals[sector->portal_ceiling]; sector->portal_ceiling = *result;
} }
return secportal; return &secportals[sector->portal_ceiling];
}
static void P_CopySectorPortalToLines(UINT32 portal_num, int sector_tag)
{
for (size_t i = 0; i < numlines; i++)
{
if (lines[i].special != SPECIAL_SECTOR_SETPORTAL)
continue;
if (lines[i].args[1] != TMSECPORTAL_COPY_PORTAL_TO_LINE)
continue;
if (lines[i].args[3] != sector_tag)
continue;
if (lines[i].args[0] != 0)
{
INT32 linenum = -1;
TAG_ITER_LINES(lines[i].args[0], linenum)
{
lines[linenum].secportal = portal_num;
}
}
else
{
// Just transfer it to this line
lines[i].secportal = portal_num;
}
}
} }
/** After the map has loaded, scans for specials that spawn 3Dfloors and /** After the map has loaded, scans for specials that spawn 3Dfloors and
@ -6514,7 +6545,7 @@ 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)); 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; break;
case 6: // Sector portal case SPECIAL_SECTOR_SETPORTAL: // Sector portal
{ {
int target_sector_tag = lines[i].args[0]; int target_sector_tag = lines[i].args[0];
int portal_type = lines[i].args[1]; int portal_type = lines[i].args[1];
@ -6530,28 +6561,32 @@ void P_SpawnSpecials(boolean fromnetsave)
ceiling = plane_type == TMP_CEILING; ceiling = plane_type == TMP_CEILING;
} }
UINT32 portal_num = UINT32_MAX;
// Eternity's floor and horizon portal types // Eternity's floor and horizon portal types
if (portal_type == TMSECPORTAL_PLANE || portal_type == TMSECPORTAL_HORIZON) if (portal_type == TMSECPORTAL_PLANE || portal_type == TMSECPORTAL_HORIZON)
{ {
secportaltype_e type = portal_type == TMSECPORTAL_HORIZON ? SECPORTAL_HORIZON : SECPORTAL_PLANE; secportaltype_e type = portal_type == TMSECPORTAL_HORIZON ? SECPORTAL_HORIZON : SECPORTAL_PLANE;
if (floor) if (floor)
{ {
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(lines[i].frontsector); sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(lines[i].frontsector, &portal_num);
floorportal->type = type; floorportal->type = type;
floorportal->sector = lines[i].frontsector; floorportal->sector = lines[i].frontsector;
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
if (ceiling) if (ceiling)
{ {
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(lines[i].frontsector); sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(lines[i].frontsector, &portal_num);
ceilportal->type = type; ceilportal->type = type;
ceilportal->sector = lines[i].frontsector; ceilportal->sector = lines[i].frontsector;
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
break; break;
} }
INT32 s1 = -1; INT32 s1 = -1;
TAG_ITER_SECTORS(target_sector_tag, s1) // Target sector tag TAG_ITER_SECTORS(target_sector_tag, s1)
{ {
sector_t *target_sector = &sectors[s1]; sector_t *target_sector = &sectors[s1];
@ -6561,7 +6596,7 @@ void P_SpawnSpecials(boolean fromnetsave)
INT32 linenum = -1; INT32 linenum = -1;
TAG_ITER_LINES(misc, linenum) TAG_ITER_LINES(misc, linenum)
{ {
if (lines[linenum].special == 6 if (lines[linenum].special == SPECIAL_SECTOR_SETPORTAL
&& lines[linenum].args[0] == target_sector_tag && lines[linenum].args[0] == target_sector_tag
&& lines[linenum].args[1] == portal_type && lines[linenum].args[1] == portal_type
&& lines[linenum].args[2] == plane_type && lines[linenum].args[2] == plane_type
@ -6569,17 +6604,19 @@ void P_SpawnSpecials(boolean fromnetsave)
{ {
if (floor) if (floor)
{ {
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector); sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector, &portal_num);
floorportal->type = SECPORTAL_LINE; floorportal->type = SECPORTAL_LINE;
floorportal->line.start = &lines[i]; floorportal->line.start = &lines[i];
floorportal->line.dest = &lines[linenum]; floorportal->line.dest = &lines[linenum];
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
if (ceiling) if (ceiling)
{ {
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector); sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector, &portal_num);
ceilportal->type = SECPORTAL_LINE; ceilportal->type = SECPORTAL_LINE;
ceilportal->line.start = &lines[i]; ceilportal->line.start = &lines[i];
ceilportal->line.dest = &lines[linenum]; ceilportal->line.dest = &lines[linenum];
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
} }
} }
@ -6589,13 +6626,15 @@ void P_SpawnSpecials(boolean fromnetsave)
{ {
if (floor) if (floor)
{ {
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector); sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector, &portal_num);
floorportal->type = SECPORTAL_SKYBOX; floorportal->type = SECPORTAL_SKYBOX;
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
if (ceiling) if (ceiling)
{ {
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector); sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector, &portal_num);
ceilportal->type = SECPORTAL_SKYBOX; ceilportal->type = SECPORTAL_SKYBOX;
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
} }
// Plane portal // Plane portal
@ -6607,15 +6646,17 @@ void P_SpawnSpecials(boolean fromnetsave)
sector_t *view_sector = &sectors[s2]; sector_t *view_sector = &sectors[s2];
if (floor) if (floor)
{ {
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector); sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector, &portal_num);
floorportal->type = SECPORTAL_CEILING; floorportal->type = SECPORTAL_CEILING;
floorportal->sector = view_sector; floorportal->sector = view_sector;
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
if (ceiling) if (ceiling)
{ {
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector); sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector, &portal_num);
ceilportal->type = SECPORTAL_FLOOR; ceilportal->type = SECPORTAL_FLOOR;
ceilportal->sector = view_sector; ceilportal->sector = view_sector;
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
} }
} }
@ -6627,15 +6668,17 @@ void P_SpawnSpecials(boolean fromnetsave)
break; break;
if (floor) if (floor)
{ {
sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector); sectorportal_t *floorportal = P_SectorGetFloorPortalOrCreate(target_sector, &portal_num);
floorportal->type = SECPORTAL_OBJECT; floorportal->type = SECPORTAL_OBJECT;
P_SetTarget(&floorportal->mobj, mobj); P_SetTarget(&floorportal->mobj, mobj);
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
if (ceiling) if (ceiling)
{ {
sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector); sectorportal_t *ceilportal = P_SectorGetCeilingPortalOrCreate(target_sector, &portal_num);
ceilportal->type = SECPORTAL_OBJECT; ceilportal->type = SECPORTAL_OBJECT;
P_SetTarget(&ceilportal->mobj, mobj); P_SetTarget(&ceilportal->mobj, mobj);
P_CopySectorPortalToLines(portal_num, target_sector_tag);
} }
} }
} }
@ -7448,7 +7491,7 @@ void P_SpawnSpecials(boolean fromnetsave)
// Copy portals // Copy portals
for (i = 0; i < numlines; i++) for (i = 0; i < numlines; i++)
{ {
if (lines[i].special != 6) if (lines[i].special != SPECIAL_SECTOR_SETPORTAL)
continue; continue;
int portal_type = lines[i].args[1]; int portal_type = lines[i].args[1];
@ -7470,7 +7513,6 @@ void P_SpawnSpecials(boolean fromnetsave)
TAG_ITER_SECTORS(target_sector_tag, s1) TAG_ITER_SECTORS(target_sector_tag, s1)
P_DoPortalCopyFromLine(&sectors[s1], plane_type, tag_to_copy); P_DoPortalCopyFromLine(&sectors[s1], plane_type, tag_to_copy);
} }
break;
} }
if (!fromnetsave) if (!fromnetsave)

View file

@ -483,9 +483,8 @@ typedef enum
TMSECPORTAL_SKYBOX = 2, TMSECPORTAL_SKYBOX = 2,
TMSECPORTAL_PLANE = 3, TMSECPORTAL_PLANE = 3,
TMSECPORTAL_HORIZON = 4, TMSECPORTAL_HORIZON = 4,
// The two portal types below are unimplemented
TMSECPORTAL_COPY_PORTAL_TO_LINE = 5, TMSECPORTAL_COPY_PORTAL_TO_LINE = 5,
TMSECPORTAL_INTERACTIVE = 6, TMSECPORTAL_INTERACTIVE = 6, // unimplemented
// The two portal types below are new to SRB2 // The two portal types below are new to SRB2
TMSECPORTAL_SECTOR = 7, TMSECPORTAL_SECTOR = 7,
TMSECPORTAL_OBJECT = 8 TMSECPORTAL_OBJECT = 8
@ -543,6 +542,8 @@ boolean P_IsFlagAtBase(mobjtype_t flag);
void P_InitSectorPortals(void); void P_InitSectorPortals(void);
UINT32 P_NewSectorPortal(void); UINT32 P_NewSectorPortal(void);
boolean P_IsSectorPortalValid(sectorportal_t *secportal);
sectorportal_t *P_SectorGetFloorPortal(sector_t *sector); sectorportal_t *P_SectorGetFloorPortal(sector_t *sector);
sectorportal_t *P_SectorGetCeilingPortal(sector_t *sector); sectorportal_t *P_SectorGetCeilingPortal(sector_t *sector);

View file

@ -458,7 +458,7 @@ static void R_AddLine(seg_t *line)
return; return;
backsector = line->backsector; backsector = line->backsector;
horizonline = line->linedef->special == HORIZONSPECIAL; horizonline = line->linedef->special == SPECIAL_HORIZON_LINE;
bothceilingssky = bothfloorssky = false; bothceilingssky = bothfloorssky = false;
// Portal line // Portal line
@ -484,6 +484,15 @@ static void R_AddLine(seg_t *line)
} }
} }
} }
// Transferred portal
else if (line->linedef->secportal != UINT32_MAX && line->side == 0)
{
if (portalrender < cv_maxportals.value)
{
Portal_AddTransferred(line->linedef-lines, line->linedef->secportal, x1, x2);
goto clipsolid;
}
}
// Single sided line? // Single sided line?
if (!backsector) if (!backsector)

View file

@ -536,7 +536,9 @@ typedef enum
ST_NEGATIVE ST_NEGATIVE
} slopetype_t; } slopetype_t;
#define HORIZONSPECIAL 41 #define SPECIAL_HORIZON_LINE 41
#define SPECIAL_SECTOR_SETPORTAL 6
#define NUMLINEARGS 10 #define NUMLINEARGS 10
#define NUMLINESTRINGARGS 2 #define NUMLINESTRINGARGS 2
@ -577,6 +579,8 @@ typedef struct line_s
polyobj_t *polyobj; // Belongs to a polyobject? polyobj_t *polyobj; // Belongs to a polyobject?
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
UINT32 secportal; // transferred sector portal
} line_t; } line_t;
typedef struct typedef struct

View file

@ -263,30 +263,14 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16*
return false; return false;
} }
/** Creates a skybox portal out of a visplane. static void Portal_GetViewpointForSkybox(portal_t *portal)
*
* Applies the necessary offsets and rotation to give
* a depth illusion to the skybox.
*/
void Portal_AddSkybox (const visplane_t* plane)
{ {
INT16 start, end;
mapheader_t *mh;
portal_t* portal;
if (TrimVisplaneBounds(plane, &start, &end))
return;
portal = Portal_Add(start, end);
Portal_ClipVisplane(plane, portal);
portal->viewx = skyboxmo[0]->x; portal->viewx = skyboxmo[0]->x;
portal->viewy = skyboxmo[0]->y; portal->viewy = skyboxmo[0]->y;
portal->viewz = skyboxmo[0]->z; portal->viewz = skyboxmo[0]->z;
portal->viewangle = viewangle + skyboxmo[0]->angle; portal->viewangle = viewangle + skyboxmo[0]->angle;
mh = mapheaderinfo[gamemap-1]; mapheader_t *mh = mapheaderinfo[gamemap-1];
// If a relative viewpoint exists, offset the viewpoint. // If a relative viewpoint exists, offset the viewpoint.
if (skyboxmo[1]) if (skyboxmo[1])
@ -313,31 +297,22 @@ void Portal_AddSkybox (const visplane_t* plane)
portal->viewz += viewz / mh->skybox_scalez; portal->viewz += viewz / mh->skybox_scalez;
else if (mh->skybox_scalez < 0) else if (mh->skybox_scalez < 0)
portal->viewz += viewz * -mh->skybox_scalez; portal->viewz += viewz * -mh->skybox_scalez;
portal->clipline = -1;
portal->is_horizon = false;
portal->horizon_sector = NULL;
} }
/** Creates a sector portal out of a visplane. /** Creates a skybox portal out of a visplane.
*
* Applies the necessary offsets and rotation to give
* a depth illusion to the skybox.
*/ */
void Portal_AddSectorPortal (const visplane_t* plane) void Portal_AddSkybox (const visplane_t* plane)
{ {
INT16 start, end; INT16 start, end;
fixed_t x, y, z, angle; portal_t* portal;
sectorportal_t *secportal = plane->portalsector;
// Shortcut
if (secportal->type == SECPORTAL_SKYBOX)
{
Portal_AddSkybox(plane);
return;
}
if (TrimVisplaneBounds(plane, &start, &end)) if (TrimVisplaneBounds(plane, &start, &end))
return; return;
portal_t* portal = Portal_Add(start, end); portal = Portal_Add(start, end);
Portal_ClipVisplane(plane, portal); Portal_ClipVisplane(plane, portal);
@ -345,6 +320,13 @@ void Portal_AddSectorPortal (const visplane_t* plane)
portal->is_horizon = false; portal->is_horizon = false;
portal->horizon_sector = NULL; portal->horizon_sector = NULL;
Portal_GetViewpointForSkybox(portal);
}
static void Portal_GetViewpointForSecPortal(portal_t *portal, sectorportal_t *secportal, fixed_t origin_x, fixed_t origin_y)
{
fixed_t x, y, z, angle;
switch (secportal->type) switch (secportal->type)
{ {
case SECPORTAL_LINE: case SECPORTAL_LINE:
@ -374,8 +356,8 @@ void Portal_AddSectorPortal (const visplane_t* plane)
case SECPORTAL_HORIZON: case SECPORTAL_HORIZON:
portal->is_horizon = true; portal->is_horizon = true;
portal->horizon_sector = secportal->sector; portal->horizon_sector = secportal->sector;
x = plane->sector->soundorg.x; x = secportal->sector->soundorg.x;
y = plane->sector->soundorg.y; y = secportal->sector->soundorg.y;
if (secportal->type == SECPORTAL_PLANE) if (secportal->type == SECPORTAL_PLANE)
z = -viewz; z = -viewz;
else else
@ -386,8 +368,8 @@ void Portal_AddSectorPortal (const visplane_t* plane)
return; return;
} }
fixed_t refx = plane->sector->soundorg.x - viewx; fixed_t refx = origin_x - viewx;
fixed_t refy = plane->sector->soundorg.y - viewy; fixed_t refy = origin_y - viewy;
// Rotate the X/Y to match the target angle // Rotate the X/Y to match the target angle
if (angle != 0) if (angle != 0)
@ -404,6 +386,70 @@ void Portal_AddSectorPortal (const visplane_t* plane)
portal->viewangle = angle + viewangle; portal->viewangle = angle + viewangle;
} }
/** Creates a sector portal out of a visplane.
*/
void Portal_AddSectorPortal (const visplane_t* plane)
{
INT16 start, end;
sectorportal_t *secportal = plane->portalsector;
// Shortcut
if (secportal->type == SECPORTAL_SKYBOX)
{
Portal_AddSkybox(plane);
return;
}
if (TrimVisplaneBounds(plane, &start, &end))
return;
portal_t* portal = Portal_Add(start, end);
Portal_ClipVisplane(plane, portal);
portal->clipline = -1;
portal->is_horizon = false;
portal->horizon_sector = NULL;
Portal_GetViewpointForSecPortal(portal, secportal, plane->sector->soundorg.x, plane->sector->soundorg.y);
}
/** Creates a transferred sector portal.
*/
void Portal_AddTransferred (const INT32 linenum, UINT32 secportalnum, const INT32 x1, const INT32 x2)
{
if (secportalnum >= secportalcount)
return;
sectorportal_t *secportal = &secportals[secportalnum];
if (!P_IsSectorPortalValid(secportal))
return;
portal_t* portal = Portal_Add(x1, x2);
portal->is_horizon = false;
portal->horizon_sector = NULL;
if (secportal->type == SECPORTAL_SKYBOX)
Portal_GetViewpointForSkybox(portal);
else
{
line_t *line = &lines[linenum];
fixed_t refx = (line->v1->x + line->v2->x) / 2;
fixed_t refy = (line->v1->y + line->v2->y) / 2;
Portal_GetViewpointForSecPortal(portal, secportal, refx, refy);
}
if (secportal->type == SECPORTAL_LINE)
portal->clipline = secportal->line.dest - lines;
else
portal->clipline = -1;
Portal_ClipRange(portal);
portalline = true;
}
/** Creates portals for the currently existing sky visplanes. /** Creates portals for the currently existing sky visplanes.
* The visplanes are also removed and cleared from the list. * The visplanes are also removed and cleared from the list.
*/ */

View file

@ -58,6 +58,7 @@ void Portal_Remove (portal_t* portal);
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
void Portal_AddSkybox (const visplane_t* plane); void Portal_AddSkybox (const visplane_t* plane);
void Portal_AddSectorPortal (const visplane_t* plane); void Portal_AddSectorPortal (const visplane_t* plane);
void Portal_AddTransferred (const INT32 linenum, UINT32 secportalnum, const INT32 x1, const INT32 x2);
void Portal_ClipRange (portal_t* portal); void Portal_ClipRange (portal_t* portal);
void Portal_ClipApply (const portal_t* portal); void Portal_ClipApply (const portal_t* portal);