mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-27 22:52:41 +00:00
Implement "copy portal to line" sector portal type
This commit is contained in:
parent
ff5d53e54d
commit
9335ee3031
11 changed files with 186 additions and 74 deletions
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
98
src/p_spec.c
98
src/p_spec.c
|
@ -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(§ors[sec], §ors[s], R_PointToAngle2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y));
|
P_AddCameraScanner(§ors[sec], §ors[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 = §ors[s1];
|
sector_t *target_sector = §ors[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 = §ors[s2];
|
sector_t *view_sector = §ors[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(§ors[s1], plane_type, tag_to_copy);
|
P_DoPortalCopyFromLine(§ors[s1], plane_type, tag_to_copy);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fromnetsave)
|
if (!fromnetsave)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
11
src/r_bsp.c
11
src/r_bsp.c
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
122
src/r_portal.c
122
src/r_portal.c
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue